debian/0000775000000000000000000000000012634020236007166 5ustar debian/legacy/0000775000000000000000000000000012524676037010450 5ustar debian/legacy/update-grub0000775000000000000000000007254212524662415012622 0ustar #!/bin/bash # # Insert a list of installed kernels in a grub config file # Copyright 2001 Wichert Akkerman # Copyright (C) 2007,2008 Free Software Foundation, Inc. # # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GRUB. If not, see . # # Contributors: # Jason Thomas # David B.Harris # Marc Haber # Crispin Flowerday # Abort on errors set -e host_os=`uname -s | tr '[A-Z]' '[a-z]'` abort() { message=$@ echo >&2 echo -e "$message" >&2 echo >&2 exit 1 } find_grub_dir () { echo -n "Searching for GRUB installation directory ... " >&2 for d in /boot/grub /boot/boot/grub ; do if [ -d "$d" ] ; then grub_dir="$d" break fi done if [ -z "$grub_dir" ] ; then abort "No GRUB directory found.\n To create a template run 'mkdir /boot/grub' first.\n To install grub, install it manually or try the 'grub-install' command.\n ### Warning, grub-install is used to change your MBR. ###" else echo "found: $grub_dir" >&2 fi echo $grub_dir } # This function was borrowed from grub2/util/update-grub_lib.in make_system_path_relative_to_its_root () { path=$1 # abort if file doesn't exist if test -e $path ; then : ;else return 1 fi # canonicalize if path=`readlink -f $path` ; then : ; else return 1 fi # if not a directory, climb up to the directory containing it if test -d $path ; then dir=$path else dir=`echo $path | sed -e "s,/[^/]*$,,g"` fi num=`stat -c %d $dir` # this loop sets $dir to the root directory of the filesystem we're inspecting while : ; do parent=`readlink -f $dir/..` if [ "x`stat -c %d $parent`" = "x$num" ] ; then : ; else # $parent is another filesystem; we found it. break fi if [ "x$dir" = "x/" ] ; then # / is our root. break fi dir=$parent done # This function never prints trailing slashes (so that its output can be # appended a slash unconditionally). Each slash in $dir is considered a # preceding slash, and therefore the root directory is an empty string. if [ "$dir" = "/" ] ; then dir="" fi echo $path | sed -e "s,^$dir,,g" } # The grub installation directory grub_dir=$(find_grub_dir) # Full path to the device.map device_map=$grub_dir/device.map find_device () { if ! test -e ${device_map} ; then echo quit | grub --batch --no-floppy --device-map=${device_map} > /dev/null fi grub-probe --device-map=${device_map} -t device $1 2> /dev/null } # Usage: convert_raid1 os_device # Checks if os_device is a software raid1. # If so, converts to first physical device in array. convert_raid1 () { case $1 in /dev/md[0-9] | /dev/md/[0-9]) : ;; # Continue *) return 1 ;; esac [ -x /sbin/mdadm ] || return 1 # Check that the raid device is raid1 raidlevel=$(mdadm -D -b $1 | grep "^ARRAY" | \ sed "s/^.*level=//" | cut -d" " -f1) [ "$raidlevel" = "raid1" ] || return 1 # Take only the first device that makes up the raid raiddev=$(mdadm -D $1 | grep -A1 "Number" | grep "dev" \ | sed "s/^.*\(\/dev\/.*\)$/\1/") [ -n "$raiddev" ] || return 1 echo $raiddev return 0 } # Usage: convert os_device # Convert an OS device to the corresponding GRUB drive. convert () { if ! test -e ${device_map} ; then echo quit | grub --batch --no-floppy --device-map=${device_map} > /dev/null fi GRUB_LEGACY_0_BASED_PARTITIONS=1 grub-probe --device-map=${device_map} -t drive -d "$1" 2> /dev/null || { echo "warning: grub-probe can't find drive for $1." >&2 tmp_map=$(mktemp -t device.map.XXXXXXXX) grub-mkdevicemap --device-map=${tmp_map} --no-floppy >/dev/null 2>&1 || true GRUB_LEGACY_0_BASED_PARTITIONS=1 grub-probe --device-map=${tmp_map} -t drive -d "$1" || { rm -f ${tmp_map} return 1 } echo "Please check ${device_map}, you might have to regenerate it with grub-mkdevicemap." >&2 rm -f ${tmp_map} } } # Usage: convert_default os_device # Convert an OS device to the corresponding GRUB drive. convert_default () { # Check if device is software raid1 array if tmp_dev=$(convert_raid1 $1 2>/dev/null) ; then : # Use device returned by convert_raid1 else tmp_dev=$1 fi convert $tmp_dev } ## Configuration Options # Full path to the menu.lst menu_file_basename=menu.lst menu_file=$grub_dir/$menu_file_basename # Full path to the default file default_file_basename=default default_file=$grub_dir/$default_file_basename # the device for the / filesystem root_device=$(find_device "/") # loop-AES arranges things so that /dev/loop/X can be our root device, but # the initrds that Linux uses don't like that. case ${root_device} in /dev/loop/*|/dev/loop[0-9]) root_device=`losetup ${root_device} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"` ;; esac # the device for the /boot filesystem boot_device=$(find_device "/boot") # where grub looks for the kernels at boot time kernel_dir=`make_system_path_relative_to_its_root /boot` # the "-t abstraction" check is a workaround untill #484297 is fixed if abstraction=`grub-probe -t abstraction --device ${root_device} 2> /dev/null` && [ "$abstraction" = "" ] && \ root_uuid=`grub-probe --device-map=${device_map} --device ${root_device} --target=fs_uuid 2> /dev/null` && \ test -e "/dev/disk/by-uuid/${root_uuid}" ; then linux_root_device=UUID=${root_uuid} else linux_root_device=${root_device} fi # Default kernel options, overidden by the kopt statement in the menufile. kopt="root=$linux_root_device ro" # Title title="Debian GNU/`uname -s | sed -e s,GNU/,,g`" # should update-grub remember the default entry updatedefaultentry="false" # Drive(in GRUB terms) where the kernel is located. Overridden by the # groot statement in menufile. grub_root_device=$(convert_default "$boot_device") # should grub create the alternative boot options in the menu alternative="true" # should grub lock the alternative boot options in the menu lockalternative="false" # additional options to use with the default boot option, but not with the # alternatives defoptions="" # should grub lock the old kernels lockold="false" # Xen hypervisor options to use with the default Xen boot option xenhopt="" # Xen Linux kernel options to use with the default Xen boot option xenkopt="console=tty0" # options to use with the alternative boot options altoptions="(single-user mode) single" # controls howmany kernels are listed in the config file, # this does not include the alternative kernels howmany="all" # should grub create a memtest86 entry memtest86="true" # should grub add "savedefault" to default boot options savedefault="false" # stores the command line arguments command_line_arguments=$1 # read user configuration if test -f "/etc/default/grub" ; then . /etc/default/grub fi # Default options to use in a new config file. This will only be used if $menu_file # doesn't already exist. Only edit the lines between the two "EOF"s. The others are # part of the script. newtemplate=$(tempfile) cat > "$newtemplate" <&2 if [ -f "$default_file" ] ; then echo "found: $default_file" >&2 else echo "Generating $default_file file and setting the default boot entry to 0" >&2 if [ -f /usr/lib/grub-legacy/grub-set-default ] ; then /usr/lib/grub-legacy/grub-set-default 0 else grub-set-default 0 fi fi # Make sure we use the standard sorting order LC_COLLATE=C # Magic markers we use start="### BEGIN AUTOMAGIC KERNELS LIST" end="### END DEBIAN AUTOMAGIC KERNELS LIST" startopt="## ## Start Default Options ##" endopt="## ## End Default Options ##" # Extract options from config file ExtractMenuOpt() { opt=$1 sed -ne "/^$start\$/,/^$end\$/ { /^$startopt\$/,/^$endopt\$/ { /^# $opt=/ { s/^# $opt=\(.*\)\$/\1/ p } } }" $menu } GetMenuOpts() { opt=$1 sed -ne "/^$start\$/,/^$end\$/ { /^$startopt\$/,/^$endopt\$/ { /^# $opt=/ { p } } }" $menu } ExtractMenuOpts() { opt=$1 GetMenuOpts $opt | sed "s/^# $opt=\(.*\)\$/\1=\"\2\"/" } GetMenuOpt() { opt=$1 value=$2 [ -z "$(GetMenuOpts "$opt")" ] || value=$(ExtractMenuOpt "$opt") echo $value } # Compares two version strings A and B # Returns -1 if AB # This compares version numbers of the form # 2.4.14.2 > 2.4.14 # 2.4.14random = 2.4.14-random > 2.4.14-ac10 > 2.4.14 > 2.4.14-pre2 > # 2.4.14-pre1 > 2.4.13-ac99 CompareVersions() { local sedexp="s,.*/vmlinu[zx]-,,g;s/[._-]\(pre\|rc\|test\|git\|trunk\)/~\1/g" local a=`echo $1 | sed -e "$sedexp"` local b=`echo $2 | sed -e "$sedexp"` if [ "$a" = "$b" ] ; then echo 0 elif dpkg --compare-versions "$a" gt "$b" ; then echo 1 else echo -1 fi } # looks in the directory specified for an initrd image with the version specified FindInitrdName() { # strip trailing slashes directory=$(echo $1 | sed -e 's#/*$##') version=$2 # initrd # initrd.img # initrd-lvm # .*.gz initrdName="" names="initrd initrd.img initrd-lvm" compressed="gz" for n in $names ; do # make sure we haven't already found it if [ -z "$initrdName" ] ; then if [ -f "$directory/$n$version" ] ; then initrdName="$n$version" break else for c in $compressed ; do if [ -f "$directory/$n$version.$c" ] ; then initrdName="$n$version.$c" break fi done fi else break fi done # return the result echo $initrdName } FindXenHypervisorVersions () { version=$1 if [ -f "/var/lib/linux-image-$version/xen-versions" ]; then ret="$(cat /var/lib/linux-image-$version/xen-versions)" fi echo $ret } get_kernel_opt() { kernel_version=$1 version=$(echo $kernel_version | sed 's/^[^0-9]*//') version=$(echo $version | sed 's/[-\+\.]/_/g') if [ -n "$version" ] ; then while [ -n "$version" ] ; do currentOpt="$(eval "echo \${kopt_$version}")" if [ -n "$currentOpt" ] ; then break fi version=$(echo $version | sed 's/_\?[^_]*$//') done fi if [ -z "$currentOpt" ] ; then currentOpt=$kopt fi echo $currentOpt } write_kernel_entry() { local kernel_version; kernel_version=$1; shift local recovery_desc; recovery_desc=$1; shift local lock_alternative; lock_alternative=$1; shift local grub_root_device; grub_root_device=$1; shift local kernel; kernel=$1; shift local kernel_options; kernel_options=$1; shift local recovery_suffix; recovery_suffix=$1; shift local initrd; initrd=$1; shift local savedefault; savedefault=$1; shift local lockold; lockold=$1; shift local hypervisor if [ -n "$1" ]; then # Hypervisor. hypervisor=$1; shift local hypervisor_image; hypervisor_image=$1; shift local hypervisor_version; hypervisor_version=$1; shift local hypervisor_options; hypervisor_options=$1; shift fi echo -n "title " >> $buffer if [ -n "$hypervisor" ]; then echo -n "$hypervisor $hypervisor_version / " >> $buffer fi echo -n "$title" >> $buffer if [ -n "$kernel_version" ]; then echo -n ", kernel $kernel_version" >> $buffer fi if [ -n "$recovery_desc" ]; then echo -n " $recovery_desc" >> $buffer fi echo >> $buffer # lock the alternative options if test x"$lock_alternative" = x"true" ; then echo "lock" >> $buffer fi # lock the old entries if test x"$lockold" = x"true" ; then echo "lock" >> $buffer fi echo "root $grub_root_device" >> $buffer echo -n "kernel " >> $buffer if [ -n "$hypervisor" ]; then echo -n "$hypervisor_image" >> $buffer if [ -n "$hypervisor_options" ]; then echo -n " $hypervisor_options" >> $buffer fi echo >> $buffer echo -n "module " >> $buffer fi echo -n "$kernel" >> $buffer if [ -n "$kernel_options" ]; then echo -n " $kernel_options" >> $buffer fi if [ -n "$recovery_desc" ]; then echo -n " $recovery_suffix" >> $buffer fi echo >> $buffer if [ -n "$initrd" ]; then if [ -n "$hypervisor" ]; then echo -n "module " >> $buffer else echo -n "initrd " >> $buffer fi echo "$initrd" >> $buffer fi if test x"$savedefault" = x"true" ; then echo "savedefault" >> $buffer fi echo >> $buffer } echo -n "Testing for an existing GRUB $menu_file_basename file ... " >&2 # Test if our menu file exists if [ -f "$menu_file" ] ; then menu="$menu_file" rm -f $newtemplate unset newtemplate echo "found: $menu_file" >&2 cp -f "$menu_file" "$menu_file~" else # if not ask user if they want us to create one menu="$menu_file" echo >&2 echo >&2 if [ "-y" = "$command_line_arguments" ] ; then echo "Warning: ignoring deprecated -y option." >&2 fi echo >&2 echo "Generating $menu_file" >&2 cat "$newtemplate" > $menu_file rm -f $newtemplate unset newtemplate fi # Extract the kernel options to use kopt=$(GetMenuOpt "kopt" "$kopt") # Set the kernel 2.6 option only for fresh install test -z "$(GetMenuOpt "kopt" "")" && kopt_2_6="root=$linux_root_device ro" # Extract options for specific kernels opts="$(ExtractMenuOpts "\(kopt_[[:alnum:]_]\+\)")" test -z "$opts" || eval "$opts" CustomKopts=$(GetMenuOpts "\(kopt_[[:alnum:]_]\+\)") # Extract the grub root grub_root_device=$(GetMenuOpt "groot" "$grub_root_device") # Extract the old recovery value alternative=$(GetMenuOpt "recovery" "$alternative") # Extract the alternative value alternative=$(GetMenuOpt "alternative" "$alternative") # Extract the lockalternative value lockalternative=$(GetMenuOpt "lockalternative" "$lockalternative") # Extract the additional default options defoptions=$(GetMenuOpt "defoptions" "$defoptions") # Extract the lockold value lockold=$(GetMenuOpt "lockold" "$lockold") # Extract Xen hypervisor options xenhopt=$(GetMenuOpt "xenhopt" "$xenhopt") # Extract Xen Linux kernel options xenkopt=$(GetMenuOpt "xenkopt" "$xenkopt") # Extract the howmany value howmany=$(GetMenuOpt "howmany" "$howmany") # Extract the memtest86 value memtest86=$(GetMenuOpt "memtest86" "$memtest86") # Extract the updatedefaultentry option updatedefaultentry=$(GetMenuOpt "updatedefaultentry" "$updatedefaultentry") # Extract the savedefault option savedefault=$(GetMenuOpt "savedefault" "$savedefault") # Generate the menu options we want to insert buffer=$(tempfile) echo $start >> $buffer echo "## lines between the AUTOMAGIC KERNELS LIST markers will be modified" >> $buffer echo "## by the debian update-grub script except for the default options below" >> $buffer echo >> $buffer echo "## DO NOT UNCOMMENT THEM, Just edit them to your needs" >> $buffer echo >> $buffer echo "## ## Start Default Options ##" >> $buffer echo "## default kernel options" >> $buffer echo "## default kernel options for automagic boot options" >> $buffer echo "## If you want special options for specific kernels use kopt_x_y_z" >> $buffer echo "## where x.y.z is kernel version. Minor versions can be omitted." >> $buffer echo "## e.g. kopt=root=/dev/hda1 ro" >> $buffer echo "## kopt_2_6_8=root=/dev/hdc1 ro" >> $buffer echo "## kopt_2_6_8_2_686=root=/dev/hdc2 ro" >> $buffer echo "# kopt=$kopt" >> $buffer if [ -n "$CustomKopts" ] ; then echo "$CustomKopts" >> $buffer elif [ -n "$kopt_2_6" ] && [ "$kopt" != "$kopt_2_6" ]; then echo "# kopt_2_6=$kopt_2_6" >> $buffer fi echo >> $buffer echo "## default grub root device" >> $buffer echo "## e.g. groot=(hd0,0)" >> $buffer echo "# groot=$grub_root_device" >> $buffer echo >> $buffer echo "## should update-grub create alternative automagic boot options" >> $buffer echo "## e.g. alternative=true" >> $buffer echo "## alternative=false" >> $buffer echo "# alternative=$alternative" >> $buffer echo >> $buffer echo "## should update-grub lock alternative automagic boot options" >> $buffer echo "## e.g. lockalternative=true" >> $buffer echo "## lockalternative=false" >> $buffer echo "# lockalternative=$lockalternative" >> $buffer echo >> $buffer echo "## additional options to use with the default boot option, but not with the" >> $buffer echo "## alternatives" >> $buffer echo "## e.g. defoptions=vga=791 resume=/dev/hda5" >> $buffer echo "# defoptions=$defoptions" >> $buffer echo >> $buffer echo "## should update-grub lock old automagic boot options" >> $buffer echo "## e.g. lockold=false" >> $buffer echo "## lockold=true" >> $buffer echo "# lockold=$lockold" >> $buffer echo >> $buffer echo "## Xen hypervisor options to use with the default Xen boot option" >> $buffer echo "# xenhopt=$xenhopt" >> $buffer echo >> $buffer echo "## Xen Linux kernel options to use with the default Xen boot option" >> $buffer echo "# xenkopt=$xenkopt" >> $buffer echo >> $buffer echo "## altoption boot targets option" >> $buffer echo "## multiple altoptions lines are allowed" >> $buffer echo "## e.g. altoptions=(extra menu suffix) extra boot options" >> $buffer echo "## altoptions=(single-user) single" >> $buffer if ! grep -q "^# altoptions" $menu ; then echo "# altoptions=$altoptions" >> $buffer else grep "^# altoptions" $menu >> $buffer fi echo >> $buffer echo "## controls how many kernels should be put into the $menu_file_basename" >> $buffer echo "## only counts the first occurence of a kernel, not the" >> $buffer echo "## alternative kernel options" >> $buffer echo "## e.g. howmany=all" >> $buffer echo "## howmany=7" >> $buffer echo "# howmany=$howmany" >> $buffer echo >> $buffer echo "## should update-grub create memtest86 boot option" >> $buffer echo "## e.g. memtest86=true" >> $buffer echo "## memtest86=false" >> $buffer echo "# memtest86=$memtest86" >> $buffer echo >> $buffer echo "## should update-grub adjust the value of the default booted system" >> $buffer echo "## can be true or false" >> $buffer echo "# updatedefaultentry=$updatedefaultentry" >> $buffer echo >> $buffer echo "## should update-grub add savedefault to the default options" >> $buffer echo "## can be true or false" >> $buffer echo "# savedefault=$savedefault" >> $buffer echo >> $buffer echo "## ## End Default Options ##" >> $buffer echo >> $buffer echo -n "Searching for splash image ... " >&2 current_splash=`grep '^splashimage=' ${menu_file} || true` grub_dir_rel=`make_system_path_relative_to_its_root $grub_dir` splashimage_path="splashimage=${grub_root_device}/${grub_dir_rel##${kernel_dir}}/splash.xpm.gz" if [ `sed -e "/^$start/,/^$end/d" $menu_file | grep -c '^splashimage='` != "0" ] ; then #checks for splashscreen defined outside the autoupdated part splashimage=$(grep '^splashimage=' ${menu_file}) echo "found: ${splashimage##*=}" >&2 echo >&2 elif [ -f "${grub_dir}/splash.xpm.gz" ] && [ "$current_splash" = "" ]; then echo "found: /boot/grub/splash.xpm.gz" >&2 echo "$splashimage_path" >> $buffer echo >> $buffer elif [ -f "${grub_dir}/splash.xpm.gz" ] && [ "$current_splash" = "$splashimage_path" ]; then echo "found: /boot/grub/splash.xpm.gz" >&2 echo "$splashimage_path" >> $buffer echo >> $buffer elif [ "$current_splash" != "" ] && [ "$current_splash" != "$splashimage_path" ]; then echo "found but preserving previous setting: $(grep '^splashimage=' ${menu_file})" >&2 echo "$current_splash" >> $buffer echo >> $buffer else echo "none found, skipping ..." >&2 fi xen0Kernels="" # First kernels with xen0 support. for ver in `grep -l CONFIG_XEN=y /boot/config* | sed -e s%/boot/config-%%`; do if ! grep -q CONFIG_XEN_PRIVILEGED_GUEST=y /boot/config-$ver ; then continue fi # ver is a kernel version kern="/boot/vmlinuz-$ver" if [ -r $kern ] ; then newerKernels="" for i in $xen0Kernels ; do res=$(CompareVersions "$kern" "$i") if [ "$kern" != "" ] && [ "$res" -gt 0 ] ; then newerKernels="$newerKernels $kern $i" kern="" else newerKernels="$newerKernels $i" fi done if [ "$kern" != "" ] ; then newerKernels="$newerKernels $kern" fi xen0Kernels="$newerKernels" fi done sortedKernels="" for kern in $(/bin/ls -1vr /boot | grep -v "dpkg-*" | grep "^vmlinuz-") ; do kern="/boot/$kern" newerKernels="" for i in $sortedKernels ; do res=$(CompareVersions "$kern" "$i") if [ "$kern" != "" ] && [ "$res" -gt 0 ] ; then newerKernels="$newerKernels $kern $i" kern="" else newerKernels="$newerKernels $i" fi done if [ "$kern" != "" ] ; then newerKernels="$newerKernels $kern" fi sortedKernels="$newerKernels" done if test -f "/boot/vmlinuz.old" ; then sortedKernels="/boot/vmlinuz.old $sortedKernels" fi if test -f "/boot/vmlinuz" ; then sortedKernels="/boot/vmlinuz $sortedKernels" fi hypervisors="" for hyp in /boot/xen-*.gz; do if [ ! -h "$hyp" ] && [ -f "$hyp" ]; then hypervisors="$hypervisors `basename "$hyp"`" fi done #Finding the value the default line use_grub_set_default="false" if test "$updatedefaultentry" = "true" ; then defaultEntryNumber=$(sed -ne 's/^[[:blank:]]*default[[:blank:]]*\(.*\).*/\1/p' $menu) if [ "$defaultEntryNumber" = "saved" ] ; then defaultEntryNumber=$(sed 'q' "$grub_dir/default") use_grub_set_default="true" fi if test -n "$defaultEntryNumber"; then defaultEntryNumberPlusOne=$(expr $defaultEntryNumber \+ 1); defaultEntry=$(grep "^[[:blank:]]*title" $menu | sed -ne "${defaultEntryNumberPlusOne}p" | sed -ne ";s/^[[:blank:]]*title[[:blank:]]*//p") defaultEntry=$(echo $defaultEntry | sed -e "s/[[:blank:]]*$//") # don't trust trailing blanks else notChangeDefault="yes" fi else notChangeDefault="yes" fi ## heres where we start writing out the kernel entries counter=0 grub2name="${kernel_dir}/grub/core.img" if [ "$LET_US_TRY_GRUB_2" = "true" ] \ && test -f /boot/grub/core.img ; then echo "Found GRUB 2: $grub2name" >&2 cat >> $buffer << EOF title Chainload into GRUB 2 root $grub_root_device kernel $grub2name title `echo ───────────────────────────────────────────────────────────────────── | iconv -f utf-8 -t cp437` root title When you have verified GRUB 2 works, you can use this command to root title complete the upgrade: upgrade-from-grub-legacy root title `echo ───────────────────────────────────────────────────────────────────── | iconv -f utf-8 -t cp437` root EOF fi # Xen entries first. for kern in $xen0Kernels ; do if test ! x"$howmany" = x"all" ; then if [ $counter -gt $howmany ] ; then break fi fi kernelName=$(basename $kern) kernelVersion=$(echo $kernelName | sed -e 's/vmlinuz//') initrdName=$(FindInitrdName "/boot" "$kernelVersion") initrd="" kernel=$kernel_dir/$kernelName if [ -n "$initrdName" ] ; then initrd=$kernel_dir/$initrdName fi kernelVersion=$(echo $kernelVersion | sed -e 's/^-//') currentOpt=$(get_kernel_opt $kernelVersion) hypervisorVersions=$(FindXenHypervisorVersions "$kernelVersion") found= for hypervisorVersion in $hypervisorVersions; do hypervisor="$kernel_dir/xen-$hypervisorVersion.gz" if [ -e "$hypervisor" ]; then found=1 echo "Found Xen hypervisor $hypervisorVersion, kernel: $kernel" >&2 write_kernel_entry "$kernelVersion" '' '' "$grub_root_device" \ "$kernel" "$currentOpt $xenkopt" '' "$initrd" "$savedefault" '' \ Xen "$hypervisor" "$hypervisorVersion" "$xenhopt" counter=$(($counter + 1)) fi done if [ -z $found ]; then for hypervisor in $hypervisors; do hypVersion=`basename "$hypervisor" .gz | sed s%xen-%%` echo "Found Xen hypervisor $hypVersion, kernel: $kernel" >&2 write_kernel_entry "$kernelVersion" '' '' "$grub_root_device" \ "$kernel" "$currentOpt $xenkopt" '' "$initrd" "$savedefault" '' \ Xen "$kernel_dir/$hypervisor" "$hypVersion" "$xenhopt" counter=$(($counter + 1)) done fi done for kern in $sortedKernels ; do counter=$(($counter + 1)) if test ! x"$howmany" = x"all" ; then if [ $counter -gt $howmany ] ; then break fi fi kernelName=$(basename $kern) kernelVersion=$(echo $kernelName | sed -e 's/vmlinuz//') initrdName=$(FindInitrdName "/boot" "$kernelVersion") initrd="" kernel=$kernel_dir/$kernelName if [ -n "$initrdName" ] ; then initrd=$kernel_dir/$initrdName fi echo "Found kernel: $kernel" >&2 if [ "$kernelName" = "vmlinuz" ]; then if [ -L "/boot/$kernelName" ]; then kernelVersion=`readlink -f "/boot/$kernelName"` kernelVersion=$(echo $kernelVersion | sed -e 's/.*vmlinuz-//') kernelVersion="$kernelVersion Default" else kernelVersion="Default" fi fi if [ "$kernelName" = "vmlinuz.old" ]; then if [ -L "/boot/$kernelName" ]; then kernelVersion=`readlink -f "/boot/$kernelName"` kernelVersion=$(echo $kernelVersion | sed -e 's/.*vmlinuz-//') kernelVersion="$kernelVersion Previous" else kernelVersion="Previous" fi fi kernelVersion=$(echo $kernelVersion | sed -e 's/^-//') currentOpt=$(get_kernel_opt $kernelVersion) do_lockold=$lockold # do not lockold for the first entry [ $counter -eq 1 ] && do_lockold=false write_kernel_entry "$kernelVersion" "" "" "$grub_root_device" "$kernel" \ "$currentOpt $defoptions" "" "$initrd" "$savedefault" "$do_lockold" # insert the alternative boot options if test ! x"$alternative" = x"false" ; then # for each altoptions line do this stuff sed -ne 's/# altoptions=\(.*\)/\1/p' $buffer | while read line; do descr=$(echo $line | sed -ne 's/\(([^)]*)\)[[:space:]]\(.*\)/\1/p') suffix=$(echo $line | sed -ne 's/\(([^)]*)\)[[:space:]]\(.*\)/\2/p') test x"$lockalternative" = x"true" && do_lockold=false write_kernel_entry "$kernelVersion" "$descr" "$lockalternative" \ "$grub_root_device" "$kernel" "$currentOpt" "$suffix" "$initrd" \ "$savedefault" "$do_lockold" done fi done memtest86names="memtest86 memtest86+" if test ! x"$memtest86" = x"false" ; then for name in $memtest86names ; do if test -f "/boot/$name.bin" ; then kernelVersion="$name" kernel="$kernel_dir/$name.bin" currentOpt= initrd= echo "Found kernel: $kernel" >&2 write_kernel_entry "$kernelVersion" "" "" "$grub_root_device" \ "$kernel" "$currentOpt" "" "$initrd" "false" "" fi done fi echo $end >> $buffer echo -n "Updating $menu ... " >&2 # Insert the new options into the menu if ! grep -q "^$start" $menu ; then cat $buffer >> $menu rm -f $buffer else umask 077 sed -e "/^$start/,/^$end/{ /^$start/r $buffer d } " $menu > $menu.new cat $menu.new > $menu rm -f $buffer $menu.new fi # Function to update the default value set_default_value() { if [ "$use_grub_set_default" = "true" ] ; then if [ -f /usr/lib/grub-legacy/grub-set-default ] ; then /usr/lib/grub-legacy/grub-set-default $1 else grub-set-default $1 fi else value="$1" newmenu=$(tempfile) sed -e "s/^[[:blank:]]*default[[:blank:]]*[[:digit:]]*\(.*\)/default ${value}\1/;b" $menu > $newmenu cat $newmenu > $menu rm -f $newmenu unset newmenu fi } #Updating the default number if [ "$LET_US_TRY_GRUB_2" = "true" ] && test -f /boot/grub/core.img ; then set_default_value "0" elif test -z "$notChangeDefault"; then newDefaultNumberPlusOne=$(grep "^[[:blank:]]*title[[:blank:]]*" $menu | grep -n "${defaultEntry}" | cut -f1 -d ":" | sed -ne "1p") if test -z "$newDefaultNumberPlusOne"; then echo "Previous default entry removed, resetting to 0">&2 set_default_value "0" elif test -z "$defaultEntry"; then echo "Value of default value matches no entry, resetting to 0" >&2 set_default_value "0" else if test "$newDefaultNumberPlusOne" = "1"; then newDefaultNumber="0" else newDefaultNumber=$(expr $newDefaultNumberPlusOne - 1) fi echo "Updating the default booting kernel">&2 set_default_value "$newDefaultNumber" fi fi echo "done" >&2 echo >&2 debian/legacy/update-grub.ubuntu.patch0000775000000000000000000000705712524662415015240 0ustar --- update-grub.orig 2011-03-17 14:32:24.000000000 +0000 +++ update-grub 2012-09-06 22:38:51.498737000 +0100 @@ -218,7 +218,7 @@ kopt="root=$linux_root_device ro" # Title -title="Debian GNU/`uname -s | sed -e s,GNU/,,g`" +title=$(lsb_release --short --description 2>/dev/null) || title="Ubuntu" # should update-grub remember the default entry updatedefaultentry="false" @@ -235,7 +235,7 @@ # additional options to use with the default boot option, but not with the # alternatives - defoptions="" + defoptions="quiet splash" # should grub lock the old kernels lockold="false" @@ -247,7 +247,7 @@ xenkopt="console=tty0" # options to use with the alternative boot options - altoptions="(single-user mode) single" + altoptions="(recovery mode) single" # controls howmany kernels are listed in the config file, # this does not include the alternative kernels @@ -262,6 +262,13 @@ # stores the command line arguments command_line_arguments=$1 +# does this version of grub support the quiet option? +if [ -f ${grub_dir}/installed-version ] && dpkg --compare-versions `cat ${grub_dir}/installed-version` ge 0.97-11ubuntu4; then + supports_quiet=true +else + supports_quiet=false +fi + # read user configuration if test -f "/etc/default/grub" ; then . /etc/default/grub @@ -504,6 +511,12 @@ local hypervisor_options; hypervisor_options=$1; shift fi + local grub_root_type + case "$grub_root_device" in + [^A-Za-z0-9]*) grub_root_type='root' ;; + *) grub_root_type='uuid' ;; + esac + echo -n "title " >> $buffer if [ -n "$hypervisor" ]; then @@ -512,7 +525,12 @@ echo -n "$title" >> $buffer if [ -n "$kernel_version" ]; then - echo -n ", kernel $kernel_version" >> $buffer + echo -n ", " >> $buffer + # memtest86 is not strictly a kernel + if ! echo "$kernel_version" | grep -q ^memtest86; then + echo -n "kernel " >> $buffer + fi + echo -n "$kernel_version" >> $buffer fi if [ -n "$recovery_desc" ]; then echo -n " $recovery_desc" >> $buffer @@ -528,7 +546,7 @@ echo "lock" >> $buffer fi - echo "root $grub_root_device" >> $buffer + echo "$grub_root_type $grub_root_device" >> $buffer echo -n "kernel " >> $buffer if [ -n "$hypervisor" ]; then @@ -557,6 +575,10 @@ echo "$initrd" >> $buffer fi + if [ ! -n "$recovery_desc" -a x"$supports_quiet" = x"true" ]; then + echo "quiet" >> $buffer + fi + if test x"$savedefault" = x"true" ; then echo "savedefault" >> $buffer fi @@ -701,7 +723,7 @@ echo "## altoption boot targets option" >> $buffer echo "## multiple altoptions lines are allowed" >> $buffer echo "## e.g. altoptions=(extra menu suffix) extra boot options" >> $buffer -echo "## altoptions=(single-user) single" >> $buffer +echo "## altoptions=(recovery) single" >> $buffer if ! grep -q "^# altoptions" $menu ; then echo "# altoptions=$altoptions" >> $buffer @@ -846,13 +868,18 @@ ## heres where we start writing out the kernel entries counter=0 +case "$grub_root_device" in +[^A-Za-z0-9]*) grub_root_type='root' ;; +*) grub_root_type='uuid' ;; +esac + grub2name="${kernel_dir}/grub/core.img" if [ "$LET_US_TRY_GRUB_2" = "true" ] \ && test -f /boot/grub/core.img ; then echo "Found GRUB 2: $grub2name" >&2 cat >> $buffer << EOF title Chainload into GRUB 2 -root $grub_root_device +$grub_root_type $grub_root_device kernel $grub2name title `echo ───────────────────────────────────────────────────────────────────── | iconv -f utf-8 -t cp437` debian/legacy/upgrade-from-grub-legacy0000775000000000000000000000276412524662415015171 0ustar #!/bin/bash -e if test ! -f /boot/grub/core.img ; then echo -e "\ncore.img doesn't exist, trying to create it.\n" >&2 grub-install --no-floppy --grub-setup=/bin/true "(hd0)" > /dev/null fi echo RESET grub-pc/install_devices | debconf-communicate >/dev/null # Pretend we're upgrading grub-pc. This will make our postinst DTRT. UPGRADE_FROM_GRUB_LEGACY=1 \ /var/lib/dpkg/info/grub-pc.postinst configure dummy-version if test ! -f /boot/grub/grub.cfg ; then echo -e "\nCalling update-grub to generate grub.cfg\n" >&2 update-grub || cat << EOF Failed to generate /boot/grub/grub.cfg but GRUB2 has been already installed to your MBR. THIS MEANS YOU HAVE CURRENTLY AN UNBOOTABLE SYSTEM. Either fix the error from update-grub and run $0 again or install old grub again and run grub-install from it to have again grub-legacy in your MBR. EOF fi # These never contain any valuable information, and they aren't useful for # boot anymore, since we just overwrote MBR/PBR. rm -f /boot/grub/{{xfs,reiserfs,e2fs,fat,jfs,minix}_stage1_5,stage{1,2}} # Remove marker file used to indicate that grub-install was run rather than # this script. Since stage2 has been removed, we don't need this any more. rm -f /boot/grub/grub2-installed cat << EOF GRUB Legacy has been removed, but its configuration files have been preserved, since this script cannot determine if they contain valuable information. If you would like to remove the configuration files as well, use the following command: rm -f /boot/grub/menu.lst* EOF debian/config.in0000664000000000000000000000426112524662415010777 0ustar #!/bin/sh set -e case `dpkg --print-architecture` in kfreebsd-*) # No migration from GRUB Legacy, no Linux cmdline exit 0 ;; esac . /usr/share/debconf/confmodule priority=medium case @PACKAGE@ in grub-pc) if test -e /boot/grub/stage2 && test -e /boot/grub/menu.lst && ! test -e /boot/grub/core.img ; then db_input high grub-pc/chainload_from_menu.lst || true db_get grub-pc/kopt_extracted || true # this check ensures we only do this once if [ "$RET" = "false" ] ; then kopt=`sed -ne "s/^# kopt=//p" /boot/grub/menu.lst | tr -s " " "\n" | grep -vx "\(ro\|root=[^ ]*\)" | paste -s -d ' '` || true db_set grub2/linux_cmdline "${kopt}" || true db_set grub-pc/kopt_extracted true || true if [ "${kopt}" = "" ] ; then # something smells bad. give user a chance to correct it. priority=high else # if we got something from menu.lst, it must be correct? priority=medium fi timeout=`sed -ne "s/^timeout[[:space:]][[:space:]]*//p" /boot/grub/menu.lst` || true if [ "${timeout}" != "" ]; then db_set grub-pc/timeout "${timeout}" || true fi if grep -q '^hiddenmenu\([[:space:]]\|$\)' /boot/grub/menu.lst; then db_set grub-pc/hidden_timeout true || true else db_set grub-pc/hidden_timeout false || true fi fi fi ;; esac for x in /etc/default/grub /etc/default/grub.d/*.cfg ; do if [ -e "$x" ]; then . "$x" fi done if [ "${GRUB_CMDLINE_LINUX+set}" = set ]; then db_set grub2/linux_cmdline "$GRUB_CMDLINE_LINUX" fi if [ "${GRUB_CMDLINE_LINUX_DEFAULT+set}" = set ]; then db_set grub2/linux_cmdline_default "$GRUB_CMDLINE_LINUX_DEFAULT" fi case @PACKAGE@ in grub-pc) if [ "${GRUB_TIMEOUT}" != "" ]; then db_set grub-pc/timeout "$GRUB_TIMEOUT" fi if [ "${GRUB_HIDDEN_TIMEOUT}" != "" ]; then db_set grub-pc/hidden_timeout true elif egrep -qs '^#?[[:space:]]*GRUB_HIDDEN_TIMEOUT=' /etc/default/grub; then db_set grub-pc/hidden_timeout false fi ;; esac db_input ${priority} grub2/linux_cmdline || true db_input medium grub2/linux_cmdline_default || true db_go debian/control0000664000000000000000000010270112524662415010603 0ustar Source: grub2 Section: admin Priority: extra Maintainer: Ubuntu Developers XSBC-Original-Maintainer: GRUB Maintainers Uploaders: Robert Millan , Felix Zielcke , Jordi Mallach , Colin Watson Build-Depends: debhelper (>= 7.4.2~), dpkg-dev (>= 1.15.1~), patchutils, dh-autoreconf, automake (>= 1.10.1), python, flex (>= 2.5.35), bison, po-debconf, help2man, texinfo, gcc-4.7-multilib [i386 kopensolaris-i386 any-amd64 any-ppc64 any-sparc], gcc-4.7 [!any-ppc64el], gcc-4.8-powerpc-linux-gnu [any-ppc64el], gcc-4.8 [any-ppc64el], libc6-dev-powerpc-cross [any-ppc64el], xfonts-unifont, libfreetype6-dev, gettext, libusb-dev [!hurd-any], libdevmapper-dev (>= 2:1.02.34) [linux-any], libgeom-dev (>= 8.2+ds1-1) [kfreebsd-any] | libgeom-dev (<< 8.2) [kfreebsd-any], libsdl1.2-dev [!hurd-any], xorriso (>= 0.5.6.pl00), qemu-system [i386 kfreebsd-i386 kopensolaris-i386 any-amd64], cpio [i386 kopensolaris-i386 amd64], parted [!hurd-any], libfuse-dev (>= 2.8.4-1.4) [linux-any kfreebsd-any], ttf-dejavu-core, liblzma-dev, dosfstools [amd64], mtools [amd64], wamerican, libxen-dev [i386 amd64], Build-Conflicts: autoconf2.13, libzfs-dev, libnvpair-dev Standards-Version: 3.8.4 Homepage: http://www.gnu.org/software/grub/ Vcs-Git: git://anonscm.debian.org/pkg-grub/grub.git -b experimental Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-grub/grub.git;a=shortlog;h=refs/heads/experimental Package: grub2 Section: oldlibs Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc Depends: grub-pc (= ${binary:Version}) [any-i386 any-amd64] | grub-ieee1275 (= ${binary:Version}) [any-powerpc any-ppc64 any-ppc64el any-sparc], ${misc:Depends} Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (dummy package) This is a dummy transitional package to handle GRUB 2 upgrades. It can be safely removed. Package: grub-linuxbios Section: oldlibs Architecture: any-i386 any-amd64 Depends: grub-coreboot (= ${binary:Version}), ${misc:Depends} Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (dummy package) This is a dummy transitional package that depends on grub-coreboot. Package: grub-efi Section: oldlibs Architecture: any-i386 any-amd64 Depends: ${misc:Depends}, grub-efi-ia32 (= ${binary:Version}) [any-i386], grub-efi-amd64 (= ${binary:Version}) [any-amd64] Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (dummy package) This is a dummy transitional package that depends on either grub-efi-ia32 or grub-efi-amd64, depending on the architecture. Package: grub-common Priority: optional Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-mipsel any-ia64 any-arm any-arm64 Depends: ${shlibs:Depends}, ${misc:Depends}, gettext-base, ${lsb-base-depends} Replaces: grub-pc (<< 2.00-4), grub-ieee1275 (<< 2.00-4), grub-efi (<< 1.99-1), grub-coreboot (<< 2.00-4), grub-linuxbios (<< 1.96+20080831-1), grub-efi-ia32 (<< 2.00-4), grub-efi-amd64 (<< 2.00-4), grub-efi-ia64 (<< 2.00-4), grub-yeeloong (<< 2.00-4) Recommends: os-prober (>= 1.33) Suggests: multiboot-doc, grub-emu, xorriso (>= 0.5.6.pl00), desktop-base (>= 4.0.6), console-setup # See bugs #435983 and #455746 Conflicts: mdadm (<< 2.6.7-2) Breaks: lupin-support (<< 0.55), friendly-recovery (<< 0.2.13), apport (<< 2.1.1) Multi-Arch: foreign Description: GRand Unified Bootloader (common files) This package contains common files shared by the distinct flavours of GRUB. It is shared between GRUB Legacy and GRUB 2, although a number of files specific to GRUB 2 are here as long as they do not break GRUB Legacy. Package: grub2-common Priority: optional Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-mipsel any-ia64 any-arm any-arm64 Depends: grub-common (= ${binary:Version}), dpkg (>= 1.15.4) | install-info, ${shlibs:Depends}, ${misc:Depends} Replaces: grub, grub-legacy, grub-common (<< 1.99-1), grub-pc (<< 2.00-4), grub-ieee1275 (<< 2.00-4), grub-efi (<< 1.99-1), grub-coreboot (<< 2.00-4), grub-linuxbios (<< 1.99-1), grub-efi-ia32 (<< 2.00-4), grub-efi-amd64 (<< 2.00-4), grub-efi-ia64 (<< 2.00-4), grub-ieee1275 (<< 2.00-4), grub-yeeloong (<< 2.00-4) Conflicts: grub (<< 0.97-54), grub-legacy, ${legacy-doc-conflicts} Multi-Arch: foreign Description: GRand Unified Bootloader (common files for version 2) This package contains common files shared by the distinct flavours of GRUB. The files in this package are specific to GRUB 2, and would break GRUB Legacy if installed on the same system. Package: grub-emu Architecture: any-i386 any-amd64 any-powerpc Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}) Replaces: grub-common (<= 1.97~beta3-1) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (emulated version) This package contains grub-emu, an emulated version of GRUB. It is only provided for debugging purposes. Package: grub-emu-dbg Section: debug Architecture: any-i386 any-amd64 any-powerpc Depends: ${misc:Depends}, grub-emu (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (emulated debug files) This package contains debugging files for grub-emu. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-pc-bin Priority: optional Architecture: any-i386 any-amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}) Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-pc (<< 1.99-1) Suggests: desktop-base (>= 4.0.6) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (PC/BIOS binaries) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. - VESA-based graphical mode with background image support and complete 24-bit color set. - Support for extended charsets. Users can write UTF-8 text to their menu entries. . This package contains a version of GRUB that has been built for use with traditional PC/BIOS architecture. It will not automatically install GRUB as the active boot loader, nor will it automatically update grub.cfg on upgrade, so most people should install grub-pc instead. Package: grub-pc-dbg Section: debug Architecture: any-i386 any-amd64 Depends: ${misc:Depends}, grub-pc-bin (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (PC/BIOS debug files) This package contains debugging files for grub-pc-bin. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-pc Priority: optional Architecture: any-i386 any-amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-pc-bin (= ${binary:Version}), ucf, freebsd-utils (>= 8.0-4) [kfreebsd-any], ${gfxpayload-depends} Replaces: grub, grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-ieee1275 Conflicts: grub (<< 0.97-54), grub-legacy, grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-ieee1275, grub-xen Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (PC/BIOS version) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. - VESA-based graphical mode with background image support and complete 24-bit color set. - Support for extended charsets. Users can write UTF-8 text to their menu entries. . This package contains a version of GRUB that has been built for use with traditional PC/BIOS architecture. Package: grub-rescue-pc Architecture: any-i386 any-amd64 Depends: ${misc:Depends} Multi-Arch: foreign Description: GRUB bootable rescue images, version 2 (PC/BIOS version) This package contains three GRUB rescue images that have been built for use with the traditional PC/BIOS architecture: . - grub-rescue-floppy.img: floppy image. - grub-rescue-cdrom.iso: El Torito CDROM image. - grub-rescue-usb.img: USB image. Package: grub-coreboot-bin Architecture: any-i386 any-amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}) Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-linuxbios, grub-coreboot (<< 1.99-1) Conflicts: grub-linuxbios (<< ${source:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Coreboot binaries) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with platforms running the Coreboot firmware. It will not automatically install GRUB as the active boot loader, nor will it automatically update grub.cfg on upgrade, so most people should install grub-coreboot instead. Package: grub-coreboot-dbg Section: debug Architecture: any-i386 any-amd64 Depends: ${misc:Depends}, grub-coreboot-bin (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Coreboot debug files) This package contains debugging files for grub-coreboot-bin. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-coreboot Architecture: any-i386 any-amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-coreboot-bin (= ${binary:Version}), ucf Replaces: grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-linuxbios, grub-efi-amd64, grub-efi-ia32, grub-pc, grub-ieee1275 Conflicts: grub (<< 0.97-54), grub-legacy, grub-linuxbios (<< ${source:Version}), grub-efi-amd64, grub-efi-ia32, grub-pc, grub-ieee1275, grub-xen Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Coreboot version) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with platforms running the Coreboot firmware. Package: grub-efi-ia32-bin Architecture: any-i386 any-amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}), efibootmgr [i386 amd64] Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi, grub-efi-ia32 (<< 1.99-1) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (EFI-IA32 binaries) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with EFI-IA32 architecture, such as the one provided by Intel Macs (that is, unless a BIOS interface has been activated). It will not automatically install GRUB as the active boot loader, nor will it automatically update grub.cfg on upgrade, so most people should install grub-efi-ia32 instead. Package: grub-efi-ia32-dbg Section: debug Architecture: any-i386 any-amd64 Depends: ${misc:Depends}, grub-efi-ia32-bin (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (EFI-IA32 debug files) This package contains debugging files for grub-efi-ia32-bin. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-efi-ia32 Architecture: any-i386 any-amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-ia32-bin (= ${binary:Version}), ucf Replaces: grub, grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi, grub-efi-amd64, grub-pc, grub-coreboot, grub-ieee1275 Conflicts: grub (<< 0.97-54), grub-legacy, grub-efi-amd64, grub-pc, grub-coreboot, grub-ieee1275, grub-xen, elilo Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (EFI-IA32 version) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with EFI-IA32 architecture, such as the one provided by Intel Macs (that is, unless a BIOS interface has been activated). Package: grub-efi-amd64-bin Architecture: i386 kopensolaris-i386 any-amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}), efibootmgr [i386 amd64] Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi-amd64 (<< 1.99-1) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (EFI-AMD64 binaries) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with EFI-AMD64 architecture, such as the one provided by Intel Macs (that is, unless a BIOS interface has been activated). It will not automatically install GRUB as the active boot loader, nor will it automatically update grub.cfg on upgrade, so most people should install grub-efi-amd64 instead. Package: grub-efi-amd64-dbg Section: debug Architecture: i386 kopensolaris-i386 any-amd64 Depends: ${misc:Depends}, grub-efi-amd64-bin (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (EFI-AMD64 debug files) This package contains debugging files for grub-efi-amd64-bin. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-efi-amd64 Architecture: i386 kopensolaris-i386 any-amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-amd64-bin (= ${binary:Version}), ucf Replaces: grub, grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-pc, grub-efi-ia32, grub-coreboot, grub-ieee1275 Conflicts: grub, grub-legacy, grub-efi-ia32, grub-pc, grub-coreboot, grub-ieee1275, grub-xen, elilo Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (EFI-AMD64 version) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with EFI-AMD64 architecture, such as the one provided by Intel Macs (that is, unless a BIOS interface has been activated). Package: grub-efi-ia64-bin Architecture: any-ia64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (IA64 binaries) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use on IA64. It will not automatically install GRUB as the active boot loader, nor will it automatically update grub.cfg on upgrade, so most people should install grub-efi-ia64 instead. Package: grub-efi-ia64-dbg Section: debug Architecture: any-ia64 Depends: ${misc:Depends}, grub-efi-ia64-bin (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (IA64 debug files) This package contains debugging files for grub-efi-ia64-bin. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-efi-ia64 Architecture: any-ia64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-ia64-bin (= ${binary:Version}), ucf Conflicts: elilo Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (IA64 version) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use on IA64. Package: grub-efi-arm-bin Architecture: any-arm Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (ARM UEFI binaries) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use on ARM systems with UEFI. It will not automatically install GRUB as the active boot loader, nor will it automatically update grub.cfg on upgrade, so most people should install grub-efi-arm instead. Package: grub-efi-arm-dbg Section: debug Architecture: any-arm Depends: ${misc:Depends}, grub-efi-arm-bin (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (ARM UEFI debug files) This package contains debugging files for grub-efi-arm-bin. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-efi-arm Architecture: any-arm Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-arm-bin (= ${binary:Version}), ucf Conflicts: grub-uboot Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (ARM UEFI version) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use on ARM systems with UEFI. Package: grub-efi-arm64-bin Architecture: any-arm64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}), efibootmgr [linux-any] Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (ARM64 UEFI binaries) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use on ARM64 systems with UEFI. It will not automatically install GRUB as the active boot loader, nor will it automatically update grub.cfg on upgrade, so most people should install grub-efi-arm64 instead. Package: grub-efi-arm64-dbg Section: debug Architecture: any-arm64 Depends: ${misc:Depends}, grub-efi-arm64-bin (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (ARM64 UEFI debug files) This package contains debugging files for grub-efi-arm64-bin. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-efi-arm64 Architecture: any-arm64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-arm64-bin (= ${binary:Version}), ucf Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (ARM64 UEFI version) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use on ARM64 systems with UEFI. Package: grub-ieee1275-bin Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}) Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-ieee1275 (<< 1.99-1) Suggests: genisoimage [any-powerpc any-ppc64 any-ppc64el] Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Open Firmware binaries) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with Open Firmware implementations. It will not automatically install GRUB as the active boot loader, nor will it automatically update grub.cfg on upgrade, so most people should install grub-ieee1275 instead. Package: grub-ieee1275-dbg Section: debug Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc Depends: ${misc:Depends}, grub-ieee1275-bin (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Open Firmware debug files) This package contains debugging files for grub-ieee1275-bin. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-ieee1275 Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-ieee1275-bin (= ${binary:Version}), ucf, powerpc-ibm-utils (>= 1.2.12-1) [any-powerpc any-ppc64 any-ppc64el], powerpc-utils [any-powerpc any-ppc64 any-ppc64el] Replaces: grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-pc Conflicts: grub (<< 0.97-54), grub-legacy, grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-pc, grub-xen Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Open Firmware version) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with Open Firmware implementations. Package: grub-firmware-qemu Architecture: any-i386 any-amd64 Depends: ${misc:Depends} Recommends: qemu Enhances: qemu Multi-Arch: foreign Description: GRUB firmware image for QEMU This package contains a binary of GRUB that has been built for use as firmware for QEMU. It can be used as a replacement for other PC BIOS images provided by seabios, bochsbios, and so on. . In order to make QEMU use this firmware, simply add `-bios grub.bin' when invoking it. . This package behaves in the same way as GRUB for coreboot, but doesn't contain any code from coreboot itself, and is only suitable for QEMU. If you want to install GRUB as firmware on real hardware, you need to use the grub-coreboot package, and manually combine that with coreboot. Package: grub-uboot-bin Architecture: any-arm Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (ARM U-Boot binaries) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with ARM systems with U-Boot. It will not automatically install GRUB as the active boot loader, nor will it automatically update grub.cfg on upgrade, so most people should install grub-uboot instead. Package: grub-uboot-dbg Section: debug Architecture: any-arm Depends: ${misc:Depends}, grub-uboot-bin (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (ARM U-Boot debug files) This package contains debugging files for grub-uboot-bin. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-uboot Architecture: any-arm Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-uboot-bin (= ${binary:Version}), ucf Conflicts: grub-efi-arm Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (ARM U-Boot version) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with ARM systems with U-Boot. Package: grub-xen-bin Architecture: i386 amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Xen binaries) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with the Xen hypervisor (i.e. PV-GRUB). It will not automatically install GRUB as the active boot loader, nor will it automatically update grub.cfg on upgrade, so most people should install grub-xen instead. Package: grub-xen-dbg Section: debug Architecture: i386 amd64 Depends: ${misc:Depends}, grub-xen-bin (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Xen debug files) This package contains debugging files for grub-xen-bin. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-xen Architecture: i386 amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-xen-bin (= ${binary:Version}), ucf Conflicts: grub (<< 0.97-54), grub-legacy, grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-ieee1275, grub-pc Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Xen version) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with the Xen hypervisor (i.e. PV-GRUB). Package: grub-yeeloong-bin Architecture: any-mipsel Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version}) Replaces: grub-common (<< 1.98+20100617-2), grub-yeeloong (<< 1.99-1) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Yeeloong binaries) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with the Lemote Yeeloong laptop. It will not automatically install GRUB as the active boot loader, nor will it automatically update grub.cfg on upgrade, so most people should install grub-yeeloong instead. Package: grub-yeeloong-dbg Section: debug Architecture: any-mipsel Depends: ${misc:Depends}, grub-yeeloong-bin (= ${binary:Version}), grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Yeeloong debug files) This package contains debugging files for grub-yeeloong-bin. You only need these if you are trying to debug GRUB using its GDB stub. Package: grub-yeeloong Architecture: any-mipsel Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-yeeloong-bin (= ${binary:Version}), ucf Replaces: grub-common (<< 1.98+20100617-2) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (Yeeloong version) GRUB is a portable, powerful bootloader. This version of GRUB is based on a cleaner design than its predecessors, and provides the following new features: . - Scripting in grub.cfg using BASH-like syntax. - Support for modern partition maps such as GPT. - Modular generation of grub.cfg via update-grub. Packages providing GRUB add-ons can plug in their own script rules and trigger updates by invoking update-grub. . This package contains a version of GRUB that has been built for use with the Lemote Yeeloong laptop. Package: grub-theme-starfield Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-mipsel any-ia64 any-arm any-arm64 Depends: ${misc:Depends}, grub-common (= ${binary:Version}) Multi-Arch: foreign Description: GRand Unified Bootloader, version 2 (starfield theme) This is the default theme for GRUB's graphical menu. Package: grub-mount-udeb XC-Package-Type: udeb Section: debian-installer Architecture: i386 amd64 powerpc ppc64 ppc64el sparc mipsel ia64 armel armhf arm64 kfreebsd-i386 kfreebsd-amd64 Depends: ${shlibs:Depends}, ${misc:Depends} Description: export GRUB filesystems using FUSE debian/grub-common.maintscript.linux.in0000664000000000000000000000016312524662415015446 0ustar # Removed in 1.96+20090307-1. rm_conffile /etc/grub.d/10_freebsd 2.00-14~ rm_conffile /etc/grub.d/10_hurd 2.00-14~ debian/grub2-common.install0000664000000000000000000000040712524662415013077 0ustar ../../debian/default usr/share/grub ../../debian/update-grub usr/sbin usr/sbin/grub-install usr/sbin/grub-reboot usr/sbin/grub-set-default usr/share/info usr/share/man/man8/grub-install.8 usr/share/man/man8/grub-reboot.8 usr/share/man/man8/grub-set-default.8 debian/grub-coreboot-bin.install.kopensolaris-i386.in0000664000000000000000000000004612524662415017712 0ustar usr/lib/grub/@CPU_PLATFORM@/efiemu*.o debian/grub-common.install.sparc.in0000664000000000000000000000007612524662415014533 0ustar usr/sbin/grub-ofpathname usr/share/man/man8/grub-ofpathname.8 debian/update-grub0000664000000000000000000000010012524662415011330 0ustar #!/bin/sh set -e exec grub-mkconfig -o /boot/grub/grub.cfg "$@" debian/grub-mount-udeb.install0000664000000000000000000000004712524662415013604 0ustar usr/bin/grub-mount usr/sbin/grub-probe debian/grub-pc.links.in0000664000000000000000000000020712524662415012204 0ustar usr/lib/grub/@CPU_PLATFORM@/grub-ntldr-img usr/bin/grub-ntldr-img usr/lib/grub/@CPU_PLATFORM@/grub-bios-setup usr/sbin/grub-bios-setup debian/grub-common.maintscript.hurd.in0000664000000000000000000000016412524662415015252 0ustar # Removed in 1.96+20090307-1. rm_conffile /etc/grub.d/10_freebsd 2.00-14~ rm_conffile /etc/grub.d/10_linux 2.00-14~ debian/grub-common.install.in0000664000000000000000000000265312524662415013427 0ustar ../../debian/apport/source_grub2.py usr/share/apport/package-hooks/ ../../debian/grub.d etc etc/bash_completion.d etc/grub.d usr/bin/grub-editenv usr/bin/grub-file usr/bin/grub-fstest usr/bin/grub-glue-efi usr/bin/grub-kbdcomp usr/bin/grub-menulst2cfg usr/bin/grub-mkfont usr/bin/grub-mkimage usr/bin/grub-mklayout usr/bin/grub-mknetdir usr/bin/grub-mkpasswd-pbkdf2 usr/bin/grub-mkrelpath usr/bin/grub-mkrescue usr/bin/grub-mkstandalone usr/bin/grub-render-label usr/bin/grub-script-check usr/bin/grub-syslinux2cfg usr/sbin/grub-macbless usr/sbin/grub-mkconfig usr/sbin/grub-mkdevicemap usr/sbin/grub-probe usr/share/grub/*.h usr/share/grub/*.pf2 usr/share/grub/grub-mkconfig_lib usr/share/locale usr/share/man/man1/grub-editenv.1 usr/share/man/man1/grub-file.1 usr/share/man/man1/grub-fstest.1 usr/share/man/man1/grub-glue-efi.1 usr/share/man/man1/grub-kbdcomp.1 usr/share/man/man1/grub-menulst2cfg.1 usr/share/man/man1/grub-mkfont.1 usr/share/man/man1/grub-mkimage.1 usr/share/man/man1/grub-mklayout.1 usr/share/man/man1/grub-mknetdir.1 usr/share/man/man1/grub-mkpasswd-pbkdf2.1 usr/share/man/man1/grub-mkrelpath.1 usr/share/man/man1/grub-mkrescue.1 usr/share/man/man1/grub-mkstandalone.1 usr/share/man/man1/grub-render-label.1 usr/share/man/man1/grub-script-check.1 usr/share/man/man1/grub-syslinux2cfg.1 usr/share/man/man8/grub-macbless.8 usr/share/man/man8/grub-mkconfig.8 usr/share/man/man8/grub-mkdevicemap.8 usr/share/man/man8/grub-probe.8 debian/kernel/0000775000000000000000000000000012524676037010464 5ustar debian/kernel/zz-update-grub0000775000000000000000000000120112524662415013257 0ustar #! /bin/sh set -e which update-grub >/dev/null 2>&1 || exit 0 if type running-in-container >/dev/null 2>&1 && \ running-in-container >/dev/null; then exit 0 fi set -- $DEB_MAINT_PARAMS mode="${1#\'}" mode="${mode%\'}" case $0:$mode in # Only run on postinst configure and postrm remove, to avoid wasting # time by calling update-grub multiple times on upgrade and removal. # Also run if we have no DEB_MAINT_PARAMS, in order to work with old # kernel packages. */postinst.d/*:|*/postinst.d/*:configure|*/postrm.d/*:|*/postrm.d/*:remove) if [ -e /boot/grub/grub.cfg ]; then exec update-grub fi ;; esac exit 0 debian/grub-common.dirs0000664000000000000000000000001112524662415012277 0ustar usr/sbin debian/grub-ieee1275-bin.install.ppc64el.in0000664000000000000000000000011712524662415015400 0ustar usr/lib/grub/@CPU_PLATFORM@/bootinfo.txt usr/lib/grub/@CPU_PLATFORM@/grub.chrp debian/po/0000775000000000000000000000000012634020236007604 5ustar debian/po/nl.po0000664000000000000000000003615312524662415010576 0ustar # Dutch translation of grub2 debconf templates. # Copyright (C) 2008-2011 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the grub2 package. # Paul Gevers , 2008-2010. # Jeroen Schot , 2011. # msgid "" msgstr "" "Project-Id-Version: grub2 1.99-14\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-12-06 08:19+0100\n" "Last-Translator: Jeroen Schot \n" "Language-Team: Debian l10n Dutch \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Doorschakelen vanuit menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "GRUBs opwaardeerscripts hebben een oude-stijl GRUB opstelling in /boot/grub " "gedetecteerd." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Om de oude-stijl versie van GRUB op uw systeem te vervangen wordt het " "aangeraden om het /boot/grub/menu.lst bestand zo te laten aanpassen dat er " "een GRUB 2 opstartopname wordt geladen vanuit uw bestaande oude-stijl GRUB " "opstelling. Deze stap kan nu automatisch worden uitgevoerd." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "U wordt aangeraden om het doorschakelen van GRUB 2 vanuit menu.lst te " "accepteren, en daarna te verifiëren dat de nieuwe GRUB 2 opstelling werkt " "voordat het in de MBR (Master Boot Record) wordt geïnstalleerd." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Waar u ook voor kiest, u kunt de oude MBR opname later door GRUB 2 vervangen " "door het volgende commando uit te voeren (met beheerdersrechten (root)):" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB installatie apparaten:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Het grub-pc pakket wordt bijgewerkt. Dit menu stelt u in staat om de " "apparaten te selecteren waar u wilt dat grub-install automatisch gedraaid " "wordt." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Het wordt over het algemeen aanbevolen om grub-install automatisch te laten " "draaien om te voorkomen dat de geïnstalleerde GRUB kernopname niet meer " "gesynchroniseerd is met GRUB modules of grub.cfg. " #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Indien u niet zeker weet welk station door de BIOS wordt gebruikt als " "opstartstation, is het vaak een goed idee om GRUB op alle stations te " "installeren." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Merk op dat het ook mogelijk is om GRUB naar opstartstructuren op partities " "te installeren. Enkele geschikte partities worden hier aangeboden. Dit wordt " "echter niet aangeraden omdat het GRUB dwingt om een bloklijstmechanisme te " "gebruiken waar het minder betrouwbaar van wordt." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Het GRUB opstartprogramma was voorheen geïnstalleerd op een schijf die niet " "langer aanwezig is, of waarvan de unieke identificatie is veranderd. Het is " "belangrijk om ervoor te zorgen dat de geïnstalleerde GRUB kernopname " "gesynchroniseerd blijft met GRUB modules en grub.cfg. Controleer of GRUB wel " "naar het juiste opstartapparaat wordt geschreven." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Schrijven van GRUB naar opstartapparaat mislukt. Doorgaan?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Het installeren van de volgende apparaten is mislukt: " #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Wilt u desondanks verder gaan? Verder gaan kan ervoor zorgen dat uw computer " "niet meer goed opstart." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Schrijven van GRUB naar opstartapparaat mislukt. Opnieuw proberen?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "U kunt proberen om GRUB te installeren op een ander apparaat, maar het wordt " "aangeraden om eerst te controleren of u kunt opstarten vanaf dat apparaat. " "Als u dit niet probeert, zal het nu opwaarderen van de oude-stijl GRUB " "geannuleerd worden." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Verder gaan zonder GRUB te installeren?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "U heeft ervoor gekozen om GRUB niet te installeren. Als u nu doorgaat zou " "het kunnen dat het opstartprogramma niet correct geconfigureerd is en dat de " "computer bij de volgende start de informatie gebruikt die vroeger in de " "opstartsector stond. Indien daar een eerdere versie van GRUB 2 staat, kan " "het zijn dat modules niet geladen kunnen worden of dat het huidige " "configuratiebestand niet verwerkt kan worden." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "U kunt verder gaan als u al een ander opstartprogramma gebruikt en deze wilt " "blijven gebruiken, of als dit een speciale omgeving is waar u geen " "opstartprogramma nodig heeft. In de overige gevallen wilt u waarschijnlijk " "GRUB installeren." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "GRUB 2 uit /boot/grub verwijderen?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Wilt u dat alle GRUB 2 bestanden worden verwijderd uit /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Dit heeft tot gevolg dat het systeem niet opgestart kan worden tenzij er een " "ander opstartprogramma is geïnstalleerd." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Wilt u de conversie naar GRUB 2 nu afronden?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Dit systeem heeft nog steeds bestanden van het oude-stijl GRUB " "opstartprogramma geïnstalleerd, maar er zijn nu ook GRUB 2 opstartopnames " "geïnstalleerd op de volgende schijven:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Het lijkt erop dat de oude-stijl GRUB niet langer gebruikt wordt en het " "wordt aanbevolen dat u de conversie naar GRUB 2 afrond door de GRUB 2 " "opnames op deze schijven op te waarderen en de oude-stijl GRUB bestanden te " "verwijderen. Indien u de GRUB 2 opnames niet opwaardeert, is het mogelijk " "dat ze incompatibel zijn met de nieuwe pakketten en kunnen ze uw systeem " "verhinderen correct op te starten." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "In het algemeen zult u de conversie naar GRUB 2 willen afmaken, tenzij deze " "opstartopnames gemaakt zijn door een GRUB 2 op een ander besturingssysteem." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux-commandoregel:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "De volgende Linux-commandoregel is gebaseerd op /etc/default/grub of op de " "'kopt'-parameter gevonden in het menu.lst bestand van de oude-stijl GRUB. " "Wilt u deze op correctheid controleren en indien nodig aanpassen? De " "commandoregel mag leeg zijn." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Standaard Linux-commandoregel:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "De volgende regel zal, behalve in de herstelmodus, gebruikt worden voor de " "Linux parameters in de standaard menuoptie." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD-commandoregel:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "De volgende kFreeBSD-commandoregel is gebaseerd op /etc/default/grub of op " "de 'kopt'-parameter gevonden in het menu.lst bestand van de oude-stijl GRUB. " "Wilt u deze op correctheid controleren en indien nodig aanpassen? De " "commandoregel mag leeg zijn." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Standaard kFreeBSD-commandoregel:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "De volgende regel zal, behalve in de herstelmodus, gebruikt worden voor de " "kFreeBSD parameters in de standaard menuoptie." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map is opnieuw aangemaakt" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Het bestand /boot/grub/device.map is zo herschreven dat het stabiele " "apparaatnamen gebruikt. In de meeste gevallen zal dit de noodzaak van " "toekomstige veranderingen verlagen en zullen door GRUB gegenereerde " "opstartmenu-items ongewijzigd zijn." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Het is mogelijk dat het systeem afhankelijk was van de oude apparatenlijst, " "aangezien er meer dan één schijf aanwezig is. Het wordt aanbevolen dat u de " "opstartmenu-items controleert op het gebruik van GRUB's schijfbenummering " "(hdN) en deze zo nodig aanpast." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "U kunt deze melding negeren indien u deze melding niet begrijpt, of als er " "geen zelfgemaakte menu-items aanwezig zijn." debian/po/nb.po0000664000000000000000000003601512524662415010561 0ustar # Norwegian Bokmål translation for grub2. # Copyright (C) 2010 grub2 # This file is distributed under the same license as the grub2 package. # Hans Fredrik Nordhaug , 2010-12. msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-03-12 02:14+0200\n" "Last-Translator: Hans Fredrik Nordhaug \n" "Language-Team: Norwegian Bokmål \n" "Language: nb\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Virtaal 0.7.1\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Kjedelaste fra menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Oppgraderingsskriptene til GRUB har funnet et GRUB Legacy-oppsett i /boot/" "grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "For å erstatte Legacy-versjonen av GRUB på ditt system anbefales det at /" "boot/grub/menu.lst justeres til å laste GRUB 2 oppstartsbilde fra ditt " "eksisterende GRUB Legacy-oppsett. Dette steget kan utføres automatisk nå." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Det anbefales at du aksepterer å kjedelaste GRUB 2 fra menu.lst, og " "verifiserer at det nye GRUB 2-oppsettet virker før det skrives til MBR " "(Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Uavhengig av din avgjørelse kan du erstatte det gamle MBR-bildet med GRUB 2 " "senere ved å kjøre følgende kommando som root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB installasjonsenheter:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Pakken grub-pc blir oppgradert. Denne menyen lar deg velge hvilke enheter " "hvilke enheter du vil at grub-install skal kjøres automatisk for, hvis noen." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Kjøring av grub-install automatisk anbefales i de fleste situasjoner for å " "forhindre at det installerte GRUB-kjernebildet kommer ut av synk med GRUB-" "moduler i grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Hvis du er usikker hvilken disk som er satt som oppstartsdisk i din BIOS, er " "det ofte en god ide å installere GRUB på alle diskene. " #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Merk: Det er mulig å installere GRUB til partisjonsoppstartsposter også, og " "noen passende partisjoner er foreslått her. Imidlertid tvinger dette GRUB " "til å bruke blocklist-mekanismen som ikke er like pålitelig og derfor ikke " "anbefalt." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB oppstartslasteren var tidligere installert på en disk som ikke lenger " "fins eller på en disk hvor den unike identifikatoren er endret av eller " "annen grunn. Det er viktig å være sikker på at det installerte GRUB-" "kjernebildet forblir i synk med GRUB-moduler og grub.cfg. Sjekk igjen at " "GRUB skrive til passende oppstartsenhet." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Klarte ikke skrive GRUB til oppstartsenhet - fortsette?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Klarte ikke installere GRUB på følgende enheter:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Ønsker du å fortsette likevel? Hvis du fortsetter, vil kanskje ikke din " "datamaskin starte opp skikkelig." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Klarte ikke skrive GRUB til oppstartsenhet - prøve igjen?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Du kan klare å installere GRUB på en annen enhet, selvom du bør sjekke at " "systemet ditt kan/vil starte opp fra den enheten. Ellers vil oppgraderingen " "fra GRUB Legacy bli avbrutt." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Fortsett uten å installere GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Du har valgt å ikke installere GRUB på noen enhet. Hvis du fortsetter, vil " "oppstartslasteren kanskje ikke være skikkelig satt opp, og når denne " "datamaskinen starter opp neste gang vil den bruke det tidligere innholdet i " "oppstartssektoren. Hvis det er en tidligere versjon av GRUB 2 i " "oppstartsektoren, vil den kanskje ikke være i stand til å laste inn moduler " "eller håndtere den aktuelle konfigurasjonsfilen." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Hvis du allerede kjører en annen oppstartslaster og ønsker å fortsette med " "det, eller hvis dette er et spesielt miljø hvor du ikke har bruk for en " "oppstartslaster, så skal du fortsette likevel. Ellers, bør du installere " "GRUB et eller annet sted." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Fjern GRUB 2 fra /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Vil du at alle filer for GRUB 2 skal fjernes fra /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Dette vil gjøre at systemet ikke kan starte med mindre en annen " "oppstartslaster er installert." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Avslutt konvertering til GRUB 2 nå?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Dette systemet har fremdeles installert filer fra GRUB Legacy-" "oppstartslasteren, men systemet har nå også GRUB 2 oppstartsposter " "installert på disse diskene:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Det virker sannsynlig at GRUB Legacy ikke lenger er i bruk, og at du i " "steden for skal oppgradere GRUB 2-bildene på disse diskene og avslutte " "konverteringen til GRUB 2 ved å fjerne eldre GRUB Legacy-filer. Hvis du ikke " "oppgraderer disse GRUB 2-bildene, så er de kanskje ikke kompatible med de " "nye pakkene og kan få ditt system til å stoppe å starte opp skikkelig." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Du bør generelt avslutte konverteringen til GRUB 2 med mindre disse " "oppstartspostene ble opprettet av en GRUB 2-installasjon på et annet " "operativsystem." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Kommandolinje i Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Den følgende Linux-kommandolinjen ble trukket ut fra /etc/default/grub eller " "parameteren `kopt' i GRUB Legacys menu.lst. Verifiser at den er korrekt og " "endre den om nødvendig. Det er lov at kommandolinjen er tom." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Standardkommandolinje i Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Den følgende teksten vil bli brukt som Linux-parametre for " "standardmenupunktet, men ikke for gjenopprettelsesmodus." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Kommandolinje i kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Den følgende kFreeBSD-kommandolinjen ble trukket ut fra /etc/default/grub " "eller fra parameteren `kopt' i GRUB Legacys menu.lst. Verifiser at den er " "korrekt, og endre den om nødvendig. Det er lov at kommandolinjen er tom." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Standardkommandolinje i kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Den følgende teksten vil bli brukt som kFreeBSD-parametre for " "standardmenupunktet men ikke for gjenopprettelsesmodus." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map er regenerert" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Filen /boot/grub/device.map er oppdatert til å bruke stabile enhetsnavn. I " "de fleste tilfeller vil dette markant redusere behovet for å endre filen " "fremover, og oppstartsmenupunkter opprettet av GRUB skal ikke bli påvirket." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Siden det er mer enn en disk i sytemet, er det mulig at systemet er avhengig " "av det gamle enhetskartet. Sjekk om det er noen tilpassede " "oppstartsmenupunkter som er avhengig av GRUBs (hdN) disknummerering, og " "oppdater dem om nødvendig." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Hvis du ikke forstår denne beskjeden, eller det ikke er noen tilpassede " "oppstartsmenypunkter, kan du ignorere denne beskjeden." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Uansett hva, når du ønsker at GRUB 2 skal lastes inn direkte fra MBR, kan " #~ "du gjøre ved å utføre følgende kommando (som root):" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Klarte ikke installere GRUB. Fortsett?" debian/po/ar.po0000664000000000000000000004230312524662415010561 0ustar # translation of grub.ar.po to Arabic # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Ossama M. Khayat , 2008, 2009, 2010. msgid "" msgstr "" "Project-Id-Version: grub.ar\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2010-07-16 02:38+0300\n" "Last-Translator: Ossama M. Khayat \n" "Language-Team: Arabic \n" "Language: ar\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "تفعيل التحميل التسلسلي من menu.lst؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "عثرت بريمجيات ترقية GRUB على إعداد سابق في /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 #, fuzzy #| msgid "" #| "In order to replace the Legacy version of GRUB in your system, it is " #| "recommended that /boot/grub/menu.lst is adjusted to chainload GRUB 2 from " #| "your existing GRUB Legacy setup. This step may be automaticaly performed " #| "now." msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "لتستبدل النسخة السابقة من GRUB في نظامك، يُستحسن تعديل الملف /boot/grub/menu." "lst لتحميل GRUB 2 تسلسلياً من إعداد GRUB السابق. ويمكن تنفيذ هذه الخطوة " "تلقائياً الآن." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 #, fuzzy #| msgid "" #| "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " #| "verify that your new GRUB 2 setup is functional for you, before you " #| "install it directly to your MBR (Master Boot Record)." msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "يُستحسن أن تقبل التحميل التسلسلي لمدير الإقلاع GRUB من خلال الملف menu.lst، " "وتحقق من أن إعداد GRUB 2 صالح لاستخدامك، قبل أن تُبّته مباشرة على سجل الإقلاع " "الرئيسي MBR الخاص بك." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 #, fuzzy #| msgid "GRUB failed to install to the following devices:" msgid "GRUB install devices:" msgstr "تعذر تثبيت GRUB على الأجهزة التالية:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 #, fuzzy msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} م.ب.، ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 #, fuzzy #| msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "${DEVICE} (${SIZE} م.ب.، ${MODEL})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "تعذر تثبيت GRUB على الأجهزة التالية:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "هل تريد الاستمرار على أي حال؟ إن فعلت، فقد لا يتمكن جهازك من بدء التشغيل كما " "يجب." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 #, fuzzy #| msgid "GRUB installation failed. Try again?" msgid "Writing GRUB to boot device failed - try again?" msgstr "تعذر تثبيت GRUB. تريد المحاولة مجدداً؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "قد تتمكن من تثبيت GRUB على جهاز آخر، لكن يجب أن تتحقق من إمكانية نظامك " "الإقلاع من ذلك الجهاز. وإن لم يكن كذلك، فسيتم إلغاء الترقية من نظام GRUB " "القديم." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "تريد الاستمرار دون تثبيت GRUB؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 #, fuzzy #| msgid "" #| "You chose not to install GRUB to any devices. If you continue, the boot " #| "loader may not be properly configured, and when your computer next starts " #| "up it will use whatever was previously in the boot sector. If there is an " #| "earlier version of GRUB 2 in the boot sector, it may be unable to load " #| "modules or handle the current configuration file." msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "اخترت عدم تثبيت GRUB على أية جهاز. إن استمريت، فقد لا يتم تهيئة محمّل الإقلاع " "بشكل صحيح، كما يستخدم حاسبك أي نظام موجود على قطاع الإقلاع مسبقاً. إن كان " "هناك نسخة سابقة من GRUB 2 في قطاع الإقلاع، فقد لا يستطيع تحميل الوحدات أو " "قراءة ملف التهيئة الحالي بشكل صحيح." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 #, fuzzy #| msgid "" #| "If you are already running a different boot loader and want to carry on " #| "doing so, or if this is a special environment where you do not need a " #| "boot loader, then you should continue anyway. Otherwise, you should " #| "install GRUB somewhere." msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "إن كنت تستخدم محمل إقلاع آخر وتريد الاستمرار باستخدامه، أو إن كانت لديك بيئة " "عمل خاصة حيث لا تحتاج إلى محمل إقلاع، فيجب عليك الاستمرار على أي حال. وإلا " "يجب أن تقوم بتثبيت GRUB في مكان ما." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "إنهاء التحويل إلى GRUB 2 الآن؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "لا زال النظام يحتوي على ملفات GRUB قديمة مثبتة، كما يحتوي أيضاً على سجلات " "إقلاع GRUB 2 على هذه الأقراص:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "يبدو أن GRUB القديم لم يعد مستخدماً، ويجب عليك الترقية إلى GRUB 2 وإنهاء " "التحويل إلى GRUB 2 بإزالة ملفات GRUB القديمة. وإن لم تقم بعملية الترقية هذه، " "فقد لا يكون نظام الإقلاع متوافقاً مع الحزم الجديدة ويتسبب ذلك بعدم إقلاع نظام " "كما هو مفترض." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "بشكل عام، يجب عليك إنهاء التحويل إلى GRUB 2 إلا إن كانت سجلات الإقلاع هذه قد " "أنشأها تثبيت GRUB 2 لنظام تشغيل آخر." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "سطر أوامر لينكس:" #. Type: string #. Description #: ../templates.in:1001 #, fuzzy #| msgid "" #| "The following Linux command line was extracted from /etc/default/grub or " #| "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " #| "correct, and modify it if necessary." msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "سطر أوامر لينكس التالي تم استخراجه من /etc/default/grub أو\n" "مُعطى `kopt' في ملف menu.lst الخاص بحزمة GRUB القديمة. رجاءً تحقق من\n" "صحته وقم بتعديله إن كانت هناك ضرورة." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "سطر أوامر لينكس الافتراضي:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "سيتم استخدام سلسلة الحروف التالية كمُعطيات لتشغيل النظام لمُدخل القائمة\n" "الافتراضي ولكن ليس لوضع الإنقاذ." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "سطر أوامر KFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 #, fuzzy #| msgid "" #| "The following kFreeBSD command line was extracted from /etc/default/grub " #| "or the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it " #| "is correct, and modify it if necessary." msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "سطر أوامر KFreeBSD التالي تم استخراجه من /etc/default/grub أو\n" "مُعطى `kopt' في ملف menu.lst الخاص بحزمة GRUB القديمة. رجاءً تحقق من صحته وقم " "بتعديله إن كانت هناك ضرورة." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "سطر أوامر KFreeBSD الافتراضي:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "سيتم استخدام النص التالي كمُعطى KFreeBSD لمُدخل القائمة\n" "الافتراضي ولكن ليس لوضع الإنقاذ." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "تم إعادة إنشاء /boot/grub/device.map" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "تم إعادة كتابة الملف /boot/grub/device.map ليستخدم أسماء الأجهزة الصحيحة. في " "معظم الحالات، سيقلل هذا العمل الحاجة إلى التغييرات بشكل كبير في المستقبل، " "كما أن مُدخلات قائمة إقلاع GRUB الناتجة لن تتأثر." #. Type: note #. Description #: ../templates.in:5001 #, fuzzy #| msgid "" #| "However, since you have more than one disk in your system, it is possible " #| "that you were depending on the old device map. Please check whether you " #| "have any custom boot menu entries that rely on GRUB's (hdN) drive " #| "numbering, and update them if necessary." msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "على كل، حيث أنه لديك اكثر من قرص في نظامك، من المحتمل أنه كان يعتمد على " "خريطة الأجهزة القديمة. فالرجاء التحقق مما إذا كان لديك أية مُدخلات قائمة " "مخصصة تعتمد على طريقة GRUB لترقيم الأجهزة، (hdN)، وقم بتحديثها إن كانت " "ضرورياً." #. Type: note #. Description #: ../templates.in:5001 #, fuzzy #| msgid "" #| "If you do not understand this message, or if you do not have any custom " #| "boot menu entries, you can ignore this message." msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "إن لم تعرف مقصود هذه الرسالة، أو إن لم يكن لديك أية مُدخلات مُخصصة في القائمة، " "يمكنك تجاهل هذه الرسالة." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "في أي من الحالتين، متى ما أردت تحميل GRUB 2 مباشرة من سجل الإقلاع الرئيسي " #~ "MBR، يمكنك ذلك بإصدار الأمر التالي كمُستخدم root:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "تعذر تثبيت GRUB. تريد الاستمرار؟" debian/po/tr.po0000664000000000000000000003621212524662415010606 0ustar # Turkish messages for debian-installer. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the debian-installer package. # Atila KOÇ , 2012. # msgid "" msgstr "" "Project-Id-Version: debian-installer\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-01-23 01:09+0200\n" "Last-Translator: Atila KOÇ \n" "Language-Team: Debian L10n Turkish \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "menu.lst dosyasından zincirleme yükleme yapılsın mı?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "GRUB güncelleme betikleri /boot/grub altında eski bir GRUB kurulumu algıladı." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Sisteminizdeki eski sürüm GRUB kurulumunu değiştirmek için, /boot/grub/menu." "lst dosyasının bir GRUB 2 önyükleme görüntüsünü varolan eski GRUB " "kurulumundan yüklenmesine olanak tanıyacak şekilde değiştirilmesi " "gerekmektedir. Bu adım şimdi kendiliğinden gerçekleştirilebilir." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Yeni GRUB 2 kurulumu Ana Yükleme Kaydı'na (MBR) yazılmadan önce menu.lst'den " "GRUB 2 zincirleme önyüklemesini kabul etmeniz ve GRUB 2 kurulumunun " "çalıştığını doğrulamanız önerilir." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Seçiminiz ne olursa olsun, root kimliği ile aşağıdaki komutu işleterek eski " "MBR görüntüsünü GRUB 2 ile değiştirebilirsiniz:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB kurulum aygıtları:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "grub-pc paketi yükseltiliyor. Bu menü, eğer varsa, grub-kur'un (grub-" "install) hangi aygıtlar için kendiliğinden çalışmasını seçmenize olanak " "tanır." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "GRUB çekirdek görüntüsünün kurulmuş GRUB modülleri ya da grub.cfg ile " "eşitliğinin/uyumunun bozulmasını engellemek için, çoğu durumda grub-kur'un " "(grub-install) kendiliğinden çalıştırılması önerilir." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Eğer hangi sürücünün BIOS'unuz tarafından yükleme sürücüsü olarak " "belirlendiğinden emin değilseniz, GRUB'u tüm sürücülere kurmak yerinde " "olacaktır." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Not: GRUB'u disk bölümlerinin yükleme kayıtlarına yüklemek de olanak " "dahilindedir ve duruma uygun bazı bölümler burada listelenmiştir. Öte " "yandan, bu seçim GRUB'u daha az güvenilir kılan engelleme listesi " "(blocklist) mekanizmasını kullanmaya zorlayacağından önerilmemektedir." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB önyükleyici şu anda var olmayan ya da benzersiz tanımlayıcısı bir " "şekilde değişmiş bir diske kurulmuş durumdadır. Bu önyükleyicinin GRUB " "çekirdek görüntüsü ve grub.cfg ile uyum içinde olduğundan emin olmak " "önemlidir. Bu nedenle GRUB'un doğru önyükleme aygıtlarına yazılmış " "olduğundan emin olunuz." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "" "GRUB'u önyükleme aygıtına yazma işlemi başarısız oldu. Yine de devam edilsin " "mi?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Aşağıdaki aygıtlara GRUB kurulumu başarısız oldu:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Yine de devam edilsin mi? Devam edilirse bilgisayarınız düzgün " "başlamayabilir." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "GRUB'u önyükleme aygıtına yazma işlemi başarısız oldu. Tekrar denensin mi?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "GRUB'u başka bir aygıta kurma seçeneğiniz olabilir, bununla birlikte " "sisteminizin o aygıttan başlayabileceğini denetlemeniz gerekmektedir. Aksi " "durumda, eski GRUB'un yükseltilmesi yapılmayacaktır." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "GRUB kurulmadan devam edilsin mi?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "GRUB'u hiçbir aygıta kurmamayı seçtiniz. Devam ederseniz önyükleyici düzgün " "yapılandırılmayabilir ve bu bilgisayar bir sonraki açılışında önyükleme " "bölümünde daha önceden ne varsa onu kullanır. Eger önyükleme bölümünde GRUB " "2'nin daha önceki bir sürümü var ise, güncel yapılandırma dosyasını " "kullanamayabilir ya da birimleri yükleyemeyebilir." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Şu anda başka bir önyükleyici kullanıyorsanız ve kullanmaya da devam " "edecekseniz ya da bu sizin bir önyükleniciye gerek duymadığınız özel bir " "ortam ise bu şekilde devam edebilirsiniz. Aksi durumda, GRUB'u bir yere " "yüklemek zorundasınız." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "/boot/grub yolundan GRUB 2 kaldırılsın mı?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "" "/boot/grub yolundan bütün GRUB 2 dosyalarının kaldırılmasını istiyor musunuz?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Başka bir önyükleyici kurulmadıysa yapılan bu işlem sistemi başlatılamaz " "kılacaktır." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "GRUB 2'ye dönüşüm bitirilsin mi?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Bu sistemde hala eski GRUB kurulumundan kalan önyükleme dosyaları var, aynı " "zamanda da şu disklere yazılmış GRUB 2 önyükleme kayıtlarına sahip:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Göründüğü kadarı ile eski GRUB kurulumu artık kullanılmıyor, dolayısıyla bu " "disklerde eski GRUB dosyalarını kaldırıp GRUB 2 görüntülerine yükseltme " "yaparak dönüşümü tamamlamalısınız. Eğer bunları GRUB 2 görüntülerine " "yükseltmezseniz, yeni paketlerle uyum sorunları yaşanabilir ve bu durum " "sisteminizin gerektiği gibi başlamasına engel olabilir." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Bu önyükleme kayıtları başka bir işletim sistemindeki GRUB 2 kurulumu " "tarafından yaratılmadığı sürece GRUB 2 kurulumunu tamamlamanız gerekmektedir." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux komut satırı:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Aşağıdaki Linux komut satırı /etc/default/grub'dan ya da eski GRUB menu.lst " "dosyasındaki 'kopt' parametresinden türetilmiştir. Doğruluğundan emin olun " "ya da düzeltin. Komut satırını boş bırakabilirsiniz." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Öntanımlı Linux komut satırı:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Aşağıdaki dizge öntanımlı menü girişinin Linux parametreleri olarak " "kullanılacak fakat kurtarma kipi için kullanılmayacak." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD komut satırı:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Aşağıdaki kFreeBSD komut satırı /etc/default/grub'dan ya da eski GRUB menu." "lst dosyasındaki 'kopt' parametresinden türetilmiştir. Doğruluğundan emin " "olun ya da düzeltin. Komut satırını boş bırakabilirsiniz." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Öntanımlı kFreeBSD komut satırı:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Aşağıdaki dizge öntanımlı menü girişinin kFreeBSD parametreleri olarak " "kullanılacak fakat kurtarma kipi için kullanılmayacak." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map dosyası yeniden oluşturuldu" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "/boot/grub/device.map dosyası kararlı aygıt isimlerini kullanacak şekilde " "yeniden yazıldı. Bu işlem çoğu durumda ileride gerekebilecek bir düzenleme " "gereksinimini ciddi biçimde azaltır ve GRUB tarafından yaratılan önyükleme " "menüsü seçeneklerini etkilemez." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Öte yandan sistemde birden fazla disk olduğu için, sistemin eski aygıt " "eşlemine bağlı kalmış olması olasıdır. GRUB'un (hdN) sürücü " "numaralandırmasını kullanan herhangi bir özgün önyükleme menü şeçenegi olup " "olmadığını denetleyin ve gerekirse bunları güncelleyin." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Bu uyarıyı anlayamazsanız ya da herhangi bir özgün önyükleme menü seçeneği " "yok ise, bu uyarıyı gözardı edebilirsiniz." debian/po/he.po0000664000000000000000000003776412524662415010572 0ustar # translation of grub_debian_po_he.po to Hebrew # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # # Omer Zak , 2010, 2012. # Lior Kaplan , 2010. msgid "" msgstr "" "Project-Id-Version: grub_debian_po_he\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-01-21 00:52+0200\n" "Last-Translator: Omer Zak \n" "Language-Team: Hebrew \n" "Language: he\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "הטענה בשרשור מ-menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "תסריטי העדכון של GRUB גילו הגדרות GRUB ישנות ב-‎‎/boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "כדי להחליף את גירסת GRUB הישנה במערכת שלך, מומלץ לשנות את ‎/boot/grub/menu." "lst כך שיבצע הטענה משורשרת של קוד האיתחול של GRUB 2 מהגדרות GRUB הישנות שלך. " "ניתן לבצע פעולה זו באופן אוטומטי עכשיו." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "מומלץ שתסכים להטענה משורשרת של GRUB 2 מ-menu.lst ותוודא שהגדרות GRUB 2 " "החדשות עובדות עבורך, לפני שקוד האתחול נכתב ל-MBR (Master Boot Record)‎ שלך." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "לא משנה מהי החלטתך, ביכולתך להחליף יותר מאוחר את קוד האתחול הישן ב-MBR בקוד " "האתחול של GRUB 2 ע\"י מתן הפקודה הבאה כמשתמש-על:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "התקנים להתקנת GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "חבילת grub-pc משתדרגת כעת. תפריט זה מאפשר לך לבחור בהתקנים שברצונך ש-grub-" "install ירוץ עליהם אוטומטית, באם יש כאלה." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "בדרך כלל מומלץ להריץ אוטומטית את grub-install כדי למנוע מליבת קוד האתחול " "המותקנת של GRUB מלהפסיק להיות מתואמת עם מודולי GRUB או עם grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "אם אינך בטוח איזה התקן הוגדר כהתקן האתחול ע\"י ה-BIOS שלך, לעתים קרובות יהא " "זה רעיון טוב להתקין GRUB בכולם." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "הערה: ניתן להתקין GRUB גם ברשומות האתחול של המחיצות, וכמה מחיצות מתאימות " "מוצעות להלן. עם זאת, התקנה כזו מכריחה את GRUB להשתמש בשיטת רשימת הבלוקים, " "שמורידה מאמינותו, ולכן לא מומלץ להתקין בשיטה זו." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "המאתחל של GRUB הותקן מקודם בדיסק שכבר אינו קיים, או שהמזהה הייחודי שלו השתנה " "מסיבה כלשהי. חשוב לוודא שקוד האתחול של ליבת GRUB נשאר מתואם עם מודולי GRUB ו-" "grub.cfg. אנא בדוק שוב כדי לוודא ש-GRUB נכתב להתקני האתחול המתאימים." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "כשלון בכתיבת GRUB להתקן האתחול - להמשיך?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "כשלון בהתקנת GRUB בהתקנים הבאים:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "האם ברצונך להמשיך בכל זאת? אם כן, מחשבך עלול לא לאתחל כהלכה." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "כשלון בכתיבת GRUB להתקן האתחול - לנסות שוב?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "ייתכן שתוכל להתקין GRUB בהתקן אחר, למרות שעליך לוודא שמחשבך יאתחל מההתקן " "ההוא. אחרת, השדרוג מ-GRUB ישן יבוטל." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "להמשיך בלי להתקין GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "בחרת לא להתקין GRUB באף התקן. אם תמשיך, ייתכן שמנהל האתחול לא יהיה מוגדר " "כיאות, ובפעם הבאה שמחשבך יאותחל, הוא יאותחל ממה שהיה קודם ב-boot sector. אם " "יש גירסא מוקדמת יותר של GRUB 2 ב-boot sector, ייתכן שלא יהיה ביכולתה להטעין " "מודולים או להתמודד עם קובץ ההגדרות הנוכחי." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "אם הינך כבר משתמש במנהל אתחול אחר ומעוניין להמשיך להשתמש בו, או אם זו סביבה " "מיוחדת שבה לא דרוש לך מנהל אתחול, עליך להמשיך בכל זאת. אחרת, עליך להתקין " "GRUB במקום כלשהו." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "הסר GRUB 2 מ-/boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "האם ברצונך להסיר את כל קבצי GRUB 2 מ-/boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "פעולה זו תמנע מהמערכת מלאתחל אלא אם תתקין מנהל אתחול אחר." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "לסיים עכשיו המרה ל-GRUB 2?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "יש במערכת זו עדיין קבצים מההתקנה הישנה של מנהל האתחול GRUB, אבל יש גם רשומות " "אתחול GRUB 2 מותקנות בדיסקים הבאים:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "סביר שהתקנת GRUB הישנה כבר אינה בשימוש, ושעליך במקום זאת לשדרג את תמונות " "GRUB 2 בדיסקים אלה ולסיים את ההמרה ל-GRUB 2 על ידי הסרת קבצי GRUB הישנים. אם " "אינך משדרג תמונות GRUB 2 אלה, הן עלולות להיות בלתי תואמות את החבילות החדשות " "ולמנוע מהמערכת שלך מלאתחל כהלכה." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "בדרך כלל עליך לסיים את ההמרה ל-GRUB 2 אלא אם רשומות אתחול אלה נוצרו על ידי " "התקנת GRUB 2 במערכת הפעלה אחרת." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "שורת הפקודה של Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "שורת פקודת Linux הבאה נשלפה מ-‎/etc/default/grub או מפרמטר 'kopt' ב-menu.lst " "הישן של GRUB. נא לוודא ששורת פקודה זו נכונה ועדכן אותה אם צריך. ניתן להשאיר " "שורת פקודה זו ריקה." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "ברירת מחדל לשורת הפקודה של Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "המחרוזת הבאה תשמש כפרמטרי Linux עבור ברירת המחדל בתפריט אבל לא עבור מצב " "recovery." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "שורת הפקודה של kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "שורת פקודת kFreeBSD הבאה נשלפה מ-‎/etc/default/grub או מפרמטר'kopt' ב-menu." "lst הישן של GRUB. בבקשה לוודא ששורת פקודה זו נכונה ועדכן אותה אם צריך. ניתן " "להשאיר שורת פקודה זו ריקה." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "ברירת מחדל לשורת הפקודה של kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "המחרוזת הבאה תשמש כפרמטרי kFreeBSD עבור ברירת המחדל בתפריט אבל לא עבור מצב " "recovery." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "הקובץ ‎/boot/grub/device.map נוצר מחדש" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "הקובץ ‎/boot/grub/device.map נכתב מחדש כדי להשתמש בשמות התקנים יציבים. ברוב " "המקרים, הדבר אמור לצמצם בצורה משמעותית את הצורך לשנותו בעתיד, והבחירות " "בתפריט האתחול הנוצר על ידי GRUB לא אמורות להיות מושפעות משינוי זה." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "אבל, מכיוון שיש במערכת שלך יותר מדיסק אחד, ייתכן שהמערכת מסתמכת על קובץ " "מיפוי ההתקנים הישן. אנא בדוק אם יש לך בחירות מותאמות אישית בתפריט האתחול, " "שמשתמשות בשיטת מספור ההתקנים (hdN) של GRUB, ועדכן אותן אם צריך." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "אם אינך מבין הודעה זו, או אם אין לך ברירות מותאמות אישית בתפריט האתחול, אזי " "ניתן להתעלם מהודעה זו." debian/po/be.po0000664000000000000000000005244312524662415010553 0ustar # Belarusian translation of grub2 templates # Copyright (C) 2009 respective translators (see below) # This file is distributed under the same license as the grub2 package. # Hleb Rubanau , 2009, # Viktar Siarheichyk , 2010, 2012. # msgid "" msgstr "" "Project-Id-Version: be\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-03-05 13:46+0300\n" "Last-Translator: Viktar Siarheichyk \n" "Language-Team: Debian Belarusian (Official spelling) \n" "Language: be\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Belarusian\n" "X-Poedit-Country: BELARUS\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Ланцуговая загрузка з menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Скрыпты абнаўлення GRUB выявілі папярэднюю версію GRUB, усталяваную ў /boot/" "grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Каб замяніць папярэднюю версію GRUB у Вашай сістэме, пажадана выправіць " "файл /boot/grub/menu.lst такім чынам, каб GRUB 2 загружаўся з існуючай " "папярэдняй версіі GRUB. Зараз можна зрабіць гэтую наладку аўтаматычна." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Раім абраць ланцуговую загрузку GRUB 2 з menu.lst, і праверыць, што нанова " "ўсталяваны GRUB 2 працуе, перад тым як усталёўваць яго ў галоўны загрузачны " "запіс (MBR, Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Як бы вы ні вырашылі, можна пазней замяніць стары вобраз MBR на GRUB 2, калі " "выканаць як root наступныя каманды:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Прылады, на якія ўсталёўваць GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "x`Пакет grub-pc абнаўляецца. Гэтае меню дазваляе абраць, для якіх прыладаў " "трэба, калі ўвогуле трэба, аўтаматычна запускаць grub-install." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "У большасці выпадкаў рэкамендуецца запускаць grub-install аўтаматычна, каб " "усталяваны асноўны вобраз GRUB заставаўся ў адпаведнасці з модулямі GRUB і " "grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Калі вы не пэўныя, якая прылада ў вашым BIOS прызначаная як галоўная, то " "хутчэй за ўсё лепей будзе ўсталяваць GRUB на іх усіх." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Увага: таксама магчыма ўсталяваць GRUB у сектары пачатковай загрузкі " "падзелаў, і некаторыя адпаведныя падзелы тут прапануюцца. Аднак, для гэтага " "GRUB мусіць карыстацца механізмам спісаў блокаў, што змяншае надзейнасць і " "таму не рэкамендуецца." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Пачатковы запускальнік GRUB раней быў усталяваны на дыск, які зараз " "адсутнічае, альбо чый унікальны ідэнтыфікатар па нейкай прычыне змяніўся. " "Важна, каб усталяваны асноўны вобраз GRUB адпавядаў модулям GRUB і grub.cfg. " "Калі ласка, праверце яшчэ раз, каб упэўніцца, што GRUB запісаны ў адпаведныя " "загрузкавыя прылады." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} Мб; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Запіс GRUB на загрузкавую прыладу не ўдаўся - працягваць?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Не атрымалася ўсталяваць GRUB на наступныя прылады:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Вы жадаеце працягваць, не зважаючы на гэта? Калі працягнеце, ваш кампутар " "можа не запусціцца." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "Не атрымалася запісаць GRUB у загрузкавую прыладу - паспрабаваць ізноў?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Магчыма, што вы зможаце ўсталяваць GRUB на нейкую іншую прыладу, але вам " "варта спраўдзіць, што вашая сістэма запусціцца з гэтае прылады. Іначай, " "абнаўленне з папярэдняе версіі GRUB будзе адмененае." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Працягваць, не ўсталёўваючы GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Вы выбралі не ўсталёўваць GRUB ні на якую прыладу. Калі Вы працягнеце далей, " "пачатковы запускальнік, магчыма, не будзе сканфігураваны належным чынам, і " "калі гэты кампутар запусціцца наступным разам, ён загрузіцца з таго, што " "было раней у сектары запуску. Калі там была старая версія GRUB 2, ён можа не " "здолець загрузіць модулі альбо не разабраць цяперашні канфігурацыйны файл." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Калі Вы ўжо карыстаецеся іншым пачатковым запускальнікам і хочаце так рабіць " "і надалей альбо калі гэта адмысловае асяроддзе, дзе загрузчык непатрэбны, то " "вам варта ўсё ж працягваць. Іначай вам трэба некуды ўсталяваць GRUB." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Выдаліць GRUB 2 з /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Хочаце выдаліць усе файлы GRUB 2 з /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "З-за гэтага сістэма будзе не ў стане запусціцца, пакуль не будзе ўсталяваны " "іншы пачатковы запускальнік." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Скончыць зараз перавод на GRUB 2?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "На гэтай сістэме ўсё яшчэ ўсталяваныя файлы з папярэдняе версіі загрузчыка " "GRUB, але зараз тут таксама ўсталяваныя загрузчыкі GRUB 2 на наступных " "дысках:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Падаецца, што папярэдняя версія GRUB болей не выкарыстоўваецца, і што вы " "павінны замест гэтага абнавіць вобразы GRUB 2 на гэтых дысках і скончыць " "пераход на GRUB 2, выдаліўшы старыя файлы папярэдняй версіі GRUB. Калі вы не " "абновіце гэтыя вобразы GRUB 2, то яны могуць стаць несумяшчальнымі з новымі " "пакетамі і ваша сістэма перастане нармальна запускацца." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Звычайна, Вы павінны скончыць пераход на GRUB 2, калі толькі гэтыя " "загрузчыкі не былі створаныя ўсталёўкай GRUB 2 на нейкай іншай аперацыйнай " "сістэме." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Радок камандаў для ядра Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Гэты радок камандаў для ядра Linux узяты з файла /etc/default/grub або з " "параметра `kopt' у файле наладак (menu.lst) папярэдняй версіі GRUB (Legacy). " "Калі ласка, пераканайцеся, што каманды запісаныя правільна, або папраўце іх, " "калі трэба. Гэты радок камандаў можа быць пустым." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Прадвызначаны радок камандаў для ядра Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Наступны радок будзе выкарыстаны ў якасці параметраў ядра Linux для " "прадвызначанага пункту меню (але не для рэжыму аднаўлення)." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Радок камандаў для ядра kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Гэты радок камандаў для kFreeBSD узяты з файлу /etc/default/grub або з " "параметру `kopt' у файле наладак (menu.lst) папярэдняй версіі GRUB (Legacy). " "Калі ласка, пераканайцеся, што каманды запісаныя правільна, або папраўце іх, " "калі трэба. Гэты радок камандаў можа быць пустым." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Прадвызначаны радок камандаў для ядра kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Наступны радок будзе выкарыстаны ў якасці параметраў ядра kFreeBSD для " "прадвызначанага пункту меню (але не для рэжыму аднаўлення)." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map быў перагенераваны" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Файл /boot/grub/device.map быў перапісаны, каб выкарыстоўваць стабільныя " "імёны прыладаў. У бальшыні выпадкаў гэта значна знізіць неабходнасць змяняць " "яго ў будучыні, і пункты загрузачнага меню, згенераваныя GRUB, не давядзецца " "закрануць." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Аднак, паколькі ў вашай сістэме больш за адзін дыск, то магчыма, што ў " "сістэме выкарыстоўваецца старая табліца прыладаў. Праверце, ці ёсць пункты " "загрузкавага меню, што ўжываюць нумарацыю прыладаў GRUB (hdN) і абнавіце іх, " "калі патрэбна." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Калі вы не зразумелі гэтае паведамленне, альбо калі вы не маеце ўласных " "пунктаў загрузкавага меню, вы можаце ігнараваць гэтае паведамленне." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Калі ж Вы хочаце, каб GRUB 2 запускаўся непасрэдна з MBR, дастаткова " #~ "запусціць з правамі карыстальніка root наступную каманду:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Не атрымалася ўсталяваць GRUB. Працягваць?" #~ msgid "GRUB 1.95 numbering scheme transition" #~ msgstr "Змена схемы нумарацыі GRUB 1.95" #~ msgid "" #~ "As of version 1.95, GRUB 2 has changed its numbering scheme. Partitions " #~ "are now counted starting from 1 rather than 0. This is to make it " #~ "consistent with device names of Linux and the other kernels used in " #~ "Debian. For example, when using Linux as the kernel, \"(hd0,1)\" refers " #~ "to the same partition as the /dev/sda1 device node." #~ msgstr "" #~ "Схема нумарацыі ў GRUB 2 змянілася ў параўнанні з версіяй 1.95 . Зараз " #~ "падзелы дыску адлічваюцца пачынаючы з 1 замест 0. Гэта зроблена, каб " #~ "адпавядаць назвам прыладаў у Linux і іншых ядрах, якія выкарыстоўваюцца ў " #~ "Debian. Напрыклад, калі ў якасці ядра выкарыстоўваецца Linux, радок " #~ "\"(hd0,1)\" датычыцца таго самага падзелу дыску, як і файл прылады /dev/" #~ "sda1." #~ msgid "" #~ "Because of this, there's a chance your system becomes unbootable if " #~ "update-grub(8) is run before GRUB is updated, generating a grub.cfg file " #~ "that your installed GRUB won't yet be able to parse correctly. To ensure " #~ "your system will be able to boot, you have to:" #~ msgstr "" #~ "З гэтай прычыны Ваша сістэма можа стаць няздольнай да загрузкі, калі " #~ "праграма update-grub(8), запушчаная да абнаўлення GRUB, стварыла файл " #~ "grub.cfg, які немагчыма карэктна апрацаваць усталяваным GRUB. Каб " #~ "пераканацца, што Ваша сістэма здольная да загрузкі, варта: " #~ msgid "" #~ " - Reinstall GRUB (typically, by running grub-install).\n" #~ " - Rerun update-grub to generate a new grub.cfg." #~ msgstr "" #~ " - Пераўсталяваць GRUB (звычайна, праз запуск grub-install).\n" #~ " - Перазапусціць update-grub, каб стварыць новы grub.cfg." debian/po/pt_BR.po0000664000000000000000000003700012524662415011163 0ustar # grub2 Brazilian Portuguese translation # Copyright (C) 2009 THE grub2'S COPYRIGHT HOLDER # This file is distributed under the same license as the grub2 package. # Flamarion Jorge , 2009, 2010, 2011. # msgid "" msgstr "" "Project-Id-Version: grub2 1.98\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-05-29 17:13-0300\n" "Last-Translator: Flamarion Jorge \n" "Language-Team: Brazilian Portuguese \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Carregar em cadeia a partir do menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Os scripts de atualização do GRUB detectaram uma configuração do GRUB Legado " "em /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "A fim de substituir a versão Legada do GRUB no seu sistema, é recomendável " "que o /boot/grub/menu.lst seja ajustado para carregar uma imagem do GRUB 2 a " "partir da sua configuração existente do GRUB Legado. Este passo pode ser " "executado automaticamente agora." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "É recomendado que você aceite o carregamento em cadeia do GRUB 2 a partir do " "menu.lst, e verifique que sua nova configuração do GRUB 2 está funcional, " "antes de gravá-lo na MBR (\"Master Boot Record\")." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Seja qual for sua decisão, você pode substituir a antiga imagem da MBR com o " "GRUB 2 mais tarde executando o seguinte comando como root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Instalar o GRUB nos dispositivos:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "O pacote grub-pc está sendo atualizado. Este menu permite a você selecionar " "em quais dispositivos você quer que seja executado automaticamente o grub-" "install, se houver algum." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Executar o grub-install automaticamente é recomendado na maioria das " "situações para prevenir que a imagem principal instalada do GRUB saia de " "sincronia com os módulos do GRUB ou com o grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Se você não tiver certeza de qual unidade é designada como unidade de " "inicialização pela sua BIOS, muitas vezes é uma boa ideia instalar o GRUB em " "todas elas." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Nota: é possível instalar o GRUB em registros de inicialização de partições, " "e algumas partições apropriadas para isso são oferecidas aqui. No entanto, " "isto força o GRUB a usar o mecanismo de lista de blocos, que o torna menos " "confiável, portanto, não é recomendado." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "O carregador de inicialização GRUB foi instalado anteriormente em um disco " "que não está mais presente, ou seu identificador único foi modificado por " "alguma razão. É importante certificar-se de que a imagem principal do GRUB " "instalada está em sincronia com os módulos do GRUB e com o grub.cfg. Por " "favor, verifique novamente e esteja certo de que o GRUB está gravado nos " "dispositivos de inicialização apropriados." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "A gravação do GRUB no dispositivo de inicialização falhou - continuar?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Falha ao instalar o GRUB nos seguintes dispositivos:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Você deseja continuar de qualquer maneira? Se você continuar, seu computador " "talvez não inicialize corretamente." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "A gravação do GRUB no dispositivo de inicialização falhou - tentar novamente?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Você pode conseguir instalar o GRUB em outro dispositivo, mas você deve " "verificar se o seu sistema vai conseguir inicializar a partir deste " "dispositivo. Caso contrário, a atualização do GRUB Legado será cancelada." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Continuar sem instalar o GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Você escolheu não instalar o GRUB em nenhum dispositivo. Se você continuar, " "o carregador de inicialização poderá não ser configurado corretamente, e na " "próxima vez que este computador inicializar ele usará a versão que estava " "anteriormente no setor de inicialização. Se houver uma versão anterior do " "GRUB 2 no setor de inicialização, pode ser que ele não consiga carregar " "módulos ou manipular corretamente o arquivo de configuração atual." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Se você já estiver usando um carregador de inicialização diferente e quiser " "continuar a fazê-lo, ou se este é um ambiente especial, onde você não " "precisa de um carregador de inicialização, então você deve continuar de " "qualquer maneira. Caso contrário, você deve instalar o GRUB em algum outro " "lugar." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Remover o GRUB 2 do /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Você deseja ter todos os arquivos do GRUB 2 removidos de /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Isto fará com que seu sistema não inicialize a menos que outro carregador de " "inicialização esteja instalado." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Completar a conversão para o GRUB 2 agora?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Este sistema ainda tem arquivos do carregador de inicialização do GRUB " "Legado instalados, mas agora também tem registros de inicialização do GRUB 2 " "instalados nestes discos:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Parece provável que o GRUB Legado não está mais em uso, e que você deve " "atualizar as imagens do GRUB 2 nestes discos e completar a conversão para o " "GRUB 2, removendo arquivos antigos do GRUB Legado. Se você não atualizar " "essas imagens do GRUB 2, então elas podem ser incompatíveis com os novos " "pacotes e fazer com que o sistema deixe de inicializar corretamente." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Você normalmente deveria completar a conversão para o GRUB 2, a menos que " "esses registros de inicialização tenham sido criados por uma instalação do " "GRUB 2 em algum outro sistema operacional." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linha de comando Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "A linha de comando Linux a seguir foi extraída de /etc/default/grub ou do " "parâmetro 'kopt' do menu.lst do GRUB Legado. Por favor, verifique se ela " "está correta, e modifique-a se necessário. A linha de comando pode ser vazia." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linha de comando padrão Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "O seguinte texto será usado como lista de parâmetros do Linux para a entrada " "padrão do menu, mas não para o modo de recuperação." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Linha de comando kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "A linha de comando kFreeBSD a seguir foi extraída de /etc/default/grub ou do " "parâmetro 'kopt' do menu.lst do GRUB Legado. Por favor, verifique se ela " "está correta, e modifique-a se necessário. A linha de comando pode ser vazia." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Linha de comando padrão kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "O seguinte texto será usado como lista de parâmetros do kFreeBSD para a " "entrada padrão do menu, mas não para o modo de recuperação." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map foi gerado novamente" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "O arquivo /boot/grub/device.map foi reescrito para usar nomes estáveis de " "dispositivo. Na maioria dos casos, isto pode reduzir de forma significativa " "a necessidade de mudá-los no futuro, e as entradas do menu de inicialização " "geradas pelo GRUB não devem ser afetadas." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Entretanto, como mais de um disco está presente no sistema, é possível que o " "sistema esteja dependendo do antigo mapa de dispositivos. Por favor, " "verifique se existem quaisquer outras entradas personalizadas no menu de " "inicialização que dependam da numeração de unidade do GRUB (hdN), e atualize-" "as se necessário." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Se você não compreende esta mensagem, ou se não existem entradas " "personalizadas no menu de inicialização, você pode ignorar esta mensagem." debian/po/es.po0000664000000000000000000004511712524662415010574 0ustar # grub2 po-debconf translation to Spanish # Copyright (C) 2007, 2009, 2010, 2011 Software in the Public Interest # This file is distributed under the same license as the grub2 package. # # Changes: # - Initial translation # Maria Germana Oliveira Blazetic, 2007 # # - Updates # Gary Ariel Sandi Vigabriel , 2009 # Francisco Javier Cuadrado , 2009, 2010, 2011 # # - Revisions # Innocent De Marchi , 2010 # # Traductores, si no conocen el formato PO, merece la pena leer la # documentación de gettext, especialmente las secciones dedicadas a este # formato, por ejemplo ejecutando: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # # Equipo de traducción al español, por favor lean antes de traducir # los siguientes documentos: # # - El proyecto de traducción de Debian al español # http://www.debian.org/intl/spanish/ # especialmente las notas y normas de traducción en # http://www.debian.org/intl/spanish/notas # # - La guía de traducción de po's de debconf: # /usr/share/doc/po-debconf/README-trans # o http://www.debian.org/intl/l10n/po-debconf/README-trans # msgid "" msgstr "" "Project-Id-Version: grub2 1.99-5\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-05-28 14:04+0100\n" "Last-Translator: Francisco Javier Cuadrado \n" "Language-Team: Debian l10n Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "¿Desea realizar la carga en cadena desde el archivo «menu.lst»?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Los scripts de actualización han detectado en «/boot/grub» una configuración " "heredada de una versión anterior de GRUB." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Con el fin de reemplazar la versión anterior de GRUB en el sistema, se " "recomienda configurar «/boot/grub/menu.lst» para que cargue GRUB 2 a partir " "de la configuración heredada de GRUB. Este paso se puede hacer de forma " "automática." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Se recomienda que acepte cargarlo en cadena desde el archivo «menu.lst» y " "que compruebe el buen funcionamiento del nuevo GRUB 2, antes de instalarlo " "en el MBR («Master Boot Record»)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Sea cual sea su decisión, puede reemplazar la imagen del MBR anterior con " "GRUB 2 más tarde ejecutando, como administrador («root»), la siguiente orden:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Dispositivos en los que se puede instalar GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Se está actualizando el paquete grub-pc. Este menú le permite escoger en qué " "dispositivos quiere ejecutar automáticamente grub-install, si es que quiere." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Se recomienda ejecutar automáticamente grub-install en la mayoría de las " "situaciones, para evitar que la imagen del núcleo de GRUB instalada no esté " "sincronizada con los módulos GRUB o con el archivo «grub.cfg»." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Si no está seguro cuál es la unidad de arranque de la BIOS, normalmente es " "una buena idea instalar GRUB en todas ellas." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Nota: también es posible instalar GRUB en los registros de arranque de " "particiones, aquí se ofrecen algunas particiones apropiadas. Sin embargo, " "esto obliga a GRUB a utilizar el mecanismo de la lista de bloqueo, que lo " "hace menos fiable, y por tanto no es recomendable." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "El gestor de arranque GRUB se instaló previamente en un disco que ya no está " "presente o cuyo identificador único ha cambiado por alguna razón. Es " "importante asegurarse de que la imagen del núcleo de GRUB instalada se " "mantiene sincronizada con los módulos de GRUB y el archivo «grub.cfg». Por " "favor, asegúrese que GRUB se instala en los dispositivos de arranque " "adecuado." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "" "La instalación de GRUB en el dispositivo de arranque ha fallado. ¿Desea " "continuar?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "No se pudo instalar GRUB en los siguientes dispositivos:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "¿Desea continuar de todos modos? Si lo hace, puede que su máquina no se " "inicie apropiadamente." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "La instalación de GRUB en el dispositivo de arranque ha fallado. ¿Desea " "volver a intentarlo?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Puede instalar GRUB en otro dispositivo, aunque debería comprobar que su " "sistema arrancará desde ese dispositivo. De otro modo, se cancelará la " "actualización de la versión anterior de GRUB." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "¿Desea continuar sin instalar GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Ha escogido no instalar GRUB en ningún dispositivo. Si continua, puede que " "el cargador de arranque no se configure correctamente, y cuando esta máquina " "se vuelva a iniciar se utilizará lo que hubiera anteriormente en el sector " "de arranque. Si hay una versión previa de GRUB 2 en el sector de arranque, " "puede que sea imposible cargar los módulos o manejar el archivo de " "configuración actual." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Si está ejecutando un cargador de arranque diferente y quiere seguir " "haciéndolo o si es un entorno especial en el que no necesita un cargador de " "arranque, entonces debería continuar. De otro modo, debería instalar GRUB en " "otra ubicación." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "¿Desea eliminar GRUB 2 de «/boot/grub»?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "¿Desea eliminar todos los archivos de GRUB 2 de «/boot/grub»?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Esto hará que el sistema no arranque a menos que otro gestor de arranque " "esté instalado." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "¿Desea terminar la conversión a GRUB 2 ahora?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Este sistema todavía tiene archivos del cargador de arranque de la versión " "anterior de GRUB instalados, pero ahora también tiene registros de arranque " "de GRUB 2 instalados en estos discos:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Parece que la versión anterior de GRUB ya no se utiliza, por lo que usted " "debería actualizar las imágenes de GRUB 2 en estos discos y terminar la " "conversión a GRUB 2 borrando los archivos de la versión anterior de GRUB. Si " "no actualiza estas imágenes de GRUB 2, puede que sean incompatibles con los " "nuevos paquetes y que provoquen que su sistema no arranque correctamente." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Debería terminar la conversión a GRUB 2 a menos que estos registros de " "arranque los crease una instalación de GRUB 2 en algún otro sistema " "operativo." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linea de órdenes de Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La siguiente linea de órdenes de Linux se extrajo del archivo «/etc/default/" "grub» o del parámetro «kopt» en el archivo «menu.lst» de la versión anterior " "de GRUB. Por favor, compruebe que es correcta y modifíquela si es necesario. " "La línea de órdenes se puede dejar en blanco." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linea de órdenes predeterminada de Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "La siguiente cadena se utilizará como parámetros de Linux para la entrada " "predeterminada del menú pero no para el modo de recuperación." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Linea de órdenes de kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La siguiente linea de órdenes de kFreeBSD se extrajo del archivo «/etc/" "default/grub» o del parámetro «kopt» en el archivo «menu.lst» de la versión " "anterior de GRUB. Por favor, compruebe que es correcta y modifíquela si es " "necesario. La línea de órdenes se puede dejar en blanco." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Linea de órdenes predeterminada de kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "La siguiente cadena se utilizará como parámetros de kFreeBSD para la entrada " "predeterminada del menú pero no para el modo de recuperación." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "Se ha regenerado el archivo «/boot/grub/device.map»" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "El archivo «/boot/grub/device.map» se ha rescrito para utilizar los nombres " "de dispositivos estables. En la mayoría de los casos, esto debería reducir " "significativamente la necesidad de cambiarlo en el futuro, y las entradas " "del menú que generó GRUB no se verán afectadas." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Sin embargo, ya que hay más de un disco en el sistema, es posible que el " "sistema dependa de un mapa de dispositivos antiguo. Por favor, compruebe si " "tiene entradas personalizadas en el menú de arranque que dependan de la " "numeración de los dispositivos de GRUB (hdN) y actualícela si es necesario." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Puede ignorar este mensaje si no lo entiende o si no tiene entradas " "personalizadas en el menú de arranque." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "En cualquier caso, cuando quiera que GRUB 2 se cargue directamente desde " #~ "el MBR, puede hacerlo ejecutando (como usuario «root») la siguiente orden:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "La instalación de GRUB ha fallado. ¿Desea continuar?" #~ msgid "GRUB 1.95 numbering scheme transition" #~ msgstr "Esquema de transición numérica de GRUB 1.95" #~ msgid "" #~ "As of version 1.95, GRUB 2 has changed its numbering scheme. Partitions " #~ "are now counted starting from 1 rather than 0. This is to make it " #~ "consistent with device names of Linux and the other kernels used in " #~ "Debian. For example, when using Linux as the kernel, \"(hd0,1)\" refers " #~ "to the same partition as the /dev/sda1 device node." #~ msgstr "" #~ "GRUB 2 ha cambiado el esquema de numeración, como en la versión 1.95. " #~ "Ahora las particiones comienzan en el número 1 en vez de en el número 0. " #~ "Esto sirve para hacerlo consistente con los nombres de dispositivos de " #~ "Linux y otros núcleos que se usan en Debian. Por ejemplo, cuando se usa " #~ "Linux como núcleo, «(hd0, 1)» se refiere a la misma partición que el " #~ "dispositivo «/dev/sda1»." #~ msgid "" #~ "Because of this, there's a chance your system becomes unbootable if " #~ "update-grub(8) is run before GRUB is updated, generating a grub.cfg file " #~ "that your installed GRUB won't yet be able to parse correctly. To ensure " #~ "your system will be able to boot, you have to:" #~ msgstr "" #~ "Por este motivo, existe la posibilidad de que su sistema no sea capaz de " #~ "arrancar si se ejecuta update-grub(8) antes de actualizar GRUB, ya que se " #~ "generaría un archivo «grub.cfg» que la versión instalada de GRUB no " #~ "podría leer correctamente. Para asegurarse de que el sistema arrancará, " #~ "debe:" #~ msgid "" #~ " - Reinstall GRUB (typically, by running grub-install).\n" #~ " - Rerun update-grub to generate a new grub.cfg." #~ msgstr "" #~ " - Reinstalar GRUB (normalmente, ejecutando grub-install).\n" #~ "- Volver a ejecutar update-grub para generar un nuevo archivo «grub.cfg»." debian/po/lt.po0000664000000000000000000003634212524662415010604 0ustar # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Rimas Kudelis , 2012. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-06-02 18:36+0300\n" "Last-Translator: Rimas Kudelis \n" "Language-Team: Lithuanian \n" "Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n" "%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Virtaal 0.7.1\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Paleisti grandininiu būdu iš „menu.lst“?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "„GRUB“ atnaujinimo scenarijai aptiko senojo „GRUB“ konfigūracinius failus „/" "boot/grub“ aplanke." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Norint pakeisti senąją sistemoje esančią „GRUB“ versiją, rekomenduojama " "pirmiausia papildyti jos konfigūracinį failą „/boot/grub/menu.lst“, " "nurodant, kad ji paleistų „GRUB 2“ grandininiu būdu. Šį žingsnį galima " "automatiškai atlikti dabar." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Prieš įrašant „GRUB 2“ į disko paleidimo įrašą, rekomenduojama išbandyti " "grandininį jos paleidimą iš „menu.lst“ ir įsitikinti, jog „GRUB 2“ sąranka " "veikia tinkamai." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Koks bebūtų Jūsų sprendimas, vėliau MBR turinį galėsite perrašyti „GRUB 2“ " "ar vėlesne versija, „root“ teisėmis paleisdami komandą:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Įrenginiai „GRUB“ diegimui:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Atnaujinamas „grub-pc“ paketas. Šiame meniu galite pasirinkti, ar kuriems " "nors įrenginiams komanda „grub-install“ turėtų būti paleidžiama automatiškai." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Daugumoje atvejų rekomenduojama automatiškai vykdyti „grub-install“, kad " "būtų išvengta neatitikimų tarp pagrindinio „GRUB“ atvaizdžio ir „GRUB“ " "modulių ar „grub.cfg“ failo." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Jeigu tiksliai nežinote, kurį diską kompiuterio BIOS laiko paleidimo disku, " "galite įdiegti „GRUB“ į visus diskus – dažniausiai tai yra nebloga mintis." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Pastaba: „GRUB“ galima įdiegti ir į skaidinių paleidimo įrašus, todėl sąraše " "yra ir keletas skaidinių. Vis dėlto, šiuo atveju „GRUB“ tektų naudoti blokų " "sąrašo (blocklist) mechanizmą, kuris yra mažiau patikimas, todėl paprastai " "nepatartinas." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Anksčiau „GRUB“ paleidyklė buvo įdiegta į diską, kuris dabar nebeprieinamas " "arba kurio identifikatorius dėl kokių nors priežasčių pakeistas. Svarbu " "užtikrinti pagrindinio „GRUB“ atvaizdžio, „GRUB“ modulių ir „grub.cfg“ failo " "suderinamumą. Patikrinkite pasirinkimus dar kartą ir įsitikinkite, jog " "„GRUB“ paleidyklė bus įrašyta į reikiamus paleidimo įrenginius." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "„GRUB“ įrašyti į paleidimo įrenginį nepavyko. Ar tęsti?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Nepavyko „GRUB“ įdiegti į šiuos įrenginius:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Ar tęsti, nepaisant problemos? Jos neišsprendus, kompiuteris gali tinkamai " "nepasileisti." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "„GRUB“ įrašyti į paleidimo įrenginį nepavyko. Bandyti dar kartą?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Galbūt „GRUB“ Jums pavyks įdiegti į kurį nors kitą įrenginį, tačiau " "turėtumėte įsitikinti, jog sistemą iš to įrenginio pavyks paleisti. " "Priešingu atveju šis atnaujinimas iš senosios „GRUB“ versijos bus atšauktas." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Ar tęsti neįdiegus „GRUB“?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Galima „GRUB“ paleidyklės ir nediegti į jokį įrenginį. Tokiu atveju ji nebus " "tinkamai sukonfigūruota ir kitąkart paleidus šį kompiuterį, bus bandoma " "įvykdyti tai, kas paleidimo sektoriuje buvo iki šiol. Jeigu jame įrašyta " "ankstesnė „GRUB 2“ versija, tikėtina, jog jai nepavyks įkelti reikiamų " "modulių ar tinkamai interpretuoti konfigūracinio failo." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Jeigu šiame kompiuteryje jau naudojama kita paleidyklė ir Jūs norite ja " "naudotis toliau, arba jeigu paleidyklės diegti nereikia dėl kitų priežasčių, " "tuomet tiesiog tęskite. Priešingu atveju „GRUB“ reikėtų kur nors įdiegti." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Pašalinti „GRUB 2“ iš „/boot/grub“?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Ar pašalinti visus „GRUB 2“ failus iš „/boot/grub“ aplanko?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Tai atlikus, sistemą paleisti gali tapti neįmanoma, nebent joje įdiegta kita " "paleidyklė." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Užbaigti migraciją į „GRUB 2“ dabar?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Šioje sistemoje vis dar likę įdiegtų senosios „GRUB“ failų, tačiau joje yra " "įdiegti ir „GRUB 2“ paleidimo įrašai šiuose diskuose:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Panašu, kad senoji „GRUB“ nebenaudojama ir kad Jums derėtų atnaujinti „GRUB " "2“ atvaizdžius šiuose diskuose ir užbaigti migraciją į „GRUB 2“, pašalinant " "senosios „GRUB“ failus. Neatnaujinus šių „GRUB 2“ atvaizdžių, naujai įdiegti " "paketai gali būti su jais nesuderinami. Tokiu atveju sistema gali apskritai " "nepasileisti." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Paprastai derėtų užbaigti migraciją į „GRUB 2“, nebent šiuos paleidimo " "įrašus sukūrė „GRUB 2“ versija, įdiegta su kokia nors kita operacine sistema." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "„Linux“ komandos eilutė:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Iš „/etc/default/grub“ failo arba senosios „GRUB“ konfigūraciniame faile " "„menu.lst“ nurodyto „kopt“ parametro išrinkta žemiau pateikta „Linux“ " "komandos eilutė. Patikrinkite, ar ji tinkama ir jei reikia, ją " "patikslinkite. Komandos eilutė gali būti ir tuščia." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Numatytoji „Linux“ komandos eilutė:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Ši eilutė bus naudojama kaip įprastiniai „Linux“ branduolio parametrai, bet " "ne pasirinkus atkūrimo veikseną." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "„kFreeBSD“ komandos eilutė:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Iš „/etc/default/grub“ failo arba senosios „GRUB“ konfigūraciniame faile " "„menu.lst“ nurodyto „kopt“ parametro išrinkta žemiau pateikta „kFreeBSD“ " "komandos eilutė. Patikrinkite, ar ji tinkama ir jei reikia, ją " "patikslinkite. Komandos eilutė gali būti ir tuščia." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Numatytoji „kFreeBSD“ komandos eilutė:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Ši eilutė bus naudojama kaip įprastiniai „kFreeBSD“ branduolio parametrai, " "bet ne pasirinkus atkūrimo veikseną." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "Failas „boot/grub/device.map“ pergeneruotas" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Failas „/boot/grub/device.map“ perrašytas taip, kad naudotų stabilius " "įrenginių vardus. Tai turėtų žymiai sumažinti poreikį šį failą ateityje " "redaguoti, o „GRUB“ sugeneruotų paleidimo įrašų tai neturėtų įtakoti." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Tačiau kadangi šiame kompiuteryje yra daugiau nei vienas diskas, gali būti, " "jog sistema pasikliauna senuoju įrenginių planu. Patikrinkite, ar neturite " "rankiniu būdu sukūrę paleidimo įrašų, naudojančių „(hdN)“ diskų numeravimą " "ir jei reikia, juos patikslinkite." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Jeigu nesuprantate šio pranešimo, arba neturite rankiniu būdu sukurtų " "paleidimo įrašų, šio pranešimo galite nepaisyti." debian/po/ta.po0000664000000000000000000005757412524662415010603 0ustar # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Dr,T,Vasudevan , 2010. # Dr.T.Vasudevan , 2012. msgid "" msgstr "" "Project-Id-Version: ta\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-02-16 10:15+0530\n" "Last-Translator: Dr.T.Vasudevan \n" "Language-Team: Tamil \n" "Language: ta\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.1\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "menu.lst இலிருந்து சங்கிலிஏற்றம் செய்யலாமா?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "/boot/grub இல் பாரம்பரிய க்ரப் அமைப்பு உள்ளதாக க்ரப் மேம்படுத்தல் நிரல் கண்டது." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" " பாரம்பரிய க்ரப் அமைப்பை உங்கள் கணினியிலிருந்து மாற்ற இப்போதுள்ள பாரம்பரிய க்ரப் அமைப்பின் /" "boot/grub/menu.lst ஐ க்ரப்2 துவக்கி பிம்பத்தில் இருந்து ஏற்றம் செய்ய சரிக்கட்ட " "பரிந்துரைக்கப்படுகிறது. இந்த படி இப்போது தானியங்கியாக செய்யப்பட முடியும்." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" " menu.lst இலிருந்து க்ரப்2 ஐ சங்கிலி ஏற்றம் செய்ய இப்போது ஒப்புக்கொள்ள பரிந்துரை " "செய்யப்படுகிறது. மேலும் உங்கள் புதிய க்ரப்2 அமைப்பு செயல் சரியாக உள்ளதா என்பதையும் சரி " "பார்த்த பின் எம்பிஆர் (மாஸ்டர் பூட் ரெகார்ட்) இல் நிறுவிக்கொள்ளலாம்." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "நீங்கள் என்ன முடிவு செய்தாலும் பழைய எம்பிஆர் பிம்பத்தை, பின்னால் பின் வரும் கட்டளையை ரூட் ஆக " "இட்டு க்ரப் 2 ஆல் மாற்றிக்கொள்ளலாம்." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "க்ரப் நிறுவல் சாதனங்கள்: " #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "க்ரப்-பிசி பொதி மேம்படுத்தப்படுகிறது. இந்த மெனு க்ரப் நிறுவல் தானியங்கியாக இயங்க " "சாதனங்கள் ஏதும் இருந்தால் அதை தேர்ந்தெடுக்க இது அனுமதிக்கிறது." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "பெரும்பாலான நேரங்களில் தானியங்கியாக க்ரப் நிறுவியை இயக்குவது பரிந்துரைக்கப்படுகிறது. " "இது க்ரப் கரு பிம்பம் க்ரப் மாட்யூல்கள் அல்லது grub.cfg இலிருந்து ஒத்திசைவு இல்லாமல் போவதை " "தடுக்கிறது." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "நீங்கள் எந்த தொகுதி பூட் தொகுதியாக உங்கள் பயாஸால் அமர்த்தப்பட்டுள்ளது என தெரியவில்லையானால் " "எல்லாவற்றிலும் க்ரப் ஐ நிறுவுவது நல்ல தேர்வாகும்." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "குறிப்பு: க்ரப் ஐ பகிர்வுகளின் பூட் பதிவில் நிறுவவும் இயலும். சில பொருத்தமான பகிர்வுகள் " "இங்கு தரப்படுகின்றன. ஆனால் இது க்ரப்பை தடுப்புப்பட்டியல் பாங்கை பயன்படுத்த " "வலியுறுத்துகிறது. அதனால் இது கொஞ்சம் நம்பகத்தன்மை குறைவானது. ஆகவே இதை " "பரிந்துரைப்பதில்லை." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "க்ரப் பூட் ஏற்றி முன்பு ஒரு வட்டில் பதியப்பட்டது; அந்த வட்டு இப்போது இல்லை அல்லது ஏனோ அதன் " "பிரத்யேக அடையாளம்காணி மாறிவிட்டது. க்ரப் கரு பிம்பம் க்ரப் மாட்யூல்கள் அல்லது grub.cfg " "உடன் ஒத்திசைவு இருப்பது அவசியம். பொருத்தமான பூட் சாதனங்களில் க்ரப் எழுதப்பட்டுள்ளது என " "மீண்டும் சோதித்து உறுதி செய்து கொள்க." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} எம்பி (MB); ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} எம்பி(MB); ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "பூட் சாதனத்துக்கு க்ரப் ஐ எழுதுவது தோவியடைந்தது - தொடரலாமா?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "பின் வரும் சாதனங்களில் க்ரப் நிறுவுதல் தோல்வியடைந்தது:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "எப்படியும் தொடர வேண்டுமா? தொடர்ந்தால் உங்கள் கணினி சரியாக துவங்க முடியாமல் போகலாம்." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "பூட் சாதனத்துக்கு க்ரப் ஐ நிறுவுதல் தோல்வியடைந்தது. மீண்டும் முயற்சிக்கலாமா?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "நீங்கள் வேறு சாதனத்தில் க்ரப் ஐ நிறுவ முடியலாம். ஆனால் உங்கள் கணினி அந்த சாதனத்தில் " "இருந்து பூட் ஆகும் என்பதை உறுதி செய்து கொள்ள வேண்டும். இல்லையெனில் பாரம்பரிய க்ரப் " "இலிருந்து மேம்படுத்துதல் ரத்து செய்யப்படும். " #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "க்ரப் ஐ நிறுவாமல் தொடரலாமா?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "நீங்கள் எந்த சாதனத்திலும் க்ரப் ஐ நிறுவாமல் இருக்க தேர்ந்தெடுத்து உள்ளீர்கள். நீங்கள் தொடர்ந்தால் " "பூட் ஏற்றி சரியாக வடிவமைக்கப்படாமல் போகலாம். அதனால் கணினி மீண்டும் துவங்கும்போது முன்பு " "பூட் தொகுதியில் என்ன இருந்ததோ அதையே பயன்படுத்தும். அங்கே க்ரப் 2 இன் முந்தைய பதிப்பு " "இருப்பின் மாட்யூல்களை ஏற்றுதலும் நடப்பு வடிவமைப்பு கோப்பை கையாளுவதும் இயலாமல் போகலாம்." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "நீங்கள் ஏற்கெனெவே வேறு துவக்க ஏற்றியை பயன்படுத்திக்கொண்டு இருந்து அதையே தொடர நினைத்தால், " "அல்லது இது ஒரு விசேஷ சூழலாக இருந்து உங்களுக்கு துவக்கி தேவையில்ல்லாமல் இருந்தால், " "எப்படியும் நீங்கள் தொடர வேண்டும். அல்லது க்ரப் ஐ வேறு இடத்தில் நிறுவ வேண்டும்." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "க்ரப் 2 ஐ /boot/grub இலிருந்து நீக்கவா?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "எல்லா க்ரப் 2 கோப்புக்களையும் /boot/grub இலிருந்து நீக்க விருப்பமா?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "இது வேறு ஒரு துவக்கியை நிறுவி இருந்தால் ஒழிய கணினியை துவக்க முடியாமல் ஆக்கும்." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "க்ரப் 2 க்கு மாற்றத்தை இப்போது முடிக்கலாமா?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "இந்த கணினியில் இன்னும் க்ரப் பாரம்பரிய துவக்கி நிறுவப்பட்டுள்ளது. ஆனால் இப்போது க்ரப் 2 பூட் " "பதிவுகளும் பின் வரும் வட்டுகளில் நிறுவப்பட்டுள்ளது:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "பாரம்பரிய க்ரப் இப்போது புழக்கத்தில் இல்லை என்று தெரிகிறது. நீங்கள் இந்த வட்டுகளில் உள்ள க்ரப் " "2 பிம்பங்களை மேம்படுத்த வேண்டும். பழைய பார்மபரிய க்ரப் கோப்புக்களை நீக்கி மாற்றத்தை இறுதி " "செய்ய வேண்டும். நீங்கள் இந்த பிம்பங்களை மேம்படுத்தாவிட்டால் புதிய பொதிகளுடன் அவை " "பொருத்தமில்லாமல் போய் உங்கள் கணினி சரியாக துவங்க முடியாமல் போகலாம்." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "இந்த பூட் பதிவுகள் வேறு ஒரு இயங்கு தளத்தை நிறுவும் போது க்ரப் 2 ஆல் " "உருவாக்கப்பட்டிருந்தால் ஒழிய நீங்கள் பொதுவாக க்ரப் 2 மாற்றத்தை முடிக்க வேண்டும்." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "லீனக்ஸ் கட்டளை வரி:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "பின் வரும் லீனக்ஸ் கட்டளை வரி /etc/default/grub இலிருந்து அல்லது க்ரப் இன் பாரம்பரிய " "menu.lst இன் `kopt' அளபுருவிலிருந்து பெறப்பட்டது. இது சரியா என்று சோதித்து " "தேவையானால் மற்றவும். இந்த கட்டளை வரி காலியாக இருக்க அனுமதி உண்டு." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "லீனக்ஸ் முன்னிருப்பு கட்டளை வரி:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "பின் வரும் சரங்கள் முன்னிருப்பு மெனு உள்ளீட்டுக்கு லீனக்ஸ் அளபுருக்களாக பயன்படுத்தப்படும்; " "ஆனால் மீட்டெடுப்பு பாங்குக்கு அல்ல" #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "கேப்ரீபிஎஸ்டி கட்டளை வரி:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "பின் வரும் கேப்ரீபிஎஸ்டி கட்டளை வரி /etc/default/grub இலிருந்து அல்லது க்ரப் இன் " "பாரம்பரிய menu.lst இன் `kopt' அளபுருவிலிருந்து பெறப்பட்டது. இது சரியா என்று " "சோதித்து தேவையானால் மற்றவும். இந்த கட்டளை வரி காலியாக இருக்க அனுமதி உண்டு." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "கேப்ரீபிஎஸ்டி முன்னிருப்பு கட்டளை வரி:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "பின் வரும் சரங்கள் முன்னிருப்பு மெனு உள்ளீட்டுக்கு கேப்ரீபிஎஸ்டி அளபுருக்களாக " "பயன்படுத்தப்படும்; ஆனால் மீட்டெடுப்பு பாங்குக்கு அல்ல" #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map மறு உருவாக்கப்பட்டது" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" " /boot/grub/device.map கோப்பு நிலையான சாதனங்களின் பெயரை பயன்படுத்துமாறு மீண்டும் " "உருவாக்கப்பட்டது. பெரும்பாலான சமயங்களில் இது எதிர்காலத்தில் மாற்ற வேன்டிய அவசியம் " "ஏற்படாது. க்ரப் ஆல் உருவாக்கப்படும் பூட் மெனு உள்ளீடுகள் பாதிக்கப்படாது." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "இருப்பினும் கணினியில் ஒன்றுக்கு மேற்பட்ட வட்டுகள் இருப்பதால் கணினி பழைய சாதன வரைபடத்தை " "சார்ந்து பயன்படுத்திக்கொண்டு இருக்க வாய்ப்பு உண்டு. க்ரப் இன் (hdN) எண்ணிடலை சார்ந்த " "தனிப்பயன் பூட் மெனு ஏதும் உள்ளதா என தயை செய்து சோதிக்கவும்; அப்படி இருப்பின் அவற்றை " "மேம்படுத்தவும்." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "இந்த செய்தி உங்களுக்குப் புரியவில்லையானால், அல்லது தனிப்பயன் பூட் மெனு உள்ளீடுகள் " "இல்லையானால் இந்த செய்தியை உதாசீனம் செய்யலாம்." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "எப்படி இருந்தாலும்நீங்கள் க்ரப்2 ஐ எம்பிஆர் இலிருந்து நேரடியாக ஏற்ற விரும்பினால் எப்போது " #~ "வேண்டுமானாலும் ரூட் ஆக கீழ் கண்ட கட்டளை மூலம் அதை செய்யலாம்." debian/po/fa.po0000664000000000000000000004373712524662415010561 0ustar msgid "" msgstr "" "Project-Id-Version: fa\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: \n" "Last-Translator: Behrad Eslamifar \n" "Language-Team: debian-l10n-persian \n" "Language: fa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Persian\n" "X-Poedit-Country: IRAN, ISLAMIC REPUBLIC OF\n" "X-Poedit-SourceCharset: utf-8\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "بارگزاری به صورت Chainload از menu.lst؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "اسکریپت ارتقاء GRUB, نسخه قدیمی GRUB‌ نصب شده در /boot/grub را پیدا کرده است." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "برای جایگزینی نسخه قدیمی GRUB در سیستم شما، پیشنهاد می‌شود /boot/grub/menu." "lst تنظیم گردد تا یک تصویر بوت‌ GRUB 2 از چینش قدیمی GRUB کنونی بارگذاری " "شود . اکنون این مرحله به صورت خودکار انجام می شود." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "توصیه می‌شود که chainloading گراب۲ از menu.lst را بپذیرید، و بازبینی کنید که " "چینش جدید GRUB 2 قبل از اینکه بر روی MBR (Master Boot Record) نوشته شود کار " "می‌کند." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "تصمیم شما هر چه باشد، می‌توانید بعداً تصویر قدیم MBR را با GRUB 2 با فرمان زیر " "توسط کاربر ریشه جایگزین کنید:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "دستگاه‌های نصب گراب:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "بستهٔ grub-pc در حال ارتقاء است. این منو به شما اجازه می‌دهد که هر یک از " "دستگاه‌ها را، در صورت وجود، که مایلید grub-install به صورت خودکار برایش اجرا " "گردد را انتخاب کنید." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "اجرای خودکار grub-install در بیشتر مواقع، برای جلوگیری خارج‌شدن هستهٔ تصویر " "گراب از sync با ماژولهای گراب یا grub.cfg توصیه‌شده است." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "اگر مطمئن نیستید کدام درایو به عنوان درایو بوت توسط BIOS تعیین شده است، اغلب " "ایدهٔ خوبی است که گراب را بر روی همهٔ آنها نصب کنید." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "توجه: امکان دارد که گراب را در رکوردهای بوت پارتیشن نیز نصب کنید، و برخی از " "پارتیشن‌های مناسب نیز اینجا پیشنهاد شده است. اگرچه، این گراب را مجبور می‌کند " "که از مکانیزم blocklist استفاده کند که قابل اطمینان بودن آنرا کاهش می‌دهد و " "بنابراین توصیه نمی‌گردد." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "بارگذار بوت گراب قبلاً در دیسکی نصب شده است که دیگر در دسترس نیست، یا unique " "identifier آن بنا به دلیلی تغییر کرده است. مهم است که اطمینان حاصل کنید که " "نصویر هستهٔ گراب نصب شده در sync با ماژول‌های گراب و grub.cfg باقی بماند. لطفاً " "دوباره بررسی کنید تا مطمئن گردید که گراب در دستگاه‌های بوت مناسب نوشته شده " "است." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "نصب GRUB روی ابزار بوت با شکست مواجه شد - ادامه می‌دهید؟" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB نتوانست که تجهیزات مورد نظر را نصب کند." #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "آیا شما می‌خواهید در هر حال ادامه دهید ؟ اگر ادامه دهید، ممکن است که کامپیوتر " "شما به طور مناسب باید بالا نیاید." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "نصب GRUB روی دستگاه بوت با شکست مواجه شد - دوباره امتحان می‌کنید؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "شما ممکن است قادر باشید که GRUB را بر روی بعضی از ابزارهای دیگر نیز نصب " "کنید ، هرچند که شما باید چک کنید که سیستم شما قادر به راه‌اندازی شدن با آن " "ابزار هست یا خیر. وگرنه ، ارتقا گراب قدیمی متوقف خواهد شد." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "آیا بدون نصب کردن GRUB ، ادامه می دهید ؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "شما نصب GRUB را برای هیچ ابزاری انتخاب نکرده‌اید. اگر ادامه دهید، ممکن است که " "راه‌انداز به درستی تنظیم نشده باشد، و هنگام بالا آمدن بعدی این کامپیوتر، از " "آن چه که قبلاً بر روی بوت سکتور بوده است استفاده می‌کند. اگر نسخهٔ قدیمی‌تری از " "گراب۲ بر روی بوت سکتور وجود دارد، ممکن است که قادر نباشد ماژول‌ها را بارگذاری " "کند و یا پیکربندی کنونی فایل را به کار بندد." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "اگر شما از راه‌انداز بوت دیگری استفاده می‌کنید و می‌خواهید که با همان ادامه " "دهید، یا اگر اینجا یک محیط خاص است که شما به راه‌انداز بوت نیاز ندارید، پس " "می‌بایست به هر ترتیب ادامه دهید. در غیر این‌صورت، باید GRUB را در جایی نصب " "کنید." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "GRUB 2 از /boot/grub برداشته شود؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "آیا می‌خواهید همهٔ فایل‌های GRUB 2 از /boot/grub برداشته شود؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "این باعث غیر قابل بوت‌شدن سیستم می‌شود مگر آنکه بارگذار بوت دیگری نصب است." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "ارتباط با GRUB۲ اکنون پایان یابد؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "این سیستم هنوز فایل هایی مربوط به GRUB قدیمی را به صورت نصب شده دارد ، اما " "اکنون بوت رکورد های GRUB2 بر روی این دیسک ها نصب شده است :" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "به نظر می‌آید که احتمالاً GRUB قدیمی دیگر در استفاده نیست، و شما می‌بایست " "تصاویر GRUB2 را بر روی این دیسک‌ها ارتقاء دهید و با پاک کردن فایل‌های گراب " "قدیمی تبدیل به GRUB2 را به اتمام برسانید. اگر شما این تصاویر GRUB2 را ارتقا " "ندهید، ممکن است این تصاویر با بسته‌های جدید ناسازگار باشند و باعث جلوگیری از " "راه‌اندازی مناسب سیستم شوند." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "شما باید معمولاً به ارتباط GRUB2 پایان دهید، مگر آنکه این رکورد های بوت ساخته " "شده توسط GRUB2 مربوط به سیستم عامل های دیگر باشد." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "خط فرمان لینوکس:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "خط فرمان لینوکس ذیل از /etc/default/grub یا پارامتر های `kopt' در فایل menu." "lst از گراب قدیمی استخراج شده است. لطفاً صحت آن را بررسی کنید، و در صورت لزوم " "آن را تغییردهید. این خط فرمان می‌تواند خالی باشد." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "خط فرمان پیش فرض لینوکس:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "این رشته به عنوان یکی از پارامتر های لینوکس برای منوی پیش فرض استفاده خواهد " "شد و نه برای حالت بازیابی." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "خط فرمان kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "خط فرمان kFreeBSD ذیل از /etc/default/grub یا پارامتر های `kopt' در فایل " "menu.lst از گراب قدیمی استخراج شده است. لطفاً صحت آن را بررسی کنید، و در صورت " "لزوم آن را تغییردهید. این خط فرمان می‌تواند خالی باشد." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "خط فرمان پیش فرض kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "این رشته به عنوان یکی از پارامتر های kFreeBSD برای منوی پیش فرض استفاده " "خواهد شد و نه برای حالت بازیابی." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map بازسازی شده است." #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "فایل /boot/grub/device.map به منظور استفاده از نام تجهیزات دائمی و پایدار، " "بازنویسی شده است. در بیشتر موارد، این می‌بایست به شدت نیاز به تغییر درآینده " "را کاهش دهد، و مدخل‌های منوی بوت ایجاد شده توسط GRUB نبایست تحت تأثیر قرار " "گرفته باشد." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "اگرچه، از آنجا که بیش از یک دیسک در سیستم موجود است، ممکن است سیستم به " "device map قدیمی وابسته باشد. لطفاً بررسی کنید اگر مدخل‌های سفارشی بوت که روی " "نام‌گذاری درایو (hdN) گراب تکیه دارند وجود داشته باشند، و در صورت نیاز آنها " "را به روز نمائید." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "اگر این پیام را متوجه نمی‌شوید، یا اگر هیچ مدخل سفارشی منوی بوت وجود ندارد، " "می‌توانید این پیام را نادیده بگیرید." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "در هر صورت, هر زمان که شما بخواهید مستقیماً GRUB 2 را از MBR بارگزاری " #~ "کنید, می توانید این کار را با اجرای دستوری که در ادامه آمده, تحت کاربر " #~ "ریشه, انجام دهید:" debian/po/sk.po0000664000000000000000000003637212524662415010605 0ustar # Slovak translations for grub2 package. # Copyright (C) 2010 THE grub2'S COPYRIGHT HOLDER # This file is distributed under the same license as the grub2 package. # Slavko , 2010, 2011. # msgid "" msgstr "" "Project-Id-Version: grub2 1.99-5\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-07-19 07:49+0200\n" "Last-Translator: Slavko \n" "Language-Team: Slovak \n" "Language: sk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Zreťaziť z menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Aktualizačné skripty GRUB zistili nastavenie starej verzie GRUB (Legacy) v /" "boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Na nahradenie starej verzie GRUB (Legacy) vo vašom systéme, je odporúčané " "aby bol /boot/grub/menu.lst prispôsobený na zreťazenie (chainload) " "zavádzacieho obrazu GRUB 2 z vášho existujúceho nastavenia GRUB (Legacy). " "Tento krok môže byť automaticky vykonaný teraz." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Je odporúčané aby ste schválili zreťazenie GRUB 2 z menu.lst a overili, že " "nastavenie vášho nového GRUB 2 je funkčné ešte predtým, ako bude zapísaný do " "vášho MBR (Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Nech sa rozhodnete akokoľvek, neskôr môžete nahradiť obraz MBR s GRUB 2 " "spustením nasledujúceho príkazu s právami root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Zariadenia na inštaláciu GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Balík grub-pc je aktualizovaný. Toto menu vám umožňuje vybrať si, pre ktoré " "zariadenia bude automaticky spustený grub-install, ak nejaké vyberiete." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Vo väčšine prípadov je odporúčané spustiť automaticky grub-install, aby ste " "predišli tomu, že máte nainštalované rôzne verzie základného obrazu GRUB a " "modulov GRUB, či grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Ak si nie ste istý, ktoré zariadenie je nastavené na zavádzanie vo vašom " "BIOSe, často je dobrý nápad nainštalovať GRUB na všetky." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Poznámka: je možné nainštalovať GRUB aj do zavádzacieho sektora partície a v " "zozname sú aj niektoré príslušné partície. Avšak, tento spôsob vynúti aby " "GRUB požil mechanizmus blocklist, ktorý ho robí menej spoľahlivým a preto " "nie je odporúčaný." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Zavádzač GRUB bol predtým nainštalovaný na disk, ktorý sa už v systéme " "nenachádza alebo ktorého unikátny identifikátor bol z nejakého dôvodu " "zmenený. Je dôležité zaistiť, aby nainštalovaný základný obraz GRUB mal " "rovnakú verziu ako moduly GRUB a grub.cfg. Prosím pre istotu znova " "skontrolujte, že je GRUB zapisovaný do správnych zavádzacích zariadení." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Zápis GRUBu do zavádzacieho zariadenia zlyhal – pokračovať?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Inštalácia GRUB zlyhala na týchto zariadeniach:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Chcete napriek tomu pokračovať? Ak áno, môže sa stať, že váš počítač " "nenaštartuje správne." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Zápis GRUB do zavádzacieho zariadenia zlyhal – skúsiť znova?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Možno sa vám podarí nainštalovať GRUB aj na niektoré iné zariadenie, ale " "musíte skontrolovať, že váš systém dokáže z neho zavádzať. Inak bude " "aktualizácia zo starého GRUB (Legacy) zrušená." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Pokračovať bez inštalácie GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Zvolili ste si neinštalovať GRUB na žiadne zariadenie, ak budete pokračovať, " "zavádzač nemusí byť správne nastavený a pri ďalšom štarte tohoto počítača " "bude použité to, čo bolo v zavádzacom sektore predtým. Ak je v zavádzacom " "sektore predchádzajúca verzia GRUB 2, nemusí sa jej podariť načítať moduly " "alebo spracovať aktuálny konfiguračný súbor." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Ak už používate iný zavádzač a chcete ho zachovať, alebo ak používate " "špeciálne prostredie, v ktorom zavádzač nepotrebujete, potom môžete " "pokračovať. V opačnom prípade by ste mali niekde GRUB nainštalovať." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Odstrániť GRUB 2 z /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Chcete odstrániť všetky súbory GRUB 2 z /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Týmto nebude možné váš systém naštartovať, kým nebude nainštalovaný iný " "zavádzač." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Dokončiť konverziu na GRUB 2 teraz?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Tento systém má stále nainštalované súbory zo starého zavádzača GRUB " "(Legacy), ale má nainštalované aj nové zavádzacie záznamy GRUB 2 na týchto " "diskoch:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Vyzerá to, že starý GRUB (Legacy) už nie je používaný, a tak môžete na " "týchto diskoch aktualizovať obrazy GRUB 2 a dokončiť konverziu na GRUB 2 " "odstránením súborov starého GRUB (Legacy). Ak nezaktualizuje tieto obrazy " "GRUB 2, potom nemusia byť kompatibilné s novými balíkmi a môžu narušiť " "správne zavádzanie systému." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Mali by ste dokončiť konverziu na GRUB 2, ibaže boli tieto zavádzacie " "záznamy vytvorené inštaláciou GRUB 2 iného operačného systému." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linuxový príkazový riadok:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Nasledujúci príkazový riadok Linuxu bol získaný z /etc/default/grub alebo z " "parametra 'kopt' z menu.lst starého GRUB (Legacy). Skontrolujte prosím jeho " "správnosť a prípadne ho upravte. Príkazový riadok môže byť aj prázdny." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Predvolený Linuxový príkazový riadok:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Nasledujúci reťazec bude použitý ako Linuxové parametre predvolenej položky " "menu, ale nie pre záchranný režim." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Príkazový riadok kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Nasledujúci príkazový riadok kFreeBSD bol získaný z /etc/default/grub alebo " "z parametra 'kopt' z menu.lst starého GRUB (Legacy). Skontrolujte prosím " "jeho správnosť a prípadne ho upravte. Príkazový riadok môže byť aj prázdny." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Predvolený príkazový riadok kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Nasledujúci reťazec bude použitý ako kFreeBSD parametre predvolenej položky " "menu, ale nie pre záchranný režim." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map bol aktualizovaný" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Súbor /boot/grub/device.map bol upravený tak, aby používal stabilné mená " "zariadení. Väčšinou to významne zníži potrebu zmien v budúcnosti a položky " "zavádzacieho menu, generované GRUBom, by tým nemali byť ovplyvnené." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Avšak, keďže máte vo svojom systéme viac ako jeden disk, je možné, že systém " "závisí na starej mape zariadení. Skontrolujte prosím, že nepoužívate žiadne " "položky menu, ktoré závisia na číslovaní zariadení GRUBu (hdN) a prípadne " "ich aktualizuje." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Ak nerozumiete tejto správe, alebo ak nemáte žiadne vlastné položky " "zavádzacieho menu, môžete túto správu ignorovať." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Keď sa rozhodnete zavádzať GRUB 2 priamo z MBR, môžete to urobiť pomocou " #~ "nasledujúceho príkazu (ako root):" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Inštalácia GRUB zlyhala. Pokračovať?" debian/po/ru.po0000664000000000000000000004562712524662415010621 0ustar # translation of ru.po to Russian # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the grub2 package. # # Yuri Kozlov , 2007, 2008. # Yuri Kozlov , 2009, 2010, 2011. msgid "" msgstr "" "Project-Id-Version: grub2 1.99-5\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-05-28 11:37+0400\n" "Last-Translator: Yuri Kozlov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Включить загрузку по цепочке (chainload) в menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Сценарии обновления обнаружили установку GRUB предыдущего поколения в /boot/" "grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Чтобы заменить в системе версию GRUB предыдущего поколения, рекомендуется " "исправить /boot/grub/menu.lst так, чтобы образ GRUB 2 загружался из " "используемой установки GRUB предыдущего поколения. Это может быть сделано " "автоматически прямо сейчас." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Рекомендуется ответить утвердительно для загрузки GRUB 2 из menu.lst по " "цепочке и проверить, что новая настройка GRUB 2 работает так как нужно, " "перед тем как устанавливать её непосредственно в MBR (главную загрузочную " "запись)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "В любом случае, вы можете заменить старый образ MBR на GRUB 2 позднее с " "помощью следующей команды, выполненной с правами суперпользователя:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Устройства, на которые устанавливается GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Выполняется обновление пакета grub-pc. Это меню позволяет вам выбрать " "устройства, для которых нужно автоматически запустить grub-install." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "В большинстве случаев рекомендуется выполнять автоматический запуск grub-" "install, так как это синхронизирует основной образ GRUB с модулями GRUB и " "grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Если вы не знаете какое устройство указано в BIOS для загрузки, часто лучше " "всего установить GRUB на все устройства." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Замечание: также возможно установить GRUB в загрузочную запись раздела, и " "здесь предлагаются соответствующие разделы. Однако, это включает в GRUB " "использование механизма блок-листа, при котором уменьшается надёжность, и " "поэтому это не рекомендуется." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Системный загрузчик GRUB был установлен на диск, которого больше нет в " "системе, или по какой-то причине был изменён уникальный идентификатор. Важно " "убедиться, что установленный основной образ GRUB синхронизирован с модулями " "GRUB и grub.cfg. Проверьте ещё раз, что GRUB записан на правильные " "загрузочные устройства." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} МБ; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} МБ; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Не удалось записать GRUB на загрузочное устройство -- продолжить?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Не удалось установить GRUB на следующие устройства:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Продолжить, не смотря на это? Возможно, не удастся загрузить компьютер." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "Не удалось записать GRUB на загрузочное устройство -- попробовать ещё раз?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Вы можете установить GRUB на другое устройство, но проверьте, что компьютер " "будет загружаться с этого устройства. Иначе, обновление со старой версии " "GRUB Legacy будет отменено." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Продолжить без установки GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Вы отказались от установки GRUB. Если продолжите, то системный загрузчик " "может быть неправильно настроен, и когда компьютер будет включён в следующий " "раз, будет использоваться то, что было раньше в загрузочном секторе. Если " "там была предыдущая версия GRUB 2, то она не сможет загрузить модули или " "обработать текущий файл настройки." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Если у вас уже работает другой системный загрузчик и вы хотите оставить " "выполнение как есть, или если есть специальное окружение, где не нужен " "системный загрузчик, то продолжайте установку. Иначе, вам нужно установить " "GRUB как-то иначе." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Удалить GRUB 2 из /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Удалить все файлы GRUB 2 из /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Если не установлен другой системный загрузчик это сделает систему " "незагружаемой." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Завершить переход к GRUB 2?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "В системе остались файлы от старого системного загрузчика GRUB Legacy, но " "теперь на те же диски установлена загрузочная запись GRUB 2:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Вероятно, GRUB Legacy больше не используется и вам нужно обновить образы " "GRUB 2 на этих дисках и завершить переход к GRUB 2, удалив старые файлы GRUB " "Legacy. Если вы не обновите данные образы GRUB 2, то они могут оказаться " "несовместимыми с новыми пакетами и система больше не загрузится." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Обычно, вам нужно завершить переход к GRUB 2, если нет загрузочных записей, " "созданных установкой GRUB 2 в какой-то другой операционной системе." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Командная строка Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Представленная ниже строка команд Linux была извлечена из /etc/default/grub " "или параметра «kopt» файла menu.lst старой версии GRUB. Проверьте, что всё " "правильно, или измените её, если требуется. Также командная строка может " "быть пустой." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Командная строка Linux по умолчанию:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Данная строка будет использоваться в качестве параметров Linux в пункте меню " "по умолчанию, кроме режима восстановления." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Командная строка kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Представленная ниже строка команд kFreeBSD была извлечена из /etc/default/" "grub или параметра «kopt» файла menu.lst старой версии GRUB. Проверьте, что " "всё правильно, или измените её, если требуется. Также командная строка может " "быть пустой." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Командная строка kFreeBSD по умолчанию:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Данная строка будет использоваться в качестве параметров kFreeBSD в пункте " "меню по умолчанию, кроме режима восстановления." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "Пересоздан файл /boot/grub/device.map" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Файл /boot/grub/device.map перезаписан, согласно имеющимся стабильным именам " "устройств. В большинстве случаев, это должно значительно сократить " "необходимость изменения его в будущем, и пункты загрузочного меню, " "созданного GRUB, не должны быть затронуты." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Однако, так как у вас в системе более одного диска, возможно, что была " "зависимость от старого именования устройств. Проверьте, что во всех " "настроенных вручную пунктах загрузочного меню используется нумерация " "устройств GRUB (hd№), и измените их, если нужно." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Если вы не понимаете о чём речь, или у вас нет настроенных вручную пунктов " "загрузочного меню, то игнорируйте это сообщение." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "В любом случае, если вы хотите, чтобы GRUB 2 загружался непосредственно " #~ "из MBR, выполните следующую команду (имея права суперпользователя):" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Установка GRUB завершилась неудачно. Продолжить?" debian/po/ug.po0000664000000000000000000004473412524662415010604 0ustar # Uyghur translation for grub_debian. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Sahran , 2010. # msgid "" msgstr "" "Project-Id-Version: grub_debian\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-01-20 11:29+0600\n" "Last-Translator: Sahran \n" "Language-Team: Uyghur Computer Science Association \n" "Language: Uyghur\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "menu.lst دىن Chainload قىلامدۇ؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "GRUB نەشرىنى يۇقىرىلىتىش قوليازمىسى /boot/grub غا ئورنىتىلغان GRUB Legacy نى " "بايقىدى." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "سىستېمىڭىزدىكى GRUB Legacy نى ئالماشتۇرۇش ئۈچۈن /boot/grub/menu.lst نى " "نۆۋەتتىكى مەۋجۇت GRUB Legacy تەڭشىكىدە GRUB 2 قوزغىتىش يېتەكلىگۈچ تەسۋىرىنى " "يۈكلەڭ. ھازىر بۇ مەشغۇلاتنى ئۆزلۈكىدىن ئىجرا قىلالايدۇ." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "سىزنىڭ menu.lst دىكى chainloading GRUB 2 نى قوبۇل قىلىشىڭىزنى تەۋسىيە " "قىلىمىز ھەمدە GRUB 2 بىۋاسىتە MBR (ئاساسىي يېتەكلەش خاتىرىسى)غا ئورنىتىشتىن " "ئىلگىرى يېڭى GRUB 2 تەڭشىكىنىڭ نورمال خىزمەت قىلىدىغانلىقىنى جەزملەڭ." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "قانداق ھۆكۈم چىقىرىشىڭىزدىن قەتئىينەزەر، سىز كېيىن root سالاھىيىتىدە " "تۆۋەندىكى بۇيرۇقنى ئىجرا قىلىپ GRUB 2 بىلەن كونا MBR تەسۋىرىنى " "ئالماشتۇرالايسىز:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB ئورنىتىش ئۈسكۈنىسى:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "grub-pc بوغچىسى يېڭىلاندى. بۇ تىزىملىك سىزنىڭ قايسى ئۈسكۈنىدە grub-install " "نى ئۆزلۈكىدىن ئىجرا قىلىشنى تاللىشىڭىزغا يول قويىدۇ، ئەگەر بار بولسا." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "كۆپىنچە ئەھۋاللاردا grub-install نى ئۆزلۈكىدىن ئىجرا قىلىش تەۋسىيە قىلىنىپ، " "ئورنىتىلغان GRUB نىڭ يادرولۇق تەسۋىرى بىلەن GRUB بۆلىكى ياكى grub.cfg نىڭ " "قەدەمداش بولماسلىقىنىڭ ئالدى ئېلىنىدۇ." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "ئەگەر BIOS نىڭ قايسى قوزغاتقۇچنى ئاساسىي يېتەكلىگۈچ سۈپىتىدە " "ئىشلىتىدىغانلىقىنى جەزملىيەلمىسىڭىز، GRUB نى بۇ قوزغاتقۇچلارنىڭ ھەممىسىگە " "ئورنىتىش ئادەتتە ياخشى چارە بولالايدۇ." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "دىققەت: GRUB نى رايوننىڭ يېتەكلەش خاتىرىسىگە ئورناتسىڭىزمۇ بولىدۇ، بۇ جايدا " "مۇۋاپىق بولغان رايونلار تەمىنلەندى. ئەمما بۇنداق بولغاندا GRUB مەجبۇرىي قارا " "تىزىملىك مېخانىزمىنى ئىشلىتىپ، ئىشەنچلىكلىكىنىڭ تۆۋەنلەپ كېتىشىنى كەلتۈرۈپ " "چىقىرىدۇ، شۇڭلاشقا ئىشلىتىش تەۋسىيە قىلىنمايدۇ." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB قوزغىتىش يېتەكلىگۈچ يوقالغان دىسكىدىن بىرىگە ئورنىتىلغان ياكى ئۇنىڭ " "بىردىنبىر بەلگىسى مەلۇم سەۋەبلەردىن ئۆزگەرگەن. ئورنىتىلغان GRUB نىڭ يادرولۇق " "تەسۋىرى ۋە GRUB بۆلىكى شۇنداقلا grub.cfg نى قەدەمداشلاش ناھايىتى مۇھىم. " "قايتا بىر قېتىم تەكشۈرۈپ GRUB نىڭ مۇۋاپىق قوزغىتىش ئۈسكۈنىسىگە " "ئورنىتىلغانلىقىغا كاپالەتلىك قىلىڭ." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB, ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB, ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "GRUB نى قوزغىتىش ئۈسكۈنىسىگە يازالمىدى - داۋاملاشتۇرامدۇ؟" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB نى تۆۋەندىكى ئۈسكۈنىگە ئورنىتالمىدى:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "داۋاملاشتۇرۇۋېرەمسىز؟ ئەگەر مۇشۇنداق قىلسىڭىز، كومپيۇتېرىڭىز توغرا " "قوزغىلالماسلىقى مۇمكىن." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "GRUB نى قوزغىتىش ئۈسكۈنىسىگە يېزىش مەغلۇپ بولدى - قايتا سىنامدۇ؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "سىز GRUB نى باشقا ئۈسكۈنىگە ئورنىتالىشىڭىز مۇمكىن، تەكشۈرۈشنى جەزملىشىڭىز " "زۆرۈر بولسىمۇ سىستېمىڭىز شۇ ئۈسكۈنىدىن قوزغىلىدۇ. بولمىسا GRUB Legacy دىن " "يېڭىلاشتىن ۋاز كېچىدۇ." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "GRUB نى ئورناتماي داۋاملاشتۇرامدۇ؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "سىز ھېچقانداق ئۈسكۈنىگە GRUB ئورنىتىشنى تاللىمىدىڭىز. ئەگەر " "داۋاملاشتۇرسىڭىز، قوزغىتىش يېتەكلىگۈچنى توغرا سەپلىيەلمەسلىكىڭىز مۇمكىن، " "كومپيۇتېرىڭىز كېيىنكى قېتىم قوزغالغاندا ئۇ يېتەكلەش سېكتورىدىكى ئىلگىرىكى " "مەزمۇننى ئىشلىتىدۇ. ئەگەر يېتەكلەش سېكتورىدا ئىلگىرىكى نەشرىدىكى GRUB 2 " "بولسا ئۇنىڭ بۆلەكلىرىنى ياكى نۆۋەتتىكى سەپلىمە ھۆججەتنى يۈكلىگىلى بولماسلىقى " "مۇمكىن." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "ئەگەر سىز باشقا بىر قوزغىتىش يېتەكلىگۈچ ئىشلەتكەن ھەمدە داۋاملىق مۇشۇنداق " "قىلماقچى بولسىڭىز ياكى ئەگەر بۇ بىر ئالاھىدە قوزغىتىش يېتەكلىگۈچ تەلەپ " "قىلمايدىغان مۇھىت بولسا، بۇ خىل ئەھۋالدا يەنىلا داۋاملاشتۇرۇشقا بولىدۇ. " "ئۇنداق بولمىسا سىز مەلۇم جايغا GRUB ئورنىتىشىڭىز لازىم." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "/boot/grub دىن GRUB 2 نى چىقىرىۋېتەمدۇ؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "/boot/grub تىن GRUB 2 نىڭ ھەممە ھۆججەتلىرىنى چىقىرىۋېتەمسىز؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "بۇنداق بولغاندا سىستېمىنى يېتەكلىگىلى بولمايدۇ، باشقا قوزغىتىش يېتەكلىگۈچ " "ئورنىتىلسا بۇ باشقا گەپ." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "ھازىر GRUB 2 نىڭ ئايلاندۇرۇشىنى تاماملىدىمۇ؟" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "بۇ سىستېمىدا يەنىلا GRUB Legacy قوزغىتىش يېتەكلىگۈچ ئورناتقان ھۆججەت مەۋجۇت " "ئەمما ھازىرمۇ دىسكىغا GRUB 2 يېتەكلەش خاتىرىسىنى ئورناتتى:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "قارىغاندا GRUB Legacy ئىشلىتىلمىگەندەك تۇرىدۇ، ھەمدە سىز بۇ دىسكىلاردا GRUB " "2 تەسۋىرىگە يېڭىلىشىڭىز لازىم، كونا GRUB Legacy ھۆججەتلىرىنى ئۆچۈرۈش " "ئارقىلىق GRUB 2 تەسۋىرىنى ئايلاندۇرۇشنى تاماملايدۇ. ئەگەر بۇ GRUB 2 " "تەسۋىرىنى يېڭىلىمىغاندا ئۇلار يېڭى بوغچا بىلەن ماسلاشمىغانلىقتىن " "سىستېمىڭىزنىڭ نورمال يېتەكلىنىپ قوزغالماسلىقىنى كەلتۈرۈپ چىقىرىدۇ." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "سىز ئادەتتە GRUB 2 نىڭ ئايلاندۇرۇشىنى تاماملىشىڭىز لازىم، بۇ يېتەكلەش " "خاتىرىسى باشقا مەشغۇلات سىستېمىسىغا ئورنىتىلغان GRUB 2 قۇرغان بولسا بۇ باشقا " "گەپ." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux بۇيرۇق قۇرى:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "تۆۋەندىكى Linux بۇيرۇق قۇرى /etc/default/grub ياكى GRUB Legacy نىڭ menu.lst " "دىكى `kopt' پارامېتىرىدىن ئاجرىتىدۇ. ئۇنىڭ توغرىلىقىنى جەزملەپ، ئېھتىياجغا " "ئاساسەن ئۆزگەرتىڭ.بۇيرۇق قۇرىنىڭ بوش قالدۇرۇلۇشىغا يول قويۇلىدۇ." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linux كۆڭۈلدىكى بۇيرۇق قۇرى:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "تۆۋەندىكى ھەرپ تىزىقى كۆڭۈلدىكى تىزىملىك تۈرىنىڭ Linux پارامېتىرىغا " "ئىشلىتىلىدۇ ئەمما ئەسلىگە كەلتۈرۈش ھالىتىگە قوللىنىلمايدۇ." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD بۇيرۇق قۇرى:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "تۆۋەندىكى kFreeBSD بۇيرۇق قۇرى /etc/default/grub ياكى GRUB Legacy نىڭ menu." "lst دىكى `kopt' پارامېتىرىدىن ئاجرىتىدۇ. ئۇنىڭ توغرىلىقىنى جەزملەپ، " "ئېھتىياجغا ئاساسەن ئۆزگەرتىڭ. بۇيرۇق قۇرىنىڭ بوش قالدۇرۇلۇشىغا يول قويۇلىدۇ." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "kFreeBSD كۆڭۈلدىكى بۇيرۇق قۇرى:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "تۆۋەندىكى ھەرپ تىزىقى كۆڭۈلدىكى تىزىملىك تۈرىنىڭ kFreeBSD پارامېتىرىغا " "ئىشلىتىلىدۇ ئەمما ئەسلىگە كەلتۈرۈش ھالىتىگە قوللىنىلمايدۇ." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map ھاسىل قىلىندى" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "مۇقىم ئۈسكۈنە ئىسمىنى ئىشلىتىش ئۈچۈن /boot/grub/device.map ھۆججىتى قايتا " "يېزىلدى. كۆپ قىسىم ئەھۋالدا بۇ ئۇنى قايتا ئۆزگەرتىش ئېھتىياجىنى ئازايتىشى " "لازىم، GRUB ھاسىل قىلغان يېتەكلەش تىزىملىكى تەسىرگە ئۇچرىماسلىقى لازىم." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "ھالبۇكى، سىستېمىڭىزدا قانچە دىسكا بار، سىستېما كونا ئۈسكۈنە تەسۋىرىگە " "تايىنىشى مۇمكىن. ئۆزىڭىز بەلگىلىگەن ھەر قانداق GRUB نىڭ (hdN) قوزغاتقۇچ " "نومۇرىنىڭ يېتەكلەش تىزىملىكى بار يوقلۇقىنى تەكشۈرۈڭ، ئەگەر ئېھتىياجلىق " "بولسىڭىز ئۇلارنى يېڭىلاڭ." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "ئەگەر بۇ ئۇچۇرنى چۈشەنمىسىڭىز ياكى ھەر قانداق ئۆزلەشتۈرگەن يېتەكلەش " "تىزىملىكى بولمىسا بۇ ئۇچۇرغا پەرۋا قىلمىسىڭىزمۇ بولىدۇ." debian/po/pl.po0000664000000000000000000003624112524662415010576 0ustar # Copyright (C) 2012 # This file is distributed under the same license as the grub-pc package. # # Michał Kułach , 2012. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-01-24 21:51+0100\n" "Last-Translator: Michał Kułach \n" "Language-Team: Polish \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.2\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Załadować z menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Skrypty aktualizacyjne GRUB-a wykryły ustawienia wersji GRUB Legacy w /boot/" "grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Aby zastąpić starą wersję GRUB-a w systemie, zaleca się dostosowanie /boot/" "grub/menu.lst do uruchomienia obrazu rozruchowego GRUB 2 z istniejącej " "instalacji GRUB Legacy. Ten krok zostanie teraz wykonany automatycznie." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Zaleca się zaakceptowanie szeregowego uruchomienia (ang. chainload) GRUB 2 z " "menu.lst i zweryfikowanie poprawności nowych ustawień GRUB-a 2 przed jego " "zapisem do głównego sektora rozruchowego (ang. MBR - Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Niezależnie od podjętej teraz decyzji, zastąpienie starego obrazu MBR przez " "GRUB 2 można przeprowadzić później, wykonując następujące polecenie z " "uprawnieniami administratora:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Urządzenia do instalacji GRUB-a:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Pakiet grub-pc został zaktualizowany. To menu pozwala na wybranie urządzeń, " "dla których powinno zostać uruchomione automatycznie polecenie grub-install, " "jeśli to konieczne." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Automatyczne uruchomienie grub-install jest wskazane w większości " "przypadków, aby zapobiec straceniu synchronizacji z modułami GRUB-a w grub." "cfg przez jego główny obraz." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Jeśli nie jest się pewnym, który napęd został wybrany jako napęd rozruchowy " "przez BIOS komputera, dobrym pomysłem jest zainstalowanie GRUB-a na " "wszystkich dyskach." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Uwaga: jest możliwe zainstalowanie GRUB-a również w sektorach rozruchowych " "partycji i część odpowiednich partycji jest tu wypisana. Niestety, wymusza " "to na GRUB-ie użycie mechanizmu blocklist, który jest bardziej zawodny i, w " "związku z tym, niezalecany." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Program rozruchowy GRUB był zainstalowany wcześniej na dysku który jest " "teraz nieobecny lub którego unikalny identyfikator zmienił się z jakiegoś " "powodu. Jest istotne, aby upewnić się, że główny obraz GRUB-a jest " "zsynchronizowany z modułami GRUB-a w grub.cfg. Proszę sprawdzić ponownie, " "czy GRUB jest zapisywany na właściwe urządzenia rozruchowe." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "" "Zapisywanie GRUB-a na urządzenia rozruchowe nie powiodło się - kontynuować?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Nie powiodło się zainstalowanie GRUB-a na następujących urządzeniach:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Czy kontynuować mimo to? Jeśli tak, ten komputer może nie uruchomić się " "poprawnie." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "Zapisywanie GRUB-a na urządzenia rozruchowe nie powiodło się - spróbować " "ponownie?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Istnieje możliwość zainstalowania GRUB-a na jakimś innym urządzeniu, ale " "należy sprawdzić, czy system się z niego uruchomi. W innym przypadku, " "aktualizacja z GRUB Legacy zostanie odwołana." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Kontynuować bez instalowania GRUB-a?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Wybrano nieinstalowanie GRUB-a na żadnym urządzeniu. W przypadku " "kontynuowania, program rozruchowy może nie być poprawnie skonfigurowany, a " "kiedy komputer zostanie uruchomiony ponownie, będzie używał tego, co " "znajdowało się poprzednio w sektorze rozruchowym. Jeśli jest tam " "wcześniejsza wersja GRUB-a 2, załadowanie modułów lub obsłużenie aktualnego " "pliku konfiguracyjnego może być niemożliwe." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Jeśli używany jest obecnie inny program rozruchowy i ma być on używany nadal " "lub jeśli jest to specjalne środowisko, które nie potrzebuje programu " "rozruchowego, należy kontynuować. W przeciwnym wypadku, powinno się gdzieś " "zainstalować GRUB-a." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Usunąć GRUB-a 2 z /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Czy usunąć wszystkie pliki GRUB-a 2 z /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Może to spowodować brak możliwości uruchomienia systemu, chyba że " "zainstalowany jest inny program rozruchowy." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Zakończyć przejście do GRUB-a 2?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "System ma wciąż zainstalowane pliki z programu rozruchowego GRUB Legacy, ale " "na następujących dyskach zainstalowano także wpisy rozruchowe GRUB-a 2:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Wygląda na to, że GRUB Legacy nie jest już dłużej używany i należy " "zaktualizować obrazy GRUB-a 2 na tych dyskach oraz zakończyć przejście na " "GRUB-a 2 przez usunięcie starych plików GRUB Legacy. Jeśli nie " "zaktualizowano tych obrazów GRUB-a 2, mogą być one niekompatybilne z nowymi " "pakietami i spowodować problemy z poprawnym uruchamianiem systemu." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Można zakończyć przejście na GRUB-a 2, chyba że te wpisy rozruchowe zostały " "stworzone przez GRUB-a 2 zainstalowanego w jakimś innym systemie operacyjnym." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Wiersz poleceń do Linuksa:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Następujące polecenie do Linuksa zostało wyodrębnione z /etc/default/grub " "lub z parametru \"kopt\" w menu.lst GRUB-a Legacy. Proszę sprawdzić czy jest " "właściwe i zmodyfikować go, jeśli to konieczne. Wiersz z poleceniem może być " "pusty." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Domyślny wiersz poleceń do Linuksa:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Następujący ciąg będzie użyty jako parametry przekazywane do jądra Linux w " "domyślnym wpisie menu (ale nie w trybie ratunkowym)." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Wiersz poleceń do kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Następujące polecenie do kFreeBSD zostało wyodrębnione z /etc/default/grub " "lub z parametru \"kopt\" w menu.lst GRUB-a Legacy. Proszę sprawdzić czy jest " "właściwe i zmodyfikować go, jeśli to konieczne. Wiersz z poleceniem może być " "pusty." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Domyślny wiersz poleceń do kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Następujący ciąg będzie użyty jako parametry przekazywane do jądra kFreeBSD " "w domyślnym wpisie menu (ale nie w trybie ratunkowym)." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map został odtworzony" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Plik /boot/grub/device.map został odtworzony tak, aby używał stabilnych nazw " "urządzeń. W większości przypadków powinno to ograniczyć konieczność jego " "zmian w przyszłości, a wpisy menu wygenerowane przez GRUB-a nie powinny " "zostać naruszone." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Jednakże, ponieważ w systemie jest więcej niż jeden dysk, istnieje " "możliwość, że system korzysta ze starej mapy urządzeń. Proszę sprawdzić, czy " "istnieją jakieś specjalne wpisy rozruchowe menu, które polegają na numeracji " "GRUB-a (hdN) i zaktualizować je, jeśli to konieczne." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Jeśli ta wiadomość jest niezrozumiała lub jeśli nie tworzono żadnych " "specjalnych wpisów menu, można ją zignorować." debian/po/hr.po0000664000000000000000000003603312524662415010573 0ustar # Translation of grub2 debconf templates to Croatian # Copyright (C) 2010 Josip Rodin # This file is distributed under the same license as the grub2 package. # Josip Rodin , 2010. # Tomislav Krznar , 2012. # msgid "" msgstr "" "Project-Id-Version: grub2 1.97-2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-03-22 16:37+0100\n" "Last-Translator: Tomislav Krznar \n" "Language-Team: Hrvatski \n" "Language: hr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Učitaj ulančano preko menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Skripte za nadogradnju GRUB-a su pronašle GRUB Legacy postavke u /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Kako bi zamijenili Legacy verziju GRUB-a na vašem sustavu, preporučuje se " "prilagodba /boot/grub/menu.lst kako bi se ulančano učitao GRUB 2 iz vaših " "postojećih GRUB Legacy postavki. Ovaj korak se sada može automatski izvršiti." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Preporučuje se da prihvatite ulančano učitavanje GRUB 2 iz menu.lst, tako da " "možete provjeriti da vam nove GRUB 2 postavke funkcioniraju, prije nego što " "izravno instalirate GRUB2 u MBR (Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Što god odlučite, možete zamijeniti stari sadržaj MBR-a sa GRUB 2 kasnije " "pokretanjem sljedeće naredbe kao root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB uređaji za instalaciju:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Paket grub-pc se nadograđuje. Ovaj izbornik omogućava biranje uređaja za " "koje želite automatski pokrenuti grub-install, ako postoje." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Automatsko pokretanje grub-install je preporučeno u većini slučajeva kako bi " "instalirana GRUB osnovna slika bila sinkronizirana s GRUB modulima ili grub." "cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Ako niste sigurni koji je uređaj u BIOS-u određen za učitavanje, obično je " "dobra ideja instalirati GRUB na svaki." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Napomena: moguće je instalirati GRUB u particijski boot zapis, ovdje su " "navedene neke odgovarajuće particije. Međutim, to prisiljava GRUB na " "korištenje mehanizma blokiranja, što može biti manje pouzdano i zato se ne " "preporučuje." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB boot učitavač je prethodno instaliran na disk koji više nije prisutan, " "ili se njegov jedinstveni identifikator iz nekog razloga promijenio. Važno " "je osigurati da instalirana GRUB osnovna slika ostane sikronizirana s GRUB " "modulima i grub.cfg. Molim ponovo provjerite je li GRUB instaliran na " "odgovarajuće boot uređaje." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Instalacija GRUB-a nije uspjela - želite li nastaviti?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB nije uspio instalaciju na sljedeće uređaje:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Želite li ipak nastaviti? Ako to napravite, vaše računalo se možda neće moći " "uredno pokrenuti." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Instalacija GRUB-a nije uspjela. Pokušati ponovo?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Možda možete instalirati GRUB na neki drugi uređaj, iako biste morali " "provjeriti da se vaš sustav može podizati s tog uređaja. U suprotnom, " "nadogradnja s GRUB Legacy će biti prekinuta." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Nastaviti bez instalacije GRUB-a?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Odabrali ste da ne instalirate GRUB ni na jedan uređaj. Ako nastavite, boot " "učitavač neće biti ispravno podešen, a kada se vaše računalo idući put " "upali, koristit će što god je prethodno bilo u boot sektoru. Ako se tamo " "nalazi ranija verzija GRUB 2, možda će doći do problema s učitavanjem modula " "ili čitanjem trenutne datoteke postavki." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Ako već imate neki drugi boot učitavač i želite ga zadržati, ili ako je ovo " "neko posebno okruženje gdje ne trebate boot učitavač, trebate nastaviti. " "Inače biste morali negdje instalirati GRUB." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Želite li ukloniti GRUB 2 iz /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Želite li ukloniti sve GRUB 2 datoteke iz /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Ovo će onemogućiti učitavanje sustava ako nije instaliran drugi boot " "učitavač." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Završiti prebacivanje na GRUB 2?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Ovaj sustav još uvijek ima instalirane datoteke GRUB Legacy boot učitavača, " "ali sada ima i GRUB 2 boot zapise instalirane na ovim diskovima:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Vjerojatno je GRUB Legacy izbačen iz uporabe i trebali biste nadograditi na " "GRUB 2 snimke na ovim diskovima te završiti prebacivanje brisanjem starih " "GRUB Legacy datoteka. Ako niste nadogradili ove GRUB 2 snimke, onda bi one " "mogle biti nekompatibilne s novim verzijama paketa, što bi moglo uzrokovati " "nemogućnost ispravnog pokretanja sustava." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Općenito, trebali biste dovršiti nadogradnju na GRUB 2, osim ako su navedeni " "boot zapisi napravljeni instalacijom GRUB 2 na nekom drugom operacijskom " "sustavu." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux naredbeni redak:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Ovaj naredbeni redak za sam Linux kernel je izvađen iz /etc/default/grub ili " "iz parametra 'kopt' u GRUB Legacy datoteci menu.lst. Molim provjerite je li " "ispravan, i ako je potrebno uredite ga. Naredbeni redak smije biti prazan." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Pretpostavljeni Linux naredbeni redak:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Sljedeći izraz će biti korišten kao parametar za Linux stavke u izborniku, " "osim za spasonosni način rada." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD naredbeni redak:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Ovaj naredbeni redak za kFreeBSD kernel je izvađen iz /etc/default/grub ili " "iz parametra 'kopt' u GRUB Legacy datoteci menu.lst. Molim provjerite je li " "ispravan, i ako je potrebno uredite ga. Naredbeni redak smije biti prazan." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Pretpostavljeni kFreeBSD naredbeni redak:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Sljedeći izraz će biti korišten kao parametar za kFreeBSD stavke u " "izborniku, osim za spasonosni način rada." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map je regeneriran" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Datoteka /boot/grub/device.map je prepisana kako bi se u njoj koristila " "stabilna imena uređaja. U većini slučajeva, to bi trebalo značajno smanjiti " "potrebu za njenim budućim mijenjanjem, a boot stavke koje generira GRUB ne " "bi trebale biti pod utjecajem ove promjene." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Ipak, budući da imate više od jednog diska u vašem sustavu, moguće je da ste " "ovisili o staroj mapi uređaja. Molim provjerite imate li nekih prilagođenih " "boot zapisa koji ovise o GRUB-ovom (hdN) označavanju uređaja, i ažurirajte " "ih ako je potrebno." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Ako ne razumijete ovu poruku, ili ako nemate prilagođenih boot zapisa, ovu " "poruku možete zanemariti." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "U oba slučaja ako želite da se GRUB 2 učitava izravno iz MBR-a, možete to " #~ "napraviti ako (kao root korisnik) pokrenete sljedeću naredbu:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Instalacija GRUB-a nije uspjela. Nastaviti?" debian/po/kk.po0000664000000000000000000004364712524662415010600 0ustar # Kazakh translation for grub2. # Copyright (C) 2010 The Grub team # This file is distributed under the same license as the PACKAGE package. # Baurzhan Muftakhidinov , 2010-2011. # msgid "" msgstr "" "Project-Id-Version: master\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-06-18 23:22+0600\n" "Last-Translator: Baurzhan Muftakhidinov \n" "Language-Team: Kazakh \n" "Language: kk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Poedit-Language: Kazakh\n" "X-Poedit-Country: KAZAKHSTAN\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "menu.lst ішінен тізбектей жүктелу керек пе?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "GRUB жаңарту скриптері /boot/grub ішінен орнатылған GRUB Legacy тапты." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "GRUB Legacy нұсқасын алмастыру үшін, сіздің бар болып тұрған GRUB Legacy " "орнатудың /boot/grub/menu.lst файлынан GRUB 2 жүктеушісін тізбектей жүктеуге " "баптауға ұсынылады. Бұл қадам қазір автоматты түрде жасалуы мүмкін." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "GRUB 2-ні menu.lst ішінен тізбектей жүктеуді қабылдау, және жаңа GRUB 2 " "орнатуы оны MBR (Басты жүктелу жазбасына) ішіне жазбас бұрын жұмыс " "істейтінін тексеру ұсынылады." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Шешіміңіз қандай болса да, кейін сіз әрқашан да ескі MBR бейнесін жаңа GRUB " "2-мен ауыстыра аласыз, ол үшін root атынан келесі команда орындауыңыз керек:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB орнатылатын құрылғылар:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "grub-pc дестесі жаңартылуда. Бұл мәзір сізге қай құрылғылар үшін grub-" "install автожөнелту қалайтыныңызды көрсетуге мүмкін қылады, егер ондай " "құрылғылар бар болса." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "grub-install автожөнелту көп жағдайда ұсынылады, орнатылған GRUB өзегі және " "модульдер не grub.cfg-мен үйлесімді болуы үшін." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Егер сіз BIOS-та қай диск жүктелетін етіп орнатылғанын нақты білмесеңіз, " "GRUB-ты дисктердің барлығына орнатуға да болады." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Ескерту: GRUB-ты бөлімнің жүктелу жазбасына да орнатуға болады, сәйкес " "келетін бөлімдер тізімі төменде көрсетілген. Алайда, бұл әрекет GRUB-ты " "блоктізімді қолдануға мәжбүрлетеді, яғни оның икемділігін төмендетеді, сол " "үшін ұсынылмайды." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB жүктеушісі қазір жоқ болып тұрған, немесе қандай да бір себептермен " "уникалды идентификаторы өзгерген дискіге бұрын орнатулы болған. Орнатылған " "GRUB өзегі және модульдер мен grub.cfg-мен үйлесімді болуын тексеру маңызды. " "GRUB дұрыс жүктелу құрылғыларына жазылғанын тағы да бір рет тексеріңіз." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} МБ; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} МБ; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "GRUB-ты жүктелу құрылғысына жазу сәтсіз - жалғастыру керек пе?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB келесі құрылғыларға орнату сәтсіз аяқталды:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Бәрібір жалғастыруды қалайсыз ба? Нәтижесінде компьютеріңіз дұрыс жүктелмеуі " "мүмкін." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "GRUB-ты жүктелу құрылғысына жазу сәтсіз - қайталау керек пе?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Сіз оған қоса GRUB-ты басқа да құрылғыларға орната аласыз, бірақ жүйеңіз ол " "кезде жүктеле алатынына көз жеткізіңіз. Болмаса, GRUB Legacy нұсқасынан " "жаңартудан бас тартылады." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "GRUB орнатпай-ақ жалғастыру керек пе?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Сіз GRUB-ты ешбір құрылғыға орнатпауды қалағансыз. Жалғастырсаңыз, жүктеуші " "дұрыс бапталмауы мүмкін, және компьютеріңіз келесі рет жүктелген кезде, " "жүктелу жазбасында оған дейін болған нәрсені қолданады. Егер ол жүктелу " "жазбасында GRUB 2 ертерек шыққан нұсқасы болса, ол модульдерді жүктей алмай, " "не ағымдағы баптаулар файлын талдай алмайтын болуы әдбен мүмкін." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Егер сіз басқа жүктеушіні қолданып, оны жалғастыруды қаласаңыз, немесе бұл - " "жүктеушіні талап етпейтін ерекше жүйе болса, онда жалғастырыңыз. Болмаса, " "қайда болса да, GRUB орнатуыңыз керек." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "GRUB 2 /boot/grub ішінен өшіру керек пе?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "GRUB 2 барлық файлдарын /boot/grub ішінен өшіруді шынымен қалайсыз ба?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Бұл әрекет басқа жүктеуші орнатылмаған болса, жүйеңізді жүктелмейтін қылады." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "GRUB 2-ге айналдыруды қазір аяқтау керек пе?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Жүйеде әлі де GRUB Legacy жүктеушісі орнатылған, оған қоса GRUB 2 жүктелу " "жазбалары келесі дискілерге орнатылған:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "GRUB Legacy енді қолданылмайтын сияқты, орнына GRUB 2 бейнелерін ол " "дискілерде жаңартып, ескі GRUB Legacy файлдарын өшіріңіз. GRUB 2 бейнелерін " "жаңартпасаңыз, олар жаңа дестелермен үйлеспей, жүйеңіз дұрыс жүктелмеуі " "мүмкін." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "GRUB 2 дейін жаңартуды аяқтауыңыз керек, егер осы жүктелу жазбалары басқа " "жүйеде орнатылған GRUB 2 көмегімен жасалмаған болса." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux командалық жолы:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Келесі Linux командасы /etc/default/grub ішінен не GRUB Legacy menu.lst " "ішіндегі `kopt' параметрінен алынды. Оның дұрыстығын тексеріп, керек болса, " "өзгертіңіз. Бұл командалық жол бос болса да болады." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linux бастапқы командалық жолы:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Келесі жол Linux параметрлері бастапқы мәзірі үшін, бірақ қалпына келтіру " "үшін емес, қолданылатын болады." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD командалық жолы:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Келесі kFreeBSD командасы /etc/default/grub ішінен не GRUB Legacy menu.lst " "ішіндегі `kopt' параметрінен алынды. Оның дұрыстығын тексеріп, керек болса, " "өзгертіңіз. Бұл командалық жол бос болса да болады." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "kFreeBSD бастапқы командалық жолы:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Келесі жол kFreeBSD параметрлері бастапқы мәзірі үшін, бірақ қалпына келтіру " "үшін емес, қолданылатын болады." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map қайта құрылды" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "/boot/grub/device.map файлы құрылғылардың тұрақты аттарын қолданатындай " "түзетілген. Көп жағдайда, болашақта өзгерту керек емес болады, және GRUB " "жасаған мәзір элементтері өзгеріссіз-ақ қалады." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Алайда, жүйеңізде бірден көп диск болған соң, ескі device map-қа тәуелді " "болуыңыз мүмкін. GRUB-ң (hdN) түріндегі дисктер нөмірленуі мәзірде жоқ " "болуына көз жеткізіңіз, керек болса, оларды жаңартыңыз." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Егер сіз осы хабарламаны түсінбесеңіз, немесе сізде таңдауыңызша жүктелу " "мәзірінің элементтері жоқ болса, бұл хабарламаны елемеңіз." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Қалай болса да, GRUB 2 тура MBR ішінен жүктелуді қалайтын болсаңыз, сол " #~ "кезде root атынан келесі команданы орындаңыз:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "GRUB орнату сәтсіз. Жалғастыру керек пе?" debian/po/lv.po0000664000000000000000000003517312524662415010607 0ustar # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Rūdolfs Mazurs , 2012. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-05-25 12:10+0300\n" "Last-Translator: Rūdolfs Mazurs \n" "Language-Team: Latvian \n" "Language: lv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : " "2);\n" "X-Generator: Lokalize 1.4\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Secīgi ielādēt no menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "GRUB uzlabošanas skripti ir atklājuši GRUB mantotos iestatījumus mapē /boot/" "grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Lai aizvietotu mantoto GRUB versiju savā sistēmā, iesakām pielāgot /boot/" "grub/menu.lst, lai tā ielādē GRUB 2 palaišanas attēlu no esošās GRUB " "mantotās instalācijas. Tagad šo soli var veikt automātiski." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Ieteicams pieņemt secīgās ielādes (chainloading) GRUB 2 no menu.lst un " "pārliecināties, ka jaunais GRUB 2 darbojas, pirms no ierakstīt MBR " "(galvenajā palaišanas ierakstā)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Lai kāds būtu lēmums, jūs varat aizvietot veco MBR attēlu ar GRUB 2 vēlāk, " "dodot sekojošās komandas ar root tiesībām:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB instalēšanas ierīces:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Tiek uzlabota grub-pc pakotne. Šī izvēlne ļauj jums izvēlēties ierīces, " "kuras grub-install vajadzētu palaists (ja vajag)." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Automātiska grub-install palaišana ir ieteicama vairumā gadījumu, lai " "nepieļautu, ka instalētais GRUB attēls būtu asinhrons ar GRUB moduļiem vai " "grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Ja nezināt, kuru dzini BIOS ir nozīmējis kā palaišanas dzini, tad bieži ir " "ieteicams instalēt GRUB uz visiem dziņiem." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Ņemiet vērā — ir iespējams uzinstalēt GRUB arī uz nodalījuma palaišanas " "ierakstiem, un šeit tiek piedāvāti daži noderīgi nodalījumi. Bet tas liek " "GRUB izmantot bloķēšanas saraksta mehānismu, kas padara to mazāk uzticamu, " "tātad nerekomendējamu." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB palaidējs iepriekš bija uzinstalēts uz diska, kas vairs nav šeit, vai " "kaut kāda iemesla dēļ tika mainīts tā unikālais identifikators. Ir svarīgi " "nodrošināt, ka instalētais GRUB pamata attēls ir sinhrons ar GRUB moduļiem " "un grub.cfg. Lūdzu, vēlreiz pārliecinieties, ka GRUB ir uzrakstīts uz " "atbilstošām palaišanas ierīcēm." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Neizdevās ierakstīt GRUB uz palaišanas ierīces — turpināt?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Neizdevās uzinstalēt GRUB uz šīm ierīcēm:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Vai tomēr vēlaties turpināt? Ja tā, dators varētu nespēt pareizi palaisties." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Neizdevās ierakstīt GRUB uz palaišanas ierīces — mēģināt atkal?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Iespējams, jūs varat uzinstalēt GRUB uz kādas citas ierīces, bet jums " "jāpārliecinās, ka sistēma varēs no tās ierīces palaisties. Citādi uzlabošana " "no GRUB mantojuma tiks atcelta." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Turpināt bez GRUB instalēšanas?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Jūs varat izvēlēties neinstalēt GRUB uz nevienas ierīces. Ja turpināsiet, " "palaidējs varētu nebūt pareizi konfigurēts, un kad dators tiks palaists, tas " "izmantos to konfigurāciju, kas jau atrodas palaišanas sektorā. Ja palaišanas " "sektorā jau ir vecāka GRUB 2 versija, tā varētu nespēt ielādēt moduļus vai " "apstrādāt esošo konfigurācijas datni." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Ja jūs jau izmantojat citu palaidēju un vēlaties to turpināt izmantot, vai " "arī šī ir īpaša vide, kur nav vajadzīgs palaidējs, jums vajadzētu turpināt. " "Citādi, jums vajadzētu kaut kur uzinstalēt GRUB." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Izņemt GRUB 2 no /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Vai vēlaties, lai visi GRUB 2 faili tiktu izņemti no /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Tas padarīs sistēmu nepalaižamu, ja vien nav uzinstalēts kāds cits palaidējs." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Pabeigt pārveidošanu uz GRUB 2 tagad?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Šajā sistēmā vēl aizvien ir uzinstalētas datnes no GRUB mantojuma palaidēja, " "bet tam tagad ir arī GRUB 2 palaišanas ieraksti, kas ir uzinstalēti uz šiem " "diskiem:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Izskatās, ka GRUB mantojums vairs netiek izmantots, un jums vajadzētu " "pabeigt GRUB 2 attēlu uzlabošanu uz šiem diskiem un pabeigt pāreju uz GRUB " "2, izdzēšot vecās GRUB mantojuma datnes. Ja nevēlaties uzlabot šos GRUB 2 " "attēlus, tad tie varētu nebūt savietojami ar jaunajām pakotnēm un var neļaut " "sistēmai pareizi palaisties." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Jums vajadzētu pabeigt pāreju uz GRUB 2, izņemot, ja šos palaišanas " "ierakstus izveidoja GRUB 2 instalācija no kādas citas operētājsistēmas." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux komandrinda:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Sekojošā Linux komandrinda tika izvilkta no /etc/default/grub vai `kopt' " "parametra GRUB mantojuma menu.lst. Lūdzu, pārliecinieties, ka tā ir pareiza " "un, ja vajag, mainiet to. Komandrinda drīkst būt tukša." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linux noklusējuma komandrinda:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Sekojošā virkne tiks izmantota kā Linux parametri izvēlnes noklusējuma " "ierakstam, bet ne sistēmas atgūšanas režīmā." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD komandrinda:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Sekojošā kFreeBSD komandrinda tika izvilkta no /etc/default/grub vai `kopt' " "parametra GRUB mantojuma menu.lst. Lūdzu, pārliecinieties, ka tā ir pareiza " "un, ja vajag, mainiet to. Komandrinda drīkst būt tukša." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "kFreeBSD noklusējuma komandrinda:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Sekojošā virkne tiks izmantota kā kFreeBSD parametri izvēlnes noklusējuma " "ierakstam, bet ne sistēmas atgūšanas režīmā." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map tika reģistrēts" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Fails /boot/grub/device.map tika pārrakstīts, lai izmantotu stabilos ierīču " "nosaukumus. Vairumā gadījumu tam vajadzētu būtiski samazināt vajadzību to " "mainīt nākotnē, un palaišanas izvēlnes ierakstiem, ko veidojis GRUB, " "nevajadzētu tikt skartiem." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Tomēr, tā kā sistēmā atrodas vairāki diski, iespējams, ka sistēma ir " "atkarīga no vecās ierīču kartes. Lūdzu, pārliecinieties, vai ir kādi " "pielāgoti palaišanas izvēlnes ieraksti, kas balstās uz GRUB (hdN) disku " "numurēšanas, un atjauniniet tos, ja tā ir." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Ja jūs nesaprotat šo ziņojumu, vai arī nav pielāgotu palaišanas izvēlnes " "ieraktu, jūs varat ignorēt šo ziņojumu." debian/po/bg.po0000664000000000000000000004577612524662415010570 0ustar # Bulgarian translation of grub2 debconf messages. # Copyright (C) grub2 packagers. # This file is distributed under the same license as the grub2 package. # Damyan Ivanov , 2009, 2010, 2011. # msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-12-27 15:01+0200\n" "Last-Translator: Damyan Ivanov \n" "Language-Team: Bulgarian \n" "Language: bg\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Верижно зареждане от menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "Открита е стара инсталация на GRUB в /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "За замяна на старата инсталация на GRUB се препоръчва настройване на /boot/" "grub/menu.lst за каскадно зареждане на GRUB2 от съществуващата инсталация на " "GRUB. Това може да извършено автоматично." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Каскадното зареждане на GRUB2 от menu.lst се препоръчва за да е сигурно, че " "настройките на GRUB2 са правилни, преди инсталирането му в записа за начално " "зареждане (MBR)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Каквото и да решите, по-късно можете да замените стария запис в MBR с този " "на GRUB2 със следната команда, изпълнена като администратор:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Инсталиране на GRUB на следните устройства:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Пакетът grub-pc се обновява. Това меню позволява избиране за кои устройства " "(и дали изобщо) да се изпълни командата grub-install." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "В повечето случаи автоматичното изпълнение на grub-install се препоръчва за " "предотвратяване на разминаване между образа на GRUB на диска и модулите или " "файла grub.cfg във файловата система." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Ако не сте сигурни кое устройство е определено за начално зареждане в BIOS, " "добра идея е да инсталирате GRUB на всички налични устройства." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Забележка: по принцип е възможно GRUB да се инсталира на записите за начално " "зареждане на дисковите дялове. Списъка включва подходящи дялове, но подобна " "инсталация ще накара GRUB да използва списъци с блокове, което прави " "работата му по-малко надеждна и поради тази причина не се препоръчва." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Програмата за начално зареждане на GRUB е била инсталирана на диск, който " "вече не е достъпен или чийто уникален идентификатор е бил променен. Много е " "важно инсталираният образ винаги да е отговаря на модулите на GRUB и файла " "grub.cfg на файловата система. Проверете и се убедете, че GRUB се инсталира " "на правилните устройства." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "" "Записването на GRUB върху устройството за начално зареждане не успя. " "Продължаване?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Опитът за инсталиране на GRUB на следните устройства беше неуспешен:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Желаете ли да продължите въпреки това? Ако го направите е възможно " "компютърът да не може да зареди операционна система." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "Записването на GRUB върху устройството за начално зареждане на успя. Нов " "опит?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Възможно е инсталирането на GRUB на друго устройство да успее, но трябва да " "проверите дали компютърът може да извършва първоначално зареждане от него. " "Ако откажете, обновяването от стария GRUB ще бъде отменено." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Продължаване без инсталиране на GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Избрано е GRUB да не се инсталира на никакви устройства. Ако продължите, " "програмата за начално зареждане може да не е настроена правилно и при " "следващото стартиране на компютъра ще се използва предишното съдържание на " "сектора за начално зареждане. Ако в него има предишна инсталация на GRUB 2 е " "възможно тя да не успее да използва обновените модули или конфигурационния " "файл." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Ако използвате друга програма за начално зареждане и желаете да я запазите " "или ако обкръжението е специално и не изисква програма за начално зареждане, " "тогава е редно да продължите без да инсталирате GRUB. В противен случай би " "трябвало да инсталирате GRUB някъде." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Изтриване на GRUB 2 от /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Желаете ли да изтриете всички файлове на GRUB от папката /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Това ще възпрепятства зареждането на системата, до инсталиране на друга " "програма за начално зареждане." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Завършване на преминаването към GRUB2 ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "На системата има файлове от стария GRUB, но има сектори за начално зареждане " "от GRUB 2, инсталирани на следните дискове:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Изглежда, че старият GRUB не се използва и вместо него е редно се инсталира " "GRUB 2 върху дисковете и да се завърши прехода чрез премахване на файловете " "на стария GRUB. Ако не обновите инсталацията на GRUB 2 е възможно да се " "появят проблеми с началното зареждане поради несъвместимост с новите пакети." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "В общия случай е добре преходът към GRUB 2 да бъде завършен, освен ако " "секторите за начално зареждане са създадени от GRUB 2 или от друга " "операционна система." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Команден ред на Линукс:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Следния команден ред за зареждане на Линукс беше извлечен от /etc/default/" "grub или от параметъра „kopt“ от файла menu.lst на стария GRUB. Проверете го " "и ако е нужно го коригирайте. Допустимо е командният ред да бъде празен." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Параметри на Линукс по подразбиране:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Следните параметри ще бъдат използвани по подразбиране при зареждане на " "Линукс, освен в авариен режим." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Команден ред за kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Следния команден ред за зареждане на kFreeBSD беше извлечен от /etc/default/" "grub или от параметъра „kopt“ от файла menu.lst на стария GRUB. Проверете го " "и ако е нужно го коригирайте. Допустимо е командният ред да бъде празен." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Параметри на Линукс по подразбиране:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Следните параметри ще бъдат използвани по подразбиране при зареждане на " "kFreeBSD, освен в авариен режим." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map е създаден наново" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Файлът /boot/grub/device.map е създаден наново, използвайки постоянни имена " "на устройства. В повечето случаи това води до намаляване на нуждата да се " "правят промени в бъдеще. Елементите в менюто за начално зареждане на GRUB не " "са засегнати." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Все пак, понеже в системата има повече от един диск, е възможно съдържанието " "на стария файл да е от критична важност. Проверете дали имате елементи в " "менюто за начално зареждане на GRUB, в които да се използват устройства от " "вида „(hdN)“ и ако е нужно ги коригирайте." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Ако не разбирате предупреждението или ако нямате ръчно-въведени елементи в " "менюто на GRUB, не обръщайте внимание на това съобщение." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Когато речите да инсталирате GRUB 2 в записа за начално зареждане, " #~ "изпълнете следната команда като администратор:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Инсталирането на GRUB се провали. Продължаване?" debian/po/el.po0000664000000000000000000005114612524662415010564 0ustar # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Emmanuel Galatoulas , 2010, 2012. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-08-17 14:44+0300\n" "Last-Translator: galaxico \n" "Language-Team: Greek \n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Να γίνει αλυσιδωτή φόρτωση από το αρχείο menu.lst;" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Τα σενάρια αναβάθμισης του GRUB έχουν εντοπίσει αρχεία ρύθμισης του GRUB " "Legacy στον κατάλογο /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Για να αντικαταστήσετε την έκδοση Legacy του GRUB στο σύστημά σας, " "συνιστάται η προσαρμογή του αρχείου /boot/grub/menu.lst ώστε να γίνεται η " "φόρτωση μιας εκκινήσιμης εικόνας του GRUB 2 μέσα από την υπάρχουσα " "διαμόρφωση του GRUB Legacy. Το βήμα αυτό μπορεί να πραγματοποιηθεί τώρα " "αυτόματα." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Συνιστάται η αποδοχή της αλυσιδωτής φόρτωσης του GRUB 2 από το αρχείο menu." "lst και η επαλήθευση της λειτουργικότητας της νέας ρύθμισης του GRUB 2 πριν " "αυτό εγγραφεί στο MBR (Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Όποια κι αν είναι η απόφασή σας, μπορείτε να αντικαταστήσετε αργότερα την " "προηγούμενη εικόνα του MBR με τη βοήθεια του GRUB 2, εκτελώντας ως χρήστης " "root την ακόλουθη εντολή: " #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Συσκευές εγκατάστασης του GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Γίνεται αναβάθμιση του πακέτου grub-pc. Αυτό το μενού σας επιτρέπει να " "επιλέξετε τις συσκευές, αν θέλετε κάποιες, για τις οποίες θα εκτελεστεί " "αυτόματα το grub-install." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Η αυτόματη εκτέλεση του grub-install συνιστάται στις περισσότερες " "περιπτώσεις για την αποτροπή του αποσυγχρονισμού της εγκατεστημμένης κύριας " "εικόνας του GRUB από τα αρθρώματα του GRUB στο αρχείο grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Αν δεν είστε βέβαιοι για το ποια συσκευή έχει οριστεί ως συσκευή εκκίνησης " "από το BIOS του συστήματός σας, είναι συχνά καλή ιδέα να εγκαταστήσετε το " "GRUB σε όλες τις συσκευές." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Σημείωση: είναι δυνατόν να εγκαταστήσετε το GRUB και σε αρχεία εκκίνησης " "κατατμήσεων (boot records) και εδώ προσφέρονται μερικές τέτοιες κατάλληλες " "κατατμήσεις. Όμως, αυτό αναγκάζει το GRUB να χρησιμοποιήσει τον μηχανισμό " "blocklist, κάτι που το καθιστά λιγότερο αξιόπιστο, κατά συνέπεια αυτή η " "μέθοδος δεν συνίσταται." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Ο φορτωτής εκκίνησης GRUB είχε εγκατασταθεί προηγουμένως σε έναν δίσκο που " "δεν είναι πλέον παρόν στο σύστημα ή που ο μοναδικός κωδικός αναγνώρισής του " "έχει για κάποιο λόγο αλλάξει. Είναι σημαντικό να βεβαιωθείτε ότι η " "εγκατεστημένη κύρια εικόνα του GRUB παραμένει συγχρονισμένη με τα αρθρώματα " "του GRUB στο αρχείο grub.cfg. Παρακαλώ ελέγξτε ξανά για να σιγουρευτείτε ότι " "το GRUB έχει εγγραφεί στις κατάλληλες εκκινήσιμες συσκευές." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Η εγγραφή του GRUB στην συσκευή εκκίνησης απέτυχε - Να συνεχίσω;" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Απέτυχε η εγκατάσταση του GRUB στις ακόλουθες συσκευές:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Θέλετε να συνεχίσετε έτσι κι αλλιώς; Αν ναι, είναι πιθανόν ο υπολογιστής σας " "να μην μπορεί να εκκινήσει κανονικά." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "Η εγγραφή του GRUB στη συσκευή εκκίνησης απέτυχε - Θα ξαναπροσπαθήσετε;" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Είναι πιθανόν να εγκαταστήσετε το GRUB σε κάποια άλλη συσκευή, αλλά θα " "πρέπει να ελέγξετε ότι το σύστημά σας μπορεί να εκκινήσει από αυτή τη " "συσκευή. Διαφορετικά, η αναβάάθμιση από την έκδοση Legacy του GRUB θα " "ακυρωθεί." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Συνέχεια χωρίς εγκατάσταση του GRUB;" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Επιλέξατε να μην εγκαταστήσετε το GRUB σε οποιαδήποτε συσκευή. Αν " "συνεχίσετε, ο φορτωτής εκκίνησης πιθανόν να μην έχει ρυθμιστεί σωστά και " "στην επανεκκίνηση του υπολογιστή σας θα χρησιμοποιήσει οτιδήποτε υπήρχεαπό " "πριν στον τομέα εκκίνησης. Αν υπάρχει μια προηγούμενη έκδοση του GRUB 2 στον " "τομέα εκκίνησης, πιθανόν να μην μπορεί να φορτώσει κάποια αρθρώματα ή να " "χειριστεί το τρέχον αρχείο ρυθμίσεων." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Αν χρησιμοποιείτε ήδη έναν διαφορετικό φορτωτή εκκίνησης και θέλετε να " "συνεχίσετε με αυτόν ή αν το παρόν σύστημα είναι ένα ειδικό περιβάλλον στο " "οποίο δεν χρειάζεστε έναν φορτωτή εκκίνησης, τότε θα πρέπει να συνεχίσετε " "έτσι κι αλλιώς. Διαφορετικά, θα πρέπει να εγκαταστήσετε κάπου το GRUB." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Να αφαιρεθεί το GRUB από το /boot/grub;" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "" "Θέλετε να αφαιρεθούν όλα τα αρχεία του GRUB 2 από τον κατάλογο /boot/grub;" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Κάτι τέτοιο θα καταστήσει το σύστημα μη εκκινήσιμο εκτός αν εγκαταστήσετε " "κάποιον άλλον φορτωτή εκκίνησης." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Να τελειώσει τώρα η μετατροπή σε GRUB 2;" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Το σύστημα έχει ακόμα εγκατεστημένα αρχεία από τον φορτωτή εκκίνησης GRUB " "Legacy, αλλά έχει τώρα επίσης εγκατεστημένα αρχεία εκκίνησης του GRUB 2 " "στους εξής δίσκους:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Φαίνεται πιθανόν ότι ο φορτωτής εκκίνησης GRUB Legacy δεν είναι πια σε χρήση " "και ότι θα πρέπει αντίθετα να αναβαθμίσετε το GRUB 2 στους παρακάτω δίσκους " "και να ολοκληρώσετε την μετατροπή στο GRUB 2 αφαιρώντας οποιαδήποτε " "παλιότερα αρχεία του GRUB Legacy. Αν δεν αναβαθμίσετε αυτές τις εικόνες του " "GRUB 2, τότε πιθανόν να είναι ασύμβατες με τα νεώτερα πακέτα, με αποτέλεσμα " "να σταματήσει η κανονική εκκίνηση του συστήματός σας." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Θα πρέπει γενικά να τελειώσετε την μετατροπή σε GRUB 2 εκτός κι αν αυτά τα " "αρχεία εκκίνησης έχουν δημιουργηθεί από μια εγκατάσταση του GRUB 2 σε ένα " "άλλο λειτουργικό σύστημα." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Γραμμή εντολής Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Η επόμενη γραμμή εντολών για Linux έχει εξαχθεί από το αρχείο /etc/default/" "grub ή από την παράμετρο `kopt' στο αρχείο menu.lst του GRUB Legacy. " "Παρακαλώ επιβεβαιώστε ότι είναι ορθή και τροποποιήστε την αν είναι " "απαραίτητο. Η γραμμή επιτρέπεται να είναι κενή." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Προκαθορισμένη γραμμή εντολών Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Η ακόλουθη συμβολοσειρά θα χρησιμοποιηθεί για τις παραμέτρους Linux στην " "προκαθορισμένη είσοδο του μενού εκκίνησης αλλά όχι για την κατάσταση " "διάσωσης (rescue mode)." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Γραμμή εντολών kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Η επόμενη γραμμή εντολών του kFreeBSD έχει εξαχθεί από το αρχείο /etc/" "default/grub ή από την παράμετρο `kopt' στο αρχείο menu.lst του GRUB " "Legacy. Παρακαλώ επιβεβαιώστε ότι είναι ορθή και τροποποιήστε την αν είναι " "απαραίτητο. Η γραμμή επιτρέπεται να είναι κενή." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Προκαθορισμένη γραμμή εντολών kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Η ακόλουθη συμβολοσειρά θα χρησιμοποιηθεί για τις παραμέτρους kFreeBSD στην " "προκαθορισμένη είσοδο του μενού εκκίνησης αλλά όχι για την κατάσταση " "διάσωσης (rescue mode)." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "Το αρχείο /boot/grub/device.map έχει αναδημιουργηθεί" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Το αρχείο /boot/grub/device.map έχει ξαναγραφεί ώστε να χρησιμοποιεί σταθερά " "ονόματα συσκευών. Στις περισσότερες περιπτώσεις αυτό θα μειώσει αισθητά την " "ανάγκη αλλαγής του στο μέλλον, τα δε στοιχεία του μενού εκκίνησης που " "παράγονται από το GRUB δεν θα επηρεάζονται." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Παρ' όλα αυτά και αφού στο σύστημά σας υπάρχουν περισσότεροι από έναν " "δίσκους,είναι πιθανόν το σύστημά σας να εξαρτάται από το παλιότερο αρχείο " "απεικόνισης συσκευών device.map. Παρακαλώ ελέγξτε αν υπάρχουν οποιεσδήποτε " "ειδικές είσοδοι στο μενού εκκίνησης που βασίζονται στην αρίθμηση των " "συσκευών από το GRUB (hdN) και ενημερώστε τις αν είναι απαραίτητο." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Αν δεν καταλαβαίνετε το παρόν μήνυμα ή δεν έχετε οποιεσδήποτε ειδικές " "εισόδους στο μενού εκκίνησης, μπορείτε να το αγνοήσετε." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Σε οποιαδήποτε περίπτωση όποτε θελήσετε να φορτωθεί το GRUB 2 απευθείας " #~ "από το MBR μπορείτε να το κάνετε τρέχοντας (ως χρήστης root) την ακόλουθη " #~ "εντολή:" debian/po/hu.po0000664000000000000000000003615512524662415010603 0ustar # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # Dr. Nagy Elemér Károly , 2013. # msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2013-05-18 15:44+0200\n" "Last-Translator: Dr. Nagy Elemér Károly \n" "Language-Team: Hungarian \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: UTF-8\n" "Plural-Forms: ???\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Továbbtöltsünk a menu.lst-ből?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "A GRUB frissítő program észlelte, hogy régi GRUB beállítás van a /boot/grub-" "ban." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "A régi GRUB lecserélése érdekében javasolt, hogy a /boot/grub/menu.lst fájlt " "úgy módosítsuk, hogy egy GRUB2 betöltőképet töltsön be a régi GRUB. Ezt " "automatikusan elvégezhetjük most." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Javaslom, hogy a menu.lst-ből töltsük tovább a GRUB 2-t, és ellenőrizzük, " "hogy működik-e az új GRUB 2 beállítása, mielőtt az MBR-be (Master Boot " "Record) írnánk" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Bárhogy is döntesz most, a régi MBR képet kicserélheted a GRUB2 " "betöltőképével, ha rendszergazdaként (root) kiadod a következő parancsot:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB telepítési eszközök:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "A grub-pc csomagot frissítjük. Ebben a menüben kiválaszthatod, hogy melyik " "egységekre szeretnéd automatikusan futtatni a grub-install parancsot, ha van " "ilyen." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "A grub-install automatikus futtatása erősen javasolt a legtöbb esetben, mert " "megakadályozza, hogy a GRUB töltőkép más verziójú legyen, mint a GRUB " "modulok vagy a grub.cfg fájl." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Ha nem vagy benne biztos, hogy melyik meghajtó van rendszerlemeznek " "beállítva a BIOS-ban, jó ötlet lehet mindegyikre feltelepíteni a GRUB-ot." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Megjegyzés: A GRUB-ot nemcsak lemez, de partíció rendszerbetöltő részére is " "lehet telepíteni, és ha van erre alkalmas partíció, azt is felkínáljuk itt. " "Mivel azonban így a GRUB kénytelen a blokklista módszert (blocklist) " "alkalmazni, amely kevésbé megbízható, így ez nem javasolt." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "A GRUB rendszerbetöltő korábban egy olyan lemezre volt telepítve, amely " "hiányzik vagy amelynek megváltozott az egyedi azonosítója. Fontos, hogy " "biztosítsuk, hogy a GRUB töltőkép ugyanolyan verziójú legyen, mint a GRUB " "modulok és a grub.cfg. Kérlek ellenőrizd még egyszer hogy biztosan a " "megfelelő eszközre írjuk a GRUB-ot." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Nem sikerül a GRUB-ot a rendszerlemezre írni - folytassuk?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Nem sikerült a GRUB-ot a következő eszközökre telepíteni:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Ennek ellenére folytatni akarod? Ha folytatod, lehet, hogy a számítógéped " "nem fog elindulni." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Nem sikerül a GRUB-ot a rendszerlemezre írni - megpróbáljuk újra?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Megpróbálhatod egy másik eszközre telepíteni a GRUB-ot, de ehhez célszerű " "ellenőrizni, hogy az adott eszközről el tud-e indulni a rendszer. Egyébként " "a régi GRUB frissítését visszavonjuk." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "GRUB telepítése nélkül folytassuk:" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Úgy döntöttél, hogy ne telepítsük a GRUB-ot egyetlen eszközre sem. Ha " "folytatod, lehet, hogy nem lesz jól beállítva a rendszerbetöltőd és a " "számítógéped következő indulásakor az fog elindulni, ami korábban a " "rendszerbetöltő szektorban volt. Ha ebben a GRUB 2 egy régebbi verziója van, " "lehet, hogy nem tudja majd betölteni a moduljait vagy nem lesz képes " "értelmezni a jelenlegi konfigurációs fájlt." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Ha már egy másik rendszerbetöltőt használsz és annál maradnál, vagy ha olyan " "különleges környezetben dolgozol, ahol nincs szükséged rendszerbetöltőre, " "folytathatod. Minden más esetben valahová telepítened kellene a GRUB-ot." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Kiszedjem a GRUB 2-t a /boot/grub-ból?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Azt szeretnéd, hogy minden GRUB 2 fájlt kiszedjek a /boot/grub-ból?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Ezzel a rendszert indulásra képtelen állapotba hozod, hacsak nem telepítesz " "másik rendszerbetöltőt." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Befejezed most az átállást a GRUB 2-re?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Ezen a rendszeren még mindig vannak a régi GRUB rendszerbetöltőhöz tartozó " "fájlok, de a következő lemezeken már a GRUB 2 rendszerbetöltő van telepítve:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Úgy tűnik, hogy a régi GRUB már nincs használatban és hogy jobb lenne, ha a " "GRUB 2 betöltőképekre frissítenénk ezeket a lemezeket és ha a régi GRUB " "fájlok eltávolításával befejeznénk az áttérést a GRUB 2-re. Ha nem frissíted " "ezeket a GRUB2 betöltőképeket, akkor inkompatibilisek lehetnek az új " "csomagokkal és lehet, hogy nem fog elindulni a rendszer." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Általában célszerű befejezni a GRUB 2-re áttérést, kivéve ha ezek a " "rendszerbetöltő rekordok egy másik operációs rendszeren futó GRUB 2 " "telepítéssel készültek." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux parancssor:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "A következő Linux parancssor az /etc/default/grub vagy a régi GRUB menu.lst " "fájljában lévő `kopt' paraméterből származik. Kérlek ellenőrizd, hogy helyes-" "e, és módosítsd, ha szükséges. A parancssor lehet üres is." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Az alapértelmezett Linux parancssor:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "A következő sort fogjuk Linux paraméternek használni az alapértelmezett " "(default) menüben, de a rendszervisszaállító (recovery) módban nem." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD parancssor:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "A következő kFreeBSD parancssor az /etc/default/grub vagy a régi GRUB menu." "lst fájljában lévő `kopt' paraméterből származik. Kérlek ellenőrizd, hogy " "helyes-e, és módosítsd, ha szükséges. A parancssor lehet üres is." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Az alapértelmezett kFreeBSD parancssor:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "A következő sort fogjuk kFreeBSD paraméternek használni az alapértelmezett " "(default) menüben, de a rendszervisszaállító (recovery) módban nem." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "A /boot/grub/device.map fájlt újraépítettem." #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "A /boot/grub/device.map fájlt újraírtam, így már stabil eszköznevek " "szerepelnek benn. A legtöbb esetben ez jelentősen csökkenti a szükséges " "változtatások számát a jövőben, és a GRUB által készített menüpontoknak " "ettől nem kéne megváltozniuk változniuk." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Mivel azonban egynél több lemez van a rendszervben, lehetséges, hogy a " "rendszernek szüksége van a régi eszköztérképre. Kérelk ellenőrizd, hogy van-" "e olyan saját készítésű rendszerbetöltő menüpontod amelyik a GRUB (hdN) " "eszközszámozását használja, és frissítsd, ha szükséges." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Ha nem érted ezt az üzenetet, vagy ha nem csináltal saját készítésű " "rendszerbetöltő menüpontot, ne is törődj vele, lépj tovább." debian/po/fr.po0000664000000000000000000004062312524662415010571 0ustar # translation of fr.po to French # Translation of grub2 debconf templates to French # Copyright (C) 2008-2010 Debian French l10n # This file is distributed under the same license as the grub2 package. # # Christian Perrier , 2007, 2008, 2009, 2010, 2011. msgid "" msgstr "" "Project-Id-Version: fr\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-05-28 07:47+0200\n" "Last-Translator: Christian Perrier \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Faut-il enchaîner le chargement depuis menu.lst ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "Une installation standard de GRUB a été détectée dans /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Afin de remplacer cette installation, il est recommandé de modifier /boot/" "grub/menu.lst pour charger GRUB 2 depuis l'installation standard de GRUB " "(« chainload »). Veuillez choisir si vous souhaitez effectuer cette " "modification." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Il est recommandé de choisir cette option pour pouvoir confirmer le bon " "fonctionnement de GRUB 2 avant de l'installer directement sur le secteur " "d'amorçage (MBR : « Master Boot Record »)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Quel que soit votre choix, vous pourrez, plus tard, remplacer l'ancien " "secteur d'amorçage par GRUB 2 avec la commande suivante, exécutée avec les " "privilèges du superutilisateur :" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Périphériques où installer GRUB :" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Le paquet grub-pc est en cours de mise à jour. Ce menu permet de choisir " "pour quels périphériques vous souhaitez exécuter la commande grub-install " "automatiquement." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Il est en général recommandé d'exécuter grub-install automatiquement, afin " "d'éviter la situation où l'image de GRUB est désynchronisée avec les modules " "de GRUB ou le fichier grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Si vous n'avez pas la certitude du périphérique utilisé comme périphérique " "d'amorçage par le BIOS, il est en général conseillé d'installer GRUB sur " "l'ensemble des périphériques." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Veuillez noter que GRUB peut également être installé sur les secteurs " "d'amorçage de partitions. Certaines partitions où cela pourrait être " "nécessaire sont indiquées ici. Cependant, cela impose que GRUB utilise le " "mécanisme « blocklist », ce qui le rend moins fiable et n'est donc pas " "recommandé." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Le chargeur d'amorçage GRUB était précédemment installé sur un disque qui " "n'est plus présent ou dont l'identifiant unique a changé pour une raison ou " "une autre. Il est important de vous assurer que l'image de GRUB qui est " "installée reste synchronisée avec les modules de GRUB ou grub.cfg. Veuillez " "vérifier à nouveau que GRUB sera bien installé sur les périphériques " "d'amorçage pertinents." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} Mo; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} Mo; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "" "Échec de l'installation de GRUB sur le périphérique d'amorçage. Continuer ?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB n'a pas pu être installé sur les périphériques suivants :" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Veuillez confirmer si vous souhaitez continuer malgré le risque d'un " "démarrage incorrect de la machine." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "Échec de l'installation de GRUB sur le périphérique d'amorçage. Essayer à " "nouveau ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Il est peut-être possible d'installer GRUB sur un autre périphérique après " "avoir vérifié que le système pourra démarrer sur ce périphérique. Dans le " "cas contraire, la mise à jour depuis l'ancienne version de GRUB va échouer." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Faut-il poursuivre sans installer GRUB ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Vous avez choisi de n'installer GRUB sur aucun périphérique. Si vous " "poursuivez, il est possible que le programme de démarrage ne soit pas " "configuré correctement et que la machine démarre avec ce qui était " "précédemment installé sur le secteur d'amorçage. Si une ancienne version de " "GRUB 2 s'y trouve, il est possible qu'elle ne puisse pas charger certains " "modules ou lire le fichier de configuration actuel." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Si vous utilisez déjà un autre programme de démarrage et souhaitez " "poursuivre ou si, en raison d'un environnement particulier, vous n'avez pas " "besoin de programme de démarrage, vous pouvez continuer malgré tout. Dans le " "cas contraire, il est nécessaire d'installer GRUB quelque part." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Faut-il supprimer GRUB 2 de /boot/grub ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "" "Veuillez choisir si vous voulez vraiment supprimer tous les fichiers de " "GRUB 2 de /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Cela peut rendre le système impossible à démarrer tant qu'un autre chargeur " "d'amorçage ne sera pas installé." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Faut-il terminer la migration vers GRUB 2 maintenant ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Ce système comporte encore des fichiers de la version précédente du " "programme de démarrage GRUB mais comporte également des secteurs d'amorçage " "de GRUB 2 sur les disques suivants :" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Il est très probable que la version précédente de GRUB ne soit plus utilisée " "et il est donc conseillé de mettre à jour les images de GRUB 2 sur ces " "disques, puis terminer la migration vers GRUB 2 en supprimant les anciens " "fichiers de la version précédente. Si vous ne mettez pas ces images de " "GRUB 2 à jour, elles pourraient être incompatibles avec de nouvelles " "versions, ce qui pourrait empêcher un démarrage normal." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Il est donc très probablement nécessaire de terminer la migration vers " "GRUB 2 à moins que ces secteurs d'amorçage n'aient été créés par une " "installation de GRUB 2 d'un autre système d'exploitation." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Ligne de commande de Linux :" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La ligne de commande de Linux suivante a été récupérée via le fichier /etc/" "default/grub ou le paramètre « kopt » du fichier menu.lst utilisé par la " "version originelle de GRUB. Veuillez contrôler qu'elle est correcte et la " "modifier si nécessaire. Cette ligne de commande peut être vide." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Ligne de commande par défaut de Linux :" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Les paramètres indiqués seront utilisés pour le noyau Linux de l'entrée de " "menu par défaut mais pas pour le mode de secours." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Ligne de commande de kFreeBSD :" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La ligne de commande de kFreeBSD suivante a été récupérée via le fichier /" "etc/default/grub ou le paramètre « kopt » du fichier menu.lst utilisé par la " "version originelle de GRUB. Veuillez contrôler qu'elle est correcte et la " "modifier si nécessaire. Cette ligne de commande peut être vide." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Ligne de commande par défaut de kFreeBSD :" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Les paramètres indiqués seront utilisés pour le noyau kFreeBSD de l'entrée " "de menu par défaut mais pas pour le mode de secours." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "Recréation de /boot/grub/device.map" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Le fichier /boot/grub/device.map a été réécrit afin d'utiliser des noms de " "périphériques stables. Dans la majorité des cas, cela devrait éviter d'avoir " "à le modifier dans le futur et les entrées de menu créées par GRUB ne " "devraient pas être affectées par ce changement." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Cependant, si la machine comporte plus d'un disque, il est possible que le " "démarrage dépende de l'ancien système de cartographie des périphériques " "(« device map »). Vous devriez vérifier s'il existe des entrées de menu de " "démarrage personnalisées qui se servent encore de la numérotation de disques " "de GRUB (hdN), puis les mettre à jour si nécessaire." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Si vous ne comprenez pas ces explications ou n'utilisez pas d'entrées " "personnalisées dans le menu de démarrage, vous pouvez ignorer cet " "avertissement. " #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Dans tous les cas, pour charger GRUB 2 directement depuis le secteur " #~ "d'amorçage, vous devrez utiliser la commande suivante avec les privilèges " #~ "du superutilisateur :" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Échec de l'installation de GRUB. Continuer ?" debian/po/zh_CN.po0000664000000000000000000003422112524662415011160 0ustar # Chinese translations for grub2 po-debconf # PACKAGE 软件包的简体中文翻译. # Copyright (C) 2010 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # YunQiang Su , 2010, 2011. # msgid "" msgstr "" "Project-Id-Version: grub2-po-debconf master\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-05-28 17:29+0800\n" "Last-Translator: YunQiang Su \n" "Language-Team: Chinese (simplified) \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bits\n" "Plural-Forms: nplurals=1; plural=0;\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "从 menu.lst 进行 chainload?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "GRUB 升级脚本在 /boot/grub 探测到了已安装的 GRUB Legacy。" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "为了取代您系统上的 GRUB Legacy,推荐调整 /boot/grub/menu.lst 为从现有的 GRUB " "Legacy 设置中加载 GRUB 2 引导镜像。现在可以自动执行这个操作。" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "推荐您接受从 menu.lst 中 chainload GRUB 2,并且在将 GRUB 2 直接安装到 MBR (主" "引导记录,Master Boot Record) 之前确定新的 GRUB 2 设置可以工作。" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "无论现在做什么样的决定,您以后都可以使用 root 身份来运行如下命令来使用 GRUB " "2 来代替旧的 MBR 映像:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB 安装设备:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "grub-pc 包已经升级。此菜单允许您选择在哪个设备上自动运行 grub-install,如果有" "的话。" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "在大多数情况下推荐自动运行 grub-install,以避免安装的 GRUB 核心映像与 GRUB 模" "块或 grub.cfg 不同步。" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "如果不确定 BIOS 使用哪个驱动器作为主引导,将 GRUB 安装到所有这些驱动器是一个" "不错的主意。" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "注意:也可以将 GRUB 安装到分区的引导记录,这里提供了一些适当的分区。然而,这" "强制 GRUB 使用黑名单机制,会造成可靠性降低,因此不推荐使用。" #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB 引导器先前安装到了一个消失了的磁盘上,或者它的唯一标识符由于某些原因变化" "了。确保安装的 GRUB 核心映像和 GRUB 模块及 grub.cfg 的同步非常重要。请再次检" "查以确保 GRUB 安装到了适当的引导设备。" #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "将 GRUB 写入引导设备失败 - 要继续吗?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB 安装到如下设备时失败。" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "仍然想要继续?如果这样,您的计算机可能不能正常启动。" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "将 GRUB 写入引导设备失败 - 要重新尝试吗?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "您可能可以安装 GRUB 到其它设备,尽管您需要明确,您的系统将从那个设备启动。否" "则,从 GRUB Legacy 的升级将被取消。" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "不安装 GRUB 并且继续?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "您没有选择向任何设备安装 GRUB。如果继续,引导器可能不能正确配置,当您的计算机" "下次启动时,它将使用引导扇区中先前的内容。如果引导扇区中有早期版本的 GRUB 2," "其可能不能加载模块或者处理当前配置文件。" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "如果您已经使用了另外一个引导器并且想继续这样做,或者如果这是一个特殊的不需要" "引导器的环境,这样您可以仍然继续。否则,您应该在某处安装 GRUB。" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "从 /boot/grub 移除 GRUB 2 ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "确定想从 /boot/grub 移除全部 GRUB 2 文件吗?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "这会使系统不能引导,除非另外安装其它引导器。" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "现在完成到 GRUB 2 的转换?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "此系统仍然有 GRUB Legacy 引导器安装的文件,但是现在也在磁盘上安装了 GRUB 2 引" "导记录:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "好像 GRUB Legacy 已经不再使用了,并且您应该在这些磁盘上转而升级到 GRUB 2 映" "像,并且通过删除旧的 GRUB Legacy 文件来完成到 GRUB 2 的转换。如果不升级这些 " "GRUB 2 映像,他们将可能不能与新包兼容而造成您的系统不能正常引导。" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "您通常应该完成到 GRUB 2 的转换,除非这些引导记录是由安装到其它操作系统上的 " "GRUB 2 创建的。" #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux 命令行:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "已从 /etc/default/grub 或 GRUB Legacy 的 menu.lst 中的 `kopt' 参数中提取如下 " "Linux 命令行。请检查是否正确的,并且根据需要进行修改。此命令行可以为空。" #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linux 默认命令行:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "如下字符串将被用于默认菜单项的 Linux 参数,但是不会用于恢复模式。" #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD 参数:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "已从 /etc/default/grub 或者 GRUB Legacy 的 menu.lst 中的 `kopt' 参数中提取如" "下 kFreeBSD 命令行参数。请请检查是否正确,并且根据需要进行修改。此命令行可以" "为空。" #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "kFreeBSD 默认命令行:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "如下字符串将用于默认菜单项的 kFreeBSD 参数,但不会用于恢复模式。" #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map 已经生成" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "文件 /boot/grub/device.map 已经重写以使用稳定的设备名。多数情况下,这应该显著" "地减少以后修改它的需要,并且 GRUB 产生的引导菜单项不会受影响。" #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "然而,因为您的系统上有多个磁盘,系统可能依赖旧的设备映射。请检查您是否有任何" "自定义的依赖 GRUB 的 (hdN) 驱动器号的引导菜单项,如果需要请更新它们。" #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "如果您不理解此消息,或者没有任何自定义的引导菜单项,您可以忽略此消息。" #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "无论何种情况,当您想直接从 MBR 加载 GRUB 2 时,您可以通过以 root 身份执行" #~ "如下命令来实现:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "GRUB 安装失败。仍然继续?" debian/po/ka.po0000664000000000000000000003364212524662415010560 0ustar # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2009-08-30 18:05+0400\n" "Last-Translator: Aiet Kolkhi \n" "Language-Team: Georgian \n" "Language: ka\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: georgian\n" "X-Poedit-Country: GEORGIA\n" "X-Poedit-SourceCharset: utf-8\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "გსურთ Chainload ჩატვირთვა menu.lst-დან?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "GRUB-ის განახლების სკრიფტები GRUB-ის ძველ ინსტალაციას გადააწყდა /boot/grub " "მდებარეობაში." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 #, fuzzy #| msgid "" #| "In order to replace the Legacy version of GRUB in your system, it is " #| "recommended that /boot/grub/menu.lst is adjusted to chainload GRUB 2 from " #| "your existing GRUB Legacy setup. This step may be automaticaly performed " #| "now." msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "იმისათვის, რომ თქვენს სისტემაზე ჩანაცვლდეს ძველი GRUB-ის ინსტალაცია, " "სასურველია /boot/grub/menu.lst ჩასწორდეს, რომ შეასრულოს GRUB 2-ის chainload " "ჩატვირთვა თქვენი არსებული GRUB-ის ძველი ინსტალაციიდან. ეს საფეხური " "შესაძლებელია ახლა შესრულდეს ავტომატურად." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 #, fuzzy #| msgid "" #| "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " #| "verify that your new GRUB 2 setup is functional for you, before you " #| "install it directly to your MBR (Master Boot Record)." msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "სასურველია მიიღოთ menu.lst-დან GRUB 2-ის chainload მეთოდით ჩატვირთვა, ასევე " "გადაამოწმოთ, რომ თქვენი ახალი GRUB 2-ის ინსტალაცია ფუნქციონირებდეს, სანამ " "მას პირდაპირ Master Boot Record (MBR)-ში ჩაწერდეთ." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "ლინუქსის ბრძანების სტრიქონი:" #. Type: string #. Description #: ../templates.in:1001 #, fuzzy #| msgid "" #| "The following Linux command line was extracted from /etc/default/grub or " #| "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " #| "correct, and modify it if necessary." msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "ლინუქსის შემდეგი ბრძანება მოძიებულ იქნა /etc/default/grub-დან ან `kopt' " "პარამეტრიდან ძველი GRUB-ის menu.lst-ში. გადაამოწმეთ, რომ იგი სწორია, ან " "შეცვალეთ შესაბამისად." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "ლინუქსის სტანდარტული ბრძანების სტრიქონი:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "შემდეგი სტრიქონი გამოყენებულ იქნება როგორც ლინუქსის პარამეტრები მენიუს " "სტანდარტული შენატანისათვის, მაგრამ არა აღდგენის რეჟიმისათვის." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD ბრძანების სტრიქონი:" #. Type: string #. Description #: ../templates.in:3001 #, fuzzy #| msgid "" #| "The following kFreeBSD command line was extracted from /etc/default/grub " #| "or the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it " #| "is correct, and modify it if necessary." msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "შემდეგი kFreeBSD-ის ბრძანების სტრიქონი ამოღებულ იქნა /etc/default/grub-დან " "ან `kopt' პარამეტრიდან ძველი GRUB-ის menu.lst-ში. გადაამოწმეთ, რომ იგი " "სწორია, ან შეცვალეთ შესაბამისად." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "kFreeBSD-ის სტანდარტული ბრძანების სტრიქონი:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "შემდეგი სტრიქონი გამოყენებულ იქნება როგორც kFreeBSD-ს პარამეტრები მენიუს " "სტანდარტული შენატანისათვის, მაგრამ არა აღდგენის რეჟიმისათვის." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "ნებისმიერ შემთხვევაში, როდესაც მოისურვებთ GRUB 2 პირდაპირ MBR-დან " #~ "ჩაიტვირთოს, ამისათვის გაუშვით შემდეგი ბრძანება (root პრივილეგიებით):" debian/po/da.po0000664000000000000000000003703112524662415010545 0ustar # Danish translation grub2. # Copyright (C) 2011 grub2 & nedenstående oversættere. # This file is distributed under the same license as the grub2 package. # Joe Hansen , 2010, 2011. # Korrekturlæst Kenneth Nielsen, Keld Jørn Simonsen, Torben Grøn Helligsø. # # Chain loading -> Chain loading is a method used by computer programs # to replace the currently executing program with a new program, # using a common data area (a so-called core common area) to pass # information from the current program to the new program. It occurs # in several areas of computing. Et dansk navn? # man kunne måske med nogen rimelighed kalde det for kædeindlæsning, men # egentlig er det her jo et af de ord som jeg ikke mener at behøver at # oversætte. Dem der har brug for at vide hvad det er, kender kun det # engelsk ord og det danske vil måske endda forvirre mere end det vil # gøre gavn. I hvert fald, hvis du vil oversætte vil jeg anbefale at # sætte chainloade i parentes der hvor du kan. Beholdt uoversat. # msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-05-28 17:30+01:00\n" "Last-Translator: Joe Hansen \n" "Language-Team: Danish \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Chainload fra menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Opgraderingsskripterne til GRUB har fundet en GRUB Legacy-opsætning i /boot/" "grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "For at erstatte GRUB-versionen Legacy på dit system, anbefales det at /boot/" "grub/menu.lst justeres til at indlæse GRUB 2's opstartsaftryk fra din " "eksisterende GRUB Legacy-opsætning. Dette trin kan udføres automatisk nu." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Det anbefales, at du accepterer at chainloade GRUB 2 fra menu.lst, og " "verificerer at din nye GRUB 2-opsætning virker for dig, før du installerer " "den direkte til din MBR (Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Uanset din beslutning kan du senere erstatte dit gamle MBR-aftryk med GRUB 2 " "ved at foretage den følgende kommando som administrator (root):" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUBs installationsenheder:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Pakken grub-pc bliver opgraderet. Denne menu tillader dig at vælge, hvilke " "enheder om nogen, du vil have at grub-install automatisk skal køres for." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Automatisk kørsel af grub-install anbefales i de fleste situationer, for at " "forhindre at det installerede GRUB-kerneaftryk kommer ud af synkronisering " "med GRUB-moduler eller grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Hvis du er usikker på hvilket drev, der er bestemt som opstartsdrev af din " "BIOS, er det ofte en god ide at installere GRUB på dem alle." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Bemærk: Det er også muligt at installere GRUB til partitioners " "opstartspunkter, og nogle egnede partitioner tilbydes her. Dette tvinger dog " "GRUB til at bruge blokeringslistemekanismen, som gør den mindre pålidelig, " "og dette anbefales derfor ikke." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB-opstartsindlæseren blev tidligere installeret til en disk, som ikke " "længere er tilgængelig, eller hvis unikke identifikation er blevet ændret. " "Det er vigtigt at sikre sig, at det installerede GRUB-kerneaftryk forbliver " "i synkronisering med GRUB-moduler og grub-cfg. Kontroller venligst en ekstra " "gang så du er sikker på, at GRUB skrives til de relevante opstartsenheder." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Skrivning af GRUB til opstartsenhed fejlede - vil du fortsætte?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Kunne ikke installere GRUB på de følgende enheder:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Ønsker du at fortsætte alligevel? Hvis du fortsætter, kan din computer måske " "ikke starte korrekt op." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Skrivning af GRUB til opstartsenhed fejlede - forsøg igen?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Du kan måske installere GRUB til en anden enhed, selvom du skal tjekke at " "dit system kan/vil opstarte fra denne enhed. Ellers vil opgraderingen fra " "GRUB Legacy blive afbrudt." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Fortsæt uden at installere GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Du har valgt ikke at installere GRUB på nogen enhed. Hvis du fortsætter, vil " "opstarteren (boot loader) måske ikke være korrekt konfigureret, og når din " "computer starter op næste gang, vil den bruge det tidligere indhold i din " "opstartssektor (boot sector). Hvis der er en tidligere version af GRUB 2 i " "opstartsektoren, vil den måske ikke være i stand til at indlæse moduler " "eller håndtere den aktuelle konfigurationsfil." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Hvis du allerede kører en anden opstarter (boot loader) og ønsker at " "fortsætte sådan, eller hvis dette er et specielt miljø, hvor du ikke har " "brug for en opstarter, så skal du fortsætte alligevel. Ellers skal du " "installere GRUB et eller andet sted." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Fjern GRUB 2 fra /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Ønsker du at alle GRUB 2-filer skal fjernes fra /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Dette vil medføre, at systemet ikke kan opstartes med mindre en anden " "opstarter (boot loader) er installeret." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Afslut konvertering til GRUB 2 nu?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Dette system har stadig filer fra GRUB Legacy-opstarteren installeret, men " "systemet har nu også GRUB 2 opstartsposter installeret på disse diske:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Det virker sandsynligt at GRUB Legacy ikke længere er i brug, og at du i " "steden fir skal opgradere GRUB 2-billederne på disse diske og afslutte " "konverteringen til GRUB 2 ved af fjerne ældre GRUB Legacy-filer. Hvis du " "ikke opgraderer disse GRUB 2-billeder, så er de måske ikke kompatible med de " "nye pakker og får dit system til at holde op med at starte korrekt op." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Du bør generelt afslutte konverteringen til GRUB 2 medmindre disse " "opstartsposter blev oprettet af en GRUB 2-installation på et andet " "operativsystem." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Kommandolinje til Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Den følgende kommandolinje i Linux blev udtrukket fra /etc/default/grub " "eller parameteren `kopt' i GRUB Legacys menu.lst. Verificer venligst at den " "er korrekt, og ændre den om nødvendigt. Kommandolinjen må være tom." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Standardkommandolinje i Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Den følgende streng vil blive brugt som Linuxparametre for " "standardmenupunktet men ikke for gendannelsestilstanden." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Kommandolinje for kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Den følgende kommandolinje i kFreeBSD blev udtrukket fra /etc/default/grub " "eller fra parameteren `kopt' i GRUB Legacys menu.lst. Verificer venligst at " "den er korrekt, og ændre den om nødvendigt. Kommandolinjen må være tom." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Standardkommandolinje i kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Den følgende streng vil blive brugt som kFreeBSD-parametre for " "standardmenupunktet men ikke for gendannelsestilstanden." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map er blevet gendannet" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Filen /boot/grub/device.map er blevet genskrevet til at bruge stabile " "enhedsnavne. I de fleste tilfælde vil dette markant reducere behovet for at " "ændre filen fremover, og opstartsmenupunkter oprettet af GRUB vil ikke blive " "påvirket." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Da du har mere end en disk i dit sytem, er det dog muligt, at du har en " "afhængighed af det gamle enhedskort. Tjek venligst om der er nogle " "tilpassede opstartsmenupunkter som afhænger af GRUB's (hdn) drevnummerering, " "og opdater dem om nødvendigt." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Hvis du ikke forstår denne besked, eller der ikke er nogen tilpassede " "opstartsmenupunkter, kan du ignorere denne besked." debian/po/si.po0000664000000000000000000004734412524662415010604 0ustar # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Danishka Navin , 2011. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-09-29 08:35+0530\n" "Last-Translator: Danishka Navin \n" "Language-Team: Sinhala \n" "Language: si\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.2\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "menu.lst චක්‍ර පූර්ණය" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "GRUB යාවත් විධානාවලි පැරණි GRUB සැකසුමක් /boot/grub හි සොයාගෙන ඇත." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "ඔබේ පද්ධතියේ පවතින GRUB සංස්කරණය ප්‍රතිපිහිටුවීමට. /boot/grub/menu.lst පවතින GRUB ස්ථාපනය " "මගින් GRUB 2 ආරම්භක පිළිබිඹුවක් පූර්ණය කිරීමට සැකසීම නිර්දේශිතයි.\n" "මෙම ස්ථාපනය දැන් ස්වයංක්‍රීයව ඉටුකල හැක." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "menu.lst වෙතින් GRUB 2 දාමපූර්ණය පිළිගැනීම නිර්දේශිතයි. එමෙන්ම එය MBR (ප්‍රධාන ආරම්භක සටහන) " "වෙත ලිවීමට පෙර GRUB 2 ස්ථාපනය ක්‍රියාකරයි දැයි පිරික්සන්න." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "ඔබේ තීරණය කුමක් වුවත් ඔබට අග්‍රය ලෙස පහත විධානය නිකුත් කිරීමෙන් GRUB 2 සමඟ පැරණි MBR " "ප්‍රථිපිහිටුවිය හැක." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB ස්ථාපන උපකරණ:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "grub-pc පැකේජය යාවත් වෙමින්. මෙම මෙනුව ඔබට grub-install ස්වයංක්‍රීයව ධාවනය විය යුත්තේ " "කුමන උපකරණ මත දැයි තේරීමට ඉඩදෙයි." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "බොහෝ අවස්ථා වලදී grub-install ස්වයංක්‍රීයව ධාවනය කිරීම නිර්දේශිතයි. GRUB මොඩියුල හෝ grub." "cfg මගින් ස්ථාපිත GRUB මූල පිළිබිඹුව සම්මුහුර්තයෙන් බැහැර යාම වලක්වයි." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "ඔබට ඔබේ BIOS මගින් සඳහන් කර ඇති ආරම්භක ධාවකය කුමක් දැයි විශ්වාස නොමැති නම්. සියල්ලේම GRUB " "පිහිටුවීම හොඳ අදහසකි." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "සටහන: GRUB කොටස් ආරම්භක වාර්ථා තුළද පිහිටුවිය හැක. එමෙන්ම ඇතැම් සුදුසු කොටස් මෙහිදී පිරිනැමේ. " "කෙසේවුවත්, මෙය GRUB වෙත වැලකුම් ලැයිස්තු ක්‍රියාවලිය සිදුකිරිමට බල කරයි. එය වඩා අස්ථිර බැවින් " "නිර්දේශ නොකෙරේ." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB ආරම්භක පූරකය දැනට නොපවතින තැටියට ස්ථාපනය කර තිබී ඇත. හෝ එහි අනන්‍ය හැඳින්වීම කිසියම් " "හේතුවක් නිසා වෙනස් වී ඇත. ස්ථාපිත GRUB මූල පිළිබිඹුව GRUB මොඩියුල හා grub.cfg සමඟ සම්මුහුර්ත " "බව තහවුරු කරගැනීම වැදගත්වේ. කරුණාකර සුදුසු ආරම්භක උපකරණයන් හි GRUB ලියැවී ඇතිදැයි නැවත " "පිරික්සන්න." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "GRUB ආරම්භක උපකරණය ලිවීම අසාර්ථකයි - ඉදිරියට?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB පහත උපකරණ ස්ථාපනයෙහි අසාර්ථක විය:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "ඔබට කෙසේ හෝ ඉදිරියට යෑමට ඇවැසිද? එසේ නම් ඔබේ පරිගණකය නිසිපරිදි ආරම්භ නොවනු ඇත." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "GRUB ආරම්භක උපකරණය ලිවීම අසාර්ථකයි - නැවත උත්සාහ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "ඔබට GRUB වෙනත් උපකරණයක ස්ථාපනය කල හැක. ඒ අතර ඔබේ පද්ධතිය එම උපකරණය මගින් ආරම්භ " "වේදැයි සොයාබලන්න. එසේ නොමැති නම් පැරණි GRUB වෙතින් යාවත් වීම අවලංගු වේ." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "GRUB ස්ථාපනයෙන් තොරව ඉදිරියට යන්නද?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "ඔබ කිසිඳු උපකරණයකට GRUB ස්ථාපනය නොකිරීමට තෝරා ඇත. ඔබ ඉදිරියට යයි නම් ආරම්භක පූරකය නිසිලෙස " "නොසැකසෙනු ඇත. ඊලඟ වතාවේ පරිගණකය ආරම්භ වන විට එය ආරම්භක කොටසේ පැවති ඕනෑම දෙයක් භාවිත " "කරයි. ආරම්භක කොටසේ GRUB 2 පැරණි සංස්කරණයක් පවතී නම්. එය මොඩියුල හැසිරවීමේ හා වත්මන් සැකසුම් " "ගොනුව භාවිතයේ අසමත් විය හැක." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "ඔබ දැනටමත් වෙනස් ආරම්භක පූරකයක් භාවිත කරයි නම් හා එය දිගටම භාවිත කිරීමට ඇවැසි නම්. හෝ මෙය " "ආරම්භක පූරකයක් ඇවැසි නොවන විශේෂිත පරිසරයක් නම්. ඔබට කෙසේ හෝ ඉදිරියට යා හැක. එසේ නොවේ " "නම්, ඔබට කොතැනක හෝ GRUB ස්ථාපනයට සිදුවේ." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr " /boot/grub වෙතින් GRUB 2 ඉවත් කරන්නද?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "ඔබට /boot/grub වෙතින් සියළු GRUB 2 ගොනු ඉවත් කිරිමට ඇවැසිද?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "මෙය වෙනත් ආරම්භක පූරකයක් ස්ථාපනය කරන තුරු පද්ධතිය ආරම්භ කල නොහැකි කරයි." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "GRUB 2 වෙත හැරවීම අවසන් කරන්නද?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "තවමත් මෙම පද්ධතිය සතුව පැරණි GRUB ආරම්භක පූරකය ස්ථාපිතව පවතී. නමුත් පහත තැටි තුළ දැනට GRUB " "2 ආරම්භක වාර්ථා ස්ථාපිතව ඇත." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "පැරණි GRUB භාවිතයේ නොපවතින ලෙසක් දිස්වේ. එනම් ඔබට එම තැටි වල GRUB 2 පිළිබිඹු යාවත් කිරීමට " "හා GRUB 2 වෙත හැරවීම සම්පූර්ණ කිරීමට පැරණි GRUB ගොනු ඉවත්කිරීමට සිදුවන බවයි. ඒවා නව පැකේජ " "සමඟ සහාය නොදක්වනු ඇති අතර ඔබේ පද්ධතිය නිසිලෙස ආරම්භ නොවනු ඇත." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "GRUB 2 ස්ථාපනය මගින් වෙනත් මෙහෙයුම් පද්ධතියක් මත මෙම ආරම්භක වාර්ථා නිර්මාණය කර නොමැති නම්, " "ඔබ සාමාන්‍යෙන් GRUB 2 වෙත හැරවීම අවසන් කල යුතුයි." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux විධාන රේඛාව:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "පහත Linux විධානය /etc/default/grub හෝ පැරණි GRUB හි menu.lst හි 'kopt' පරාමිතියෙන් " "උපුටාගන්නා ලදී. කරුණාකර එය නිවැරදි දැයි තහවුරු කරන්න, ඇවැසිනම් වෙනස්කම් කරන්න. විධාන රේඛාව " "හිස්ව පැවතීමට ඉඩදෙයි. " #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "පෙරනිමි Linux විධාන රේඛාව:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "පහත යෙදුම පෙරනිමි මෙනු ඇතුළත් කිරීම් සඳහා Linux පරාමිතියක් ලෙස භාවිත වන නමුත් ගැලවීම් ප්‍රකාරයට " "නොවේ." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD විධාන රේඛාව:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "පහත kFreeBSD විධානය /etc/default/grub හෝ පැරණි GRUB හි menu.lst හි 'kopt' " "පරාමිතියෙන් උපුටාගන්නා ලදී. කරුණාකර එය නිවැරදි දැයි තහවුරු කරන්න, ඇවැසිනම් වෙනස්කම් කරන්න. " "විධාන රේඛාව හිස්ව පැවතීමට ඉඩදෙයි. " #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "kFreeBSD පෙරනිමි විධාන රේඛාව:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "පහත යෙදුම පෙරනිමි මෙනු ඇතුළත් කිරීම් සඳහා kFreeBSD පරාමිතියක් ලෙස භාවිත වන නමුත් ගැලවීම් " "ප්‍රකාරයට නොවේ." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map නැවත ජනනය වී ඇත" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "ස්ථාවර උපකරණ නාම භාවිතය සඳහා /boot/grub/device.map නැවත ලියවිනි. බොහෝ අවස්ථාවල, " "මෙය ඉදිරියේදී වෙනස් කිරීමට ඇවැසි නොවේ, තවද GRUB මගින් ජනිත ආරම්භක මෙනු ඇතුළත් කිරීම් වෙනස් " "නොකල යුතුයි." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "කෙසේ වුවත් පද්ධතියේ තැටි එකකට වඩා පවතින බැවින්, පද්ධතිය පැරණි උපකරණ සිතියමක් මත රඳාපවතිනවා " "විය හැක. කරුණාකර GRUB හි (hdN) ධාවක අංකකරණය මත රඳාපවතින රුචි ආරම්භක මෙනු ඇතුළත් කිරීම් " "පවතීදැයි සොයන්න. ඇවැසිනම් ඒවා යාවත් කරන්න." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "මෙම පණිවුඩය ඔබට තේරුම්ගත නොහැකි නම් හෝ, කිසිඳු රුචි ආරම්භක මෙනු ඇතුළත්කිරිමක් නොමැති නම් ඔබට මෙම " "පණිවුඩය මඟහැරිය හැක." debian/po/mr.po0000664000000000000000000005360612524662415010605 0ustar # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-05-13 23:06+0530\n" "Last-Translator: sampada \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "menu.lst मधून चेनलोड करायचे?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "ग्रब श्रेणीवर्धन स्क्रिप्ट्सना /boot/grub येथे ग्रब लिगसी संरचना आढळली आहे." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "तुमच्या प्रणालीतील ग्रबची लिगसी आवृत्ती बदलण्यासाठी अशी शिफारस केली जाते की तुमच्या " "अस्तित्वातील ग्रब लिगसी संरचनेमधून /boot/grub/menu.lst हा ग्रब 2 आरंभ प्रतिमा लोड " "करण्यासाठी बदलण्यात यावा. ही पायरी आता स्वयंचलितपणे करता येऊ शकते." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "अशी शिफारस आहे, की तुम्ही menu.lst मधून ग्रब 2 चेनलोड करायचे स्वीकारावे, व एमबीआर " "(मुख्य आरंभ अभिलेख) यानुसार लिहिला जाण्यापूर्वी नवीन ग्रब 2 संरचना कार्य करत आहे याची " "खातरजमा करावी." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "तुमचा निर्णय काहीही असला तरी, तुम्ही नंतर मूल म्हणून खालील आज्ञा देऊन जुनी एमबीआर " "प्रतिमा ग्रब 2 ने बदलू शकता:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "ग्रब अधिष्ठापना उपकरणे:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "ग्रब-पीसी पॅकेज श्रेणिवर्धित केले जात आहे. कोणत्या उपकरणांसाठी ग्रब-इन्स्टाल स्वयंचलितपणे " "चालवले जावे ते या मेन्यूद्वारे तुम्ही निवडू शकता." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "ग्रब गाभा प्रतिमेच्या ग्रब मोड्यूल्स वा grub.cfg शी विसंवादाला आळा बसण्यासाठी बहुतांश " "परिस्थितींमध्ये ग्रब-इन्स्टाल स्वयंचलितपणे चालवले जाण्याची शिफारस केली जाते" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "तुमच्या बायोसने कोणता ड्राईव्ह आरंभ ड्राईव्ह म्हणून ठरवला आहे याची तुम्हाला खात्री नसल्यास, " "ग्रब सर्वच ड्राईव्ह्जवर अधिष्ठापित करणे बहुतेकदा चांगले ठरते." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "नोंद: विभाजन आरंभ नोंदींमध्येही ग्रब अधिष्ठापित करणे शक्य आहे, व यासाठी काही सुयोग्य " "विभाजने येथे दर्शवली आहेत. तथापि, यामुळे ग्रबला ब्लॉकलिस्ट यंत्रणा वापरणे भाग पडते, ज्यामुळे " "त्याची विश्वासार्हता कमी होते व म्हणून याची शिफारस केली जात नाही." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "ग्रब आरंभ सूचक पूर्वी ज्या डिस्कवर अधिष्ठापित केला होता ती आता अस्तित्वात नाही, वा काही " "कारणास्तव तिचे विशिष्ट ओळखचिन्ह बदलले गेले आहे. अधिष्ठापित केलेली ग्रब गाभा प्रतिमा ग्रब " "मोड्यूल्स व grub.cfg यांच्याशी सुसंवादी राहणे महत्वाचे आहे. कृपया ग्रब सुयोग्य आरंभ उपकरणांवर " "लिहिला जात आहे याची पुन्हा खातरजमा करा." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} एमबी; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} एमबी; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "आरंभ उपकरणावर ग्रब लिहिणे फसले - सुरू ठेवायचे?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "खालील उपकरणांवर ग्रब अधिष्ठापित करणे असफल झाले:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "तुम्हाला तरीही पुढे जायचेय? असे केल्यास, तुमचा संगणक कदाचित व्यवस्थित सुरू होऊ शकणार नाही." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "आरंभ उपकरणावर ग्रब लिहिणे फसले - पुन्हा प्रयत्न करायचा?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "तुम्ही ग्रब अन्य कोणत्याही उपकरणावर अधिष्ठापित करू शकता, पण त्या उपकरणावरून तुमची " "प्रणाली आरंभ करू शकते याची खातरजमा तुम्ही केली पाहिजे. अन्यथा, लीगसी ग्रबचे श्रेणिवर्धन " "रद्द केले जाईल." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "ग्रब अधिष्ठापित न करता पुढे जायचे?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "कोणत्याही उपकरणांवर ग्रब अधिष्ठापित न करण्याचे तुम्ही निवडले आहे. तुम्ही पुढे चालू ठेवल्यास, " "हा आरंभ सूचक योग्यरित्या संरचित झालेला नसू शकतो, व हा संगणक पुन्हा सुरू होईल तेव्हा बूट " "सेक्टरमध्ये आधी जे काही होते ते वापरेल. बूट सेक्टरमध्ये ग्रब 2 ची आधीची आवृत्ती असेल, तर " "कदाचित तो मोड्युल्स लोड करू शकणार नाही वा सद्य संरचना फाईल हाताळू शकणार नाही.\t" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "तुम्ही आधीच अन्य आरंभ सूचक वापरत असाल व तोच वापरणे सुरू ठेऊ इच्छित असाल, वा तुम्हाला आरंभ " "सूचकाची गरज पडणार नाही असा हा विशेष आसमंत असेल, तर तुम्ही तसेच पुढे चालू ठेवावे. अन्यथा, " "तुम्ही कोठेतरी ग्रब अधिष्ठापित केला पाहिजे." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "/boot/grub मधून ग्रब 2 काढून टाकायचा?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "/boot/grub मधून ग्रब 2 च्या सर्व फायली तुम्ही काढून टाकू इच्छिता?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "अन्य आरंभ सूचक अधिष्ठापित न केल्यास यामुळे तुमची प्रणाली आरंभ न होण्याजोगी होईल." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "ग्रब 2 मध्ये परिवर्तन आता थांबवायचे?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "प्रणालीमध्ये अद्यापही लीगसी ग्रब आरंभ सूचक अधिष्ठापनेतील फायली आहेत, पण तिच्यात आता " "खालील डिस्क्सवर ग्रब 2 आरंभ नोंदीही अधिष्ठापित आहेत:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "ग्रब लीगसी आता वापरात नसण्याचा संभव आहे असे भासतेय, आणि या डिस्कवर तुम्ही त्याऐवजी ग्रब " "2 प्रतिमा श्रेणिवर्धित केल्या पाहिजेत व ग्रब लीगसी फायली काढून टाकून ग्रब 2 मघ्ये परिवर्तन " "पूर्ण केले पाहिजे. तुम्ही या ग्रब 2 प्रतिमा श्रेणिवर्धित केल्या नाहीत, तर त्या नवीन पॅकेजेसशी " "अनुरूप असणार नाहीत व तुमच्या प्रणालीचा योग्य आरंभ होण्यात अडथळा आणू शकतील." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "या आरंभ नोंदी अन्य कोणत्यातरी प्रचालन प्रणालीवर ग्रब 2 अधिष्ठापनेने निर्माण केलेल्या " "नसल्यास तुम्ही सामान्यतः ग्रब 2 मघ्ये परिवर्तन पूर्ण केले पाहिजे." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "लिनक्स आदेश ओळ:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "पुढील लिनक्स आदेश ओळ /etc/default/grub ग्रब लीगसीच्या menu.lst मधील `kopt' " "घटकमूल्यामधून मिळवली आहे. कृपया ती योग्य आहे का, याची खातरजमा करा व आवश्यकता असल्यास " "बदल करा. आदेश ओळ रिकामी ठेवण्याची अनुमती असते." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "लिनक्स मूलनिर्धारीत आदेश ओळ:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "मुलनिर्धारित मेन्यू नोंदीकरिता लिनक्स घटकमूल्ये म्हणून खालील श्रुंखला वापरली जाईल, पण " "रिकव्हरी मोडसाठी नाही." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "केफ्रीबीएसडी आदेश ओळ:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "पुढील केफ्रीबीएसडी आदेश ओळ /etc/default/grub ग्रब लीगसीच्या menu.lst मधील `kopt' " "घटकमूल्यामधून मिळवली आहे. कृपया ती योग्य आहे का, याची खातरजमा करा व आवश्यकता असल्यास " "बदल करा. आदेश ओळ रिकामी ठेवण्याची अनुमती असते." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "केफ्रीबीएसडी मूलनिर्धारीत आदेश ओळ:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "मुलनिर्धारित मेन्यू नोंदीकरिता केफ्रीबीएसडी घटकमूल्ये म्हणून खालील श्रुंखला वापरली जाईल, पण " "रिकव्हरी मोडसाठी नाही." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map पुनर्निर्मिला गेला आहे" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "फाईल /boot/grub/device.map स्थीर उपकरण नावे वापरण्यासाठी पुन्हा लिहिली गेली आहे. " "बहुतांश बाबतील, यामुळे तीत भविष्यात बदल करण्याची गरज लक्षणीयरित्या कमी झाली पाहिजे, व " "ग्रबने निर्माण केलेल्या आरंभ मेन्यू नोंदींवर परिणाम होता कामा नये." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "तथापि, प्रणालीमध्ये एकाहून अधिक डिस्क अस्तित्वात असल्याने, प्रणाली जुन्या उपकरण नकाशावर " "अवलंबून असणे शक्य आहे. ग्रबच्या (hdN) ड्राईव्ह क्रमांकांवर विसंबणार्‍या एखाद्या आरंभ मेन्यू नोंदी " "आहेत का हे कृपया तपासा, व आवश्यकता भासल्यास त्या अद्ययावत " #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "तुम्हाला या संदेशाचा अर्थ समजत नसेल, वा अशा आरंभ मेन्यू नोंदी नसतील, तर तुम्ही या संदेशाकडे " "दुर्लक्ष करू शकता." debian/po/it.po0000664000000000000000000003627212524662415010603 0ustar # Italian (it) translation of debconf templates for grub2 # This file is distributed under the same license as the grub2 package. # Luca Monducci , 2007-2012. # msgid "" msgstr "" "Project-Id-Version: grub2 1.99-14 italian debconf templates\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-01-02 21:52+0100\n" "Last-Translator: Luca Monducci \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Effettuare il caricamento in cascata da menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Gli script di aggiornamento hanno rilevato una installazione di GRUB Legacy " "in /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Per sostituire la versione Legacy di GRUB sul proprio sistema si raccomanda " "di modificare il file /boot/grub/menu.lst in modo da caricare l'immagine di " "avvio di GRUB 2 dall'attuale installazione di GRUB Legacy. Questa modifica " "può essere effettuata automaticamente adesso." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Si raccomanda di accettare il caricamento in cascata di GRUB 2 da menu.lst e " "di verificare che la nuova installazione di GRUB 2 funzioni prima di " "procedere con l'installazione diretta sul MBR (Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Qualsiasi sia la decisione, in seguito sarà possibile sostituire la vecchia " "immagine sul MBR con GRUB 2 eseguendo da root il seguente comando:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Installare GRUB sui device:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "È in corso l'aggiornamento del pacchetto grub-pc. Questo menu permette di " "scegliere su quali device, se specificati, si vuole eseguire automaticamente " "grub-install." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Nella maggioranza dei casi si raccomanda l'esecuzione automatica di grub-" "install in modo da prevenire la perdita di sincronia dell'immagine " "principale di GRUB con i moduli di GRUB o con grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Se non si è sicuri di quale sia il disco impostato come disco di avvio nel " "BIOS, è consigliabile installare GRUB su tutti i device." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Nota: è possibile installare GRUB anche nei boot record delle partizioni e " "qui sono elencate le partizioni più appropriate. Purtroppo questo obbliga " "GRUB a usare il meccanismo del \"blocklist\", che lo rende meno affidabile e " "di conseguenza non è raccomandato." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "In precedenza il boot loader GRUB era installato su un disco non più " "presente o che per qualche motivo ha cambiato identificatore univoco. È " "importante assicurare che l'immagine principale di GRUB rimanga in sincronia " "con i moduli di GRUB e con grub.cfg. Controllare nuovamente per essere " "sicuri che GRUB sia scritto sui corretti device di avvio." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Scrittura di GRUB sul device di avvio non riuscita. Continuare?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "L'installazione di GRUB sui seguenti device non è riuscita:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Si vuole continuare? Continuando, il computer potrebbe non avviarsi più " "correttamente." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Scrittura di GRUB sul device di avvio non riuscita. Riprovare?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "È possibile installare GRUB su un altro device, dopo aver verificato che il " "proprio sistema si possa avviare da quel device. Altrimenti, l'aggiornamento " "da GRUB Legacy verrà annullato." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Continuare senza installare GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Si è scelto di non installare GRUB su alcun device. Continuando, il boot " "loader potrebbe non essere configurato correttamente e al prossimo avvio del " "computer verrà usato il vecchio contenuto del settore di boot. Se nel " "settore di boot è presente una versione precedente di GRUB 2, questa " "potrebbe non essere in grado di caricare i moduli o di gestire l'attuale " "file di configurazione." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Continuare solo se già si usa un boot loader diverso oppure se non si ha " "necessità di un boot loader per questa macchina. Altrimenti è necessario " "installare GRUB da qualche parte." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Rimuovere GRUB 2 da /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Rimuovere tutti i file di GRUB 2 da /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Questo potrebbe rendere il sistema non avviabile a meno che non sia " "installato un altro boot loader." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Completare la conversione a GRUB 2 adesso?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Su questo sistema sono ancora presenti i file del boot loader GRUB Legacy ma " "adesso sui seguenti dischi sono installati anche i boot record di GRUB 2:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Sembra che GRUB Legacy non sia più usato, per cui è consigliabile aggiornare " "le immagini sui dischi con GRUB 2 e completare la conversione a GRUB 2 " "eliminando i vecchi file di GRUB Legacy. Se non si aggiornano le immagini " "con GRUB 2, in futuro potrebbero non essere più compatibili con i nuovi " "pacchetti e potrebbero impedire il corretto avvio del sistema." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Si dovrebbe completare la conversione a GRUB 2 a meno che i boot record non " "siano stati creati da un'altra installazione di GRUB 2 su un altro sistema " "operativo." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Riga di comando Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La seguente riga di comando Linux è stata estratta da /etc/default/grub " "oppure dal parametro \"kopt\" presente nel file menu.lst di GRUB Legacy. " "Controllare che sia corretta e modificarla se necessario. La riga di comando " "può essere vuota." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Riga di comando Linux predefinita:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Questa stringa verrà usata come parametri per Linux nella voce di menu " "predefinita, ma non nella modalità di ripristino." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Riga di comando kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La seguente riga di comando kFreeBSD è stata estratta da /etc/default/grub " "oppure dal parametro \"kopt\" presente nel file menu.lst di GRUB Legacy. " "Controllare che sia corretta e modificarla se necessario. La riga di comando " "può essere vuota." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Riga di comando kFreeBSD predefinita:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Questa stringa verrà usata come parametri per kFreeBSD nella voce di menu " "predefinita, ma non nella modalità di ripristino." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map è stato rigenerato" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Il file /boot/grub/device.map è stato riscritto in modo da usare i nomi " "stabili dei device. In molti casi questo dovrebbe ridurre in modo " "significativo la necessità di cambiarli in futuro e le voci nel menu di GRUB " "non dovrebbero essere influenzate." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Comunque, visto che sul sistema ci sono più dischi, è possibile che il " "sistema sia dipendente dalla vecchia mappa dei device. Controllare se nel " "menu di GRUB ci sono delle voci personalizzate che usano la numerazione dei " "dischi di GRUB (hdN) e, se necessario, aggiornarle." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Se non si capisce questo messaggio o non ci sono voci di menu " "personalizzate, ignorare questo messaggio." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "In ogni caso, per caricare GRUB 2 direttamente dal MBR, è necessario " #~ "eseguire (da root) il seguente comando:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Installazione di GRUB non riuscita. Continuare?" debian/po/pt.po0000664000000000000000000003723212524662415010607 0ustar # Portuguese translation for grub2's debconf messages # Copyright (C) 2007 Miguel Figueiredo # This file is distributed under the same license as the grub2 package. # # Miguel Figueiredo , 2007, 2010, 2011. # Ricardo Silva , 2008. # Tiago Fernandes , 2010. msgid "" msgstr "" "Project-Id-Version: grub2 1.98-1\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-09-11 20:39+0100\n" "Last-Translator: Miguel Figueiredo \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Carregar em cadeia a partir do menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Os scripts de actualização do GRUB detectaram uma configuração do GRUB " "Legacy em /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Por forma a substituir a versão antiga do GRUB que se encontra no sistema, é " "recomendado que o /boot/grub/menu.lst seja ajustado para permitir carregar " "imagem de boot do GRUB 2 a partir da configuração actual do GRUB antigo. " "Esta etapa agora pode ser feita automaticamente." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "É recomendado que aceite carregar em cadeia o GRUB 2 a partir do menu.lst, e " "verificar que a configuração do novo GRUB 2 está funcional, antes de ser " "escrito no MBR (Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Qualquer que seja a sua decisão, pode substituir mais tarde a antiga imagem " "do MBR com o GRUB 2, executando como root o seguinte comando:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "dispositivos de instalação GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "O pacote grub-pc está a ser actualizado. Este menu permite-lhe seleccionar " "quais os dispositivos onde gostaria que o grub-install corresse " "automaticamente, se algum." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Correr o grub-install automaticamente é recomendado na maior parte das " "situações, para prevenir que a imagem core do GRUB instalada não fique " "dessincronizada com os módulos do GRUB ou grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Se não têm a certeza de qual a drive designada como driver de arranque pela " "sua BIOS, é normalmente boa ideia instalar o GRUB em todas elas." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Nota: é possível instalar o GRUB no boot record de partições, e são " "oferecidas algumas partições aqui. No entanto, isto força o GRUB a utilizar " "o mecanismo blocklist, que o torna menos fiável. Assim não é recomendável." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "O boot loader do GRUB foi instalado num disco que não se encontra presente, " "ou então o seu identificador único foi alterado por alguma razão. É " "importante ter a certeza que a imagem core do GRUB se mantêm sincronizada " "com os módulos do GRUB e grub.cfg. Por favor verifique de novo para ter a " "certeza de que o GRUB é escrito nos dispositivos apropriados de arranque." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "A escrita do GRUB para o dispositivo de arranque falhou - continuar?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "A instalação do GRUB falhou nos seguintes dispositivos:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Pretende continuar de qualquer modo? Em caso afirmativo, o seu computador " "pode não arrancar em condições. " #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "A escrita do GRUB para o dispositivo de arranque falhou - tentar de novo?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Poderá instalar o GRUB noutro dispositivo, no entanto deverá verificar que o " "seu sistema arranca desse dispositivo. Se não o fizer, a actualização a " "partir do GRUB Legacy será cancelada." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Continuar sem instalar o GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Escolheu não instalar o GRUB em qualquer dispositivo. Se continuar, o gestor " "de arranque pode não ficar correctamente configurado, e quando o computador " "arrancar da próxima vez irá usar o que estiver anteriormente no sector de " "arranque. Se existir uma versão anterior do GRUB 2 no sector de arranque, " "poderá não ser capaz de carregar os módulos e gerir o ficheiro de " "configuração actual." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Se já estiver a utilizar um gestor de arranque diferente e quiser continuar " "a fazê-lo, ou se se tratar de um ambiente especial onde não necessita de " "gestor de arranque, deverá então continuar de qualquer modo. Caso contrário, " "deverá instalar o GRUB em algum sitio." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Remover o GRUB 2 de /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Deseja remover todos os ficheiros do GRUB 2 de /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Isto fará com que o sistema não arranque até que seja instalado outro gestor " "de arranque." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Finalizar a conversão para o GRUB 2 agora?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Este sistema ainda tem ficheiros instalados do gestor de arranque GRUB " "Legacy, no entanto agora também tem registos de arranque do GRUB 2 " "instalados nos discos seguintes:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Parece provável que o GRUB Legacy não esteja a ser usado, deve fazer a " "actualização das imagens do GRUB 2 nestes discos e finalizar a conversão " "para o GRUB 2 removendo os ficheiros antigos do GRUB Legacy. Se não " "actualizar estas imagens GRUB 2 então estas podem ser incompatíveis com " "novos pacotes e provocar uma falha no arranque do sistema." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Normalmente deverá finalizar a conversão para o GRUB 2 a não ser que estes " "registos de arranque tenham sido criados por uma instalação do GRUB 2 noutro " "sistema operativo." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linha de comandos do Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "A seguinte linha de comandos Linux foi extraída de /etc/default/grub ou do " "parâmetro `kopt' no menu.lst do GRUB Legacy. Por favor verifique que está " "correcta, e modifique se necessário. É permitido que a linha de comandos " "esteja vazia." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linha de comandos padrão do Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "A seguinte linha será utilizada como parâmetros para o Linux na entrada " "predefinida do menu, mas não para o modo de recuperação." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "linha de comandos kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "A seguinte linha de comandos kFreeBSD foi extraída a partir de /etc/default/" "grub ou do parâmetro `kopt' no menu.lst do GRUB Legacy. Por favor verifique " "que está correcta, e modifique se necessário. É permitido que a linha esteja " "vazia." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Linha de comandos padrão do kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "A seguinte linha será utilizada como parâmetros para o kFreeBSD para a " "entrada por omissão do menu, mas não para o modo de recuperação." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "O /boot/grub/device.map foi recriado" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "O ficheiro /boot/grub/device.map foi reescrito para usar nomes de " "dispositivos estáveis. Na maioria dos casos, esta acção reduz " "significativamente a necessidade de alterações no futuro e as entradas de " "menu geradas pelo GRUB não deverão ser afectadas." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "No entanto, desde que está presente no sistema mais do que um disco, é " "possível que o sistema esteja dependente do mapa antigo de dispositivos " "(device map). Por favor verifique se tem algumas entradas personalizadas no " "menu de arranque que dependam da numeração de drives do GRUB (hdN), e " "actualize-as se necessário." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Se não entende esta mensagem ou se não tiver entradas personalizadas no menu " "de arranque, pode ignorar esta mensagem." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Em qualquer dos casos, quando quiser que o GRUB 2 seja carregado " #~ "directamente a partir do MBR, pode fazê-lo executando (como root) o " #~ "seguinte comando: " #~ msgid "GRUB installation failed. Continue?" #~ msgstr "A instalação do GRUB falhou. Continuar?" debian/po/cs.po0000664000000000000000000003640612524662415010573 0ustar # Czech translation of grub2 debconf messages. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the grub2 package. # Miroslav Kure , 2008 -- 2011 # msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-06-02 19:54+0200\n" "Last-Translator: Miroslav Kure \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Zavést přes menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Aktualizační skripty GRUBu rozpoznaly v /boot/grub nastavení pro předchozí " "verzi GRUBu (tzv. GRUB Legacy)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Abyste na svém systému nahradili zastaralou verzi GRUBu, je doporučeno " "upravit /boot/grub/menu.lst tak, aby zavedl obraz GRUBu 2 pomocí stávajícího " "GRUB Legacy. Tento krok je nyní možné provést automaticky." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Před instalací GRUBu 2 přímo do MBR (Master Boot Record) se doporučuje " "nejprve vyzkoušet zavedení GRUBu 2 skrze menu.lst a teprve po ověření, že " "vše funguje očekávaným způsobem, zkusit instalaci do MBR." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Ať se rozhodnete jakkoliv, obraz v MBR můžete kdykoliv později nahradit " "GRUBem 2. Stačí jako root spustit následující příkaz:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Zařízení pro instalaci GRUBu:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Balík grub-pc se právě aktualizuje. Tato nabídka vám umožňuje zvolit " "zařízení, na kterých se má automaticky spouštět grub-install." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Automatické spouštění grub-install je ve většině případů doporučeno, protože " "tak předcházíte tomu, aby se obraz jádra GRUBu rozcházel s GRUB moduly nebo " "souborem grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Pokud si nejste jisti, který disk je v BIOSu označen jako zaváděcí, bývá " "často dobrým nápadem nainstalovat GRUB na všechny disky." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Poznámka: GRUB je možné instalovat také do zaváděcích záznamů jednotlivých " "oblastí, jejichž seznam zde vidíte. Tímto však donutíte GRUB, aby používal " "mechanismus zvaný blocklist, který je méně spolehlivý tudíž se nedoporučuje." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Zavaděč GRUB byl dříve nainstalován na disk, který již není dostupný, nebo " "jehož unikátní identifikátor se z nějakého důvodu změnil. Je důležité, aby " "nainstalovaný obraz jádra GRUBu odpovídal GRUB modulům a souboru grub.cfg. " "Ještě jednou se prosím ujistěte, že je GRUB zapsán na příslušných zaváděcích " "zařízeních." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Zápis GRUBu na zaváděcí zařízení selhal - pokračovat?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB se nepodařilo nainstalovat na následující zařízení:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Chcete přesto pokračovat? Pokud ano, je možné, že počítač nemusí korektně " "nastartovat." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Zápis GRUBu na zaváděcí zařízení selhal - zkusit znovu?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Je možné, že se povede instalace GRUBu na nějaké jiné zařízení, ovšem měli " "byste se ujistit, že váš systém umí z daného zařízení zavádět. V opačném " "případě bude aktualizace z GRUB Legacy zrušena." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Pokračovat bez instalace GRUBu?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Rozhodli jste se neinstalovat GRUB na žádné zařízení. Budete-li pokračovat, " "zavaděč nemusí být nastaven správně a při příštím spuštění počítače se " "použije cokoliv, co bylo dříve v zaváděcím sektoru. Pokud tam je dřívější " "verze GRUBu 2, nemusí se jí podařit načíst moduly, nebo zpracovat současný " "konfigurační soubor." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Pokud používáte jiný zavaděč a chcete ho používat i nadále, nebo pokud je " "toto speciální prostředí, ve kterém zavaděč nepotřebujete, můžete " "pokračovat. V opačném případě byste někam měli GRUB nainstalovat." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Odstranit GRUB 2 z /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Chcete z /boot/grub odstranit všechny soubory GRUBu 2?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Tímto se stane systém nezaveditelným do doby, než nainstalujete jiný zavaděč." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Dokončit nyní přechod na GRUB 2?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Tento systém stále obsahuje soubory starého zavaděče GRUB Legacy, ale na " "následujících discích již má zaváděcí záznamy GRUBu 2:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Je dosti pravděpodobné, že se GRUB Legacy již nepoužívá a tudíž byste na " "těchto discích měli aktualizovat obrazy GRUBu 2 a dokončit konverzi na GRUB " "2 odstraněním starých souborů z GRUB Legacy. Neaktualizujete-li tyto obrazy " "GRUBu 2, nemusí být kompatibilní s novými balíky a mohou způsobit, že se váš " "systém přestane zavádět správně." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Obvykle byste měli konverzi na GRUB 2 dokončit, s výjimkou situace, kdy tyto " "zaváděcí záznamy vytvořila instalace nějakého jiného operačního systému." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Parametry pro Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Následující řádka s parametry pro Linux byla získána ze starého souboru menu." "lst z parametru „kopt“ nebo ze souboru /etc/default/grub. Zkontrolujte " "prosím, zda jsou parametry v pořádku a případně je upravte do požadované " "podoby. Řádka s parametry může být i prázdná." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Výchozí parametry pro Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Následující parametry pro Linux se použijí pro výchozí položku menu, ale ne " "pro záchranný režim." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Parametry pro kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Následující řádka s parametry pro kFreeBSD byla získána ze starého souboru " "menu.lst z parametru „kopt“ nebo ze souboru /etc/default/grub. Zkontrolujte " "prosím, zda jsou parametry v pořádku a případně je upravte do požadované " "podoby. Řádka s parametry může být i prázdná." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Výchozí parametry pro kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Následující parametry pro kFreeBSD se použijí pro výchozí položku menu, ale " "ne pro záchranný režim." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map byl aktualizován" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Soubor /boot/grub/device.map byl přepsán tak, aby používal stabilní jména " "zařízení. Ve většině případů by to mělo výrazně snížit potřebu jejich změny " "v budoucnosti a položky v zaváděcí nabídce vygenerované GRUBem by neměly být " "nijak ovlivněny." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Nicméně je možné (protože je v systému více než jeden disk), že se systém " "spoléhal na starý soubor device.map. Zkontrolujte prosím, zda používáte " "vlastní upravené položky zaváděcí nabídky, které spoléhají na GRUBovské " "číslování disků (hdN) a podle potřeby je aktualizujte." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Nerozumíte-li této zprávě, nebo pokud žádné vlastní upravené položky " "zaváděcí nabídky nemáte, můžete tuto zprávu ignorovat." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Až se rozhodnete zavádět GRUB 2 přímo z MBR, stačí jako uživatel root " #~ "spustit příkaz:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Instalace GRUBu selhala. Pokračovat?" debian/po/th.po0000664000000000000000000005272312524662415010601 0ustar # Thai translation of grub. # Copyright (C) 2010-2012 Software in the Public Interest, Inc. # This file is distributed under the same license as the grub package. # Theppitak Karoonboonyanan , 2010-2012. # msgid "" msgstr "" "Project-Id-Version: grub\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-01-20 17:12+0700\n" "Last-Translator: Theppitak Karoonboonyanan \n" "Language-Team: Thai \n" "Language: th\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "จะโหลดแบบลูกโซ่จาก menu.lst หรือไม่?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "สคริปต์ปรับรุ่นของ GRUB ตรวจพบค่าตั้งของ GRUB รุ่นเก่าใน /boot/grub" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "ในการแทนที่ GRUB รุ่นเก่าในระบบ ขอแนะนำให้ปรับ /boot/grub/menu.lst " "ให้โหลดอิมเมจสำหรับบูตของ GRUB 2 จาก GRUB รุ่นเก่าที่มีอยู่ " "ขั้นตอนนี้สามารถทำแบบอัตโนมัติได้ในตอนนี้" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "ขอแนะนำให้คุณตอบรับการโหลด GRUB 2 แบบลูกโซ่จาก menu.lst และทดสอบว่าค่าตั้งของ GRUB 2 " "ใช้การได้ ก่อนที่จะเขียนลง MBR (Master Boot Record) จริง" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "ไม่ว่าคุณจะเลือกแบบไหน คุณยังสามารถแทนที่อิมเมจเก่าใน MBR ด้วย GRUB 2 เองได้ในภายหลัง " "โดยใช้คำสั่งต่อไปนี้ในฐานะ root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "อุปกรณ์ที่จะติดตั้ง GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "กำลังจะปรับรุ่นแพกเกจ grub-pc ขึ้น เมนูนี้จะช่วยคุณเลือกอุปกรณ์ที่คุณต้องการให้เรียก grub-" "install โดยอัตโนมัติเพื่อติดตั้ง GRUB ถ้ามีอุปกรณ์ดังกล่าว" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "โดยทั่วไปแล้ว ขอแนะนำให้เรียก grub-install โดยอัตโนมัติ เพื่อป้องกันไม่ให้อิมเมจแกนกลางของ " "GRUB ที่ติดตั้งมีข้อมูลไม่ตรงกับมอดูล GRUB ต่างๆ หรือไม่ตรงกับ grub.cfg" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "ถ้าคุณไม่แน่ใจว่า BIOS กำหนดไดรว์ไหนไว้สำหรับบูต ก็มักเป็นความคิดที่ดีที่จะติดตั้ง GRUB " "ลงในไดรว์ทุกไดรว์" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "หมายเหตุ: เป็นไปได้เหมือนกันที่จะติดตั้ง GRUB ลงในบูตเรคอร์ดของพาร์ทิชัน " "และได้แสดงพาร์ทิชันที่เหมาะสมเป็นตัวเลือกไว้ในที่นี้แล้ว อย่างไรก็ดี การทำเช่นนั้นจะเป็นการบังคับให้ " "GRUB ใช้กลไกรายชื่อบล็อค ซึ่งความถูกต้องในการทำงานอาจลดลง จึงไม่ขอแนะนำ" #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "มีการติดตั้งบูตโหลดเดอร์ GRUB ก่อนหน้านี้ในดิสก์ที่ขณะนี้ไม่มีแล้ว หรือมี " "แต่หมายเลขประจำดิสก์ได้เปลี่ยนไปด้วยสาเหตุบางอย่าง " "จึงจำเป็นต้องทำให้แน่ใจว่าอิมเมจแกนกลางของ GRUB ที่ติดตั้งไว้นั้นยังมีข้อมูลตรงกับมอดูล GRUB ต่างๆ " "และกับ grub.cfg อยู่ กรุณาตรวจสอบอีกครั้งให้แน่ใจว่าจะเขียนข้อมูล GRUB ลงในอุปกรณ์บูตที่เหมาะสม" #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "เขียน GRUB ลงในอุปกรณ์บูตไม่สำเร็จ - ดำเนินการต่อไปหรือไม่?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "ติดตั้ง GRUB ลงในอุปกรณ์ต่อไปนี้ไม่สำเร็จ:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "คุณยังคงต้องการดำเนินการต่อไปหรือไม่? ถ้าทำต่อ เครื่องของคุณอาจบูตไม่ขึ้นได้" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "เขียน GRUB ลงในอุปกรณ์บูตไม่สำเร็จ - ลองใหม่หรือไม่?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "คุณอาจสามารถติดตั้ง GRUB ลงในอุปกรณ์อื่นได้ " "โดยคุณควรทดสอบด้วยว่าเครื่องของคุณบูตจากอุปกรณ์นั้นขึ้นหรือไม่ ถ้าตอบปฏิเสธ " "ก็จะยกเลิกการปรับรุ่นจาก GRUB รุ่นเก่า" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "จะดำเนินการต่อไปโดยไม่ติดตั้ง GRUB หรือไม่?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "คุณได้เลือกที่จะไม่ติดตั้ง GRUB ลงในอุปกรณ์ใดเลย ถ้าดำเนินการต่อไป " "บูตโหลดเดอร์อาจอยู่ในสภาพที่ไม่ได้ตั้งค่าอย่างสมบูรณ์ และเมื่อเปิดเครื่องครั้งต่อไป " "ก็จะใช้สิ่งที่อยู่ในบูตเซกเตอร์ก่อนหน้านี้ และถ้าในบูตเซกเตอร์มี GRUB 2 รุ่นเก่าอยู่ " "ก็อาจจะไม่สามารถโหลดมอดูลหรือใช้แฟ้มค่าตั้งปัจจุบันได้" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "ถ้าคุณกำลังใช้บูตโหลดเดอร์ตัวอื่นอยู่ และต้องการใช้ต่อไป " "หรือถ้าคุณอยู่ในสภาพแวดล้อมที่ไม่ต้องใช้บูตโหลดเดอร์ คุณก็อาจดำเนินการต่อไปได้ มิฉะนั้น " "คุณก็ควรติดตั้ง GRUB ลงในที่ใดที่หนึ่ง" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "จะลบ GRUB 2 ออกจาก /boot/grub หรือไม่?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "คุณต้องการจะลบแฟ้มของ GRUB 2 ทั้งหมดออกจาก /boot/grub หรือไม่?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "การลบนี้จะทำให้ระบบไม่สามารถบูตได้ ยกเว้นมีบูตโหลดเดอร์ตัวอื่นติดตั้งอยู่" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "จะทำขั้นสุดท้ายของการแปลงเป็น GRUB 2 หรือไม่?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "ระบบนี้มีแฟ้มจากบูตโหลดเดอร์ GRUB รุ่นเก่าติดตั้งอยู่ แต่ตอนนี้มีบูตเรคอร์ดของ GRUB 2 " "ติดตั้งไว้ในดิสก์ต่อไปนี้เช่นกัน:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "ดูเหมือน GRUB รุ่นเก่าจะไม่มีการใช้งานอีกต่อไป และดูเหมือนว่าคุณควรจะปรับรุ่นอิมเมจของ GRUB 2 " "ในดิสก์เหล่านี้แทน พร้อมทั้งจบขั้นตอนสุดท้ายของการแปลงไปเป็น GRUB 2 โดยลบแฟ้มของ GRUB " "รุ่นเก่าทิ้ง ถ้าคุณไม่ปรับรุ่นอิมเมจ GRUB 2 เหล่านี้ขึ้น อิมเมจก็อาจไม่เข้ากันกับแพกเกจรุ่นใหม่ๆ " "และทำให้ระบบของคุณบูตไม่ขึ้นได้" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "โดยทั่วไปแล้ว คุณควรจะจบขั้นตอนสุดท้ายของการแปลงไปเป็น GRUB 2 นี้ " "นอกเสียจากว่าบูตเรคอร์ดเหล่านี้จะถูกสร้างโดย GRUB 2 ที่ติดตั้งในระบบปฏิบัติการอื่น" #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "พารามิเตอร์สำหรับบูตลินุกซ์:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "พารามิเตอร์สำหรับบูตลินุกซ์ต่อไปนี้ดึงออกมาจาก /etc/default/grub หรือพารามิเตอร์ `kopt' ใน " "menu.lst ของ GRUB รุ่นเก่า กรุณาตรวจสอบว่าค่านี้ถูกต้องหรือไม่ และกรุณาแก้ไขถ้าจำเป็น " "พารามิเตอร์นี้สามารถปล่อยเป็นค่าว่างเปล่าได้" #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "พารามิเตอร์สำหรับบูตลินุกซ์แบบปกติ:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "พารามิเตอร์ต่อไปนี้จะใช้ในเมนูสำหรับบูตลินุกซ์แบบปกติ แต่จะไม่ใช้กับโหมดกู้ระบบ" #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "พารามิเตอร์สำหรับบูต kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "พารามิเตอร์สำหรับบูต kFreeBSD ต่อไปนี้ดึงออกมาจาก /etc/default/grub หรือพารามิเตอร์ " "`kopt' ใน menu.lst ของ GRUB รุ่นเก่า กรุณาตรวจสอบว่าค่านี้ถูกต้องหรือไม่ " "และกรุณาแก้ไขถ้าจำเป็น พารามิเตอร์นี้สามารถปล่อยเป็นค่าว่างเปล่าได้" #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "พารามิเตอร์สำหรับบูต kFreeBSD แบบปกติ:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "พารามิเตอร์ต่อไปนี้จะใช้ในเมนูสำหรับบูต kFreeBSD แบบปกติ แต่จะไม่ใช้กับโหมดกู้ระบบ" #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "สร้าง /boot/grub/device.map ใหม่เรียบร้อยแล้ว" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "เขียนแฟ้ม /boot/grub/device.map ใหม่เพื่อใช้ชื่ออุปกรณ์ที่ไม่เปลี่ยนแปลงง่ายเรียบร้อยแล้ว " "โดยส่วนใหญ่แล้ว ชื่อแบบนี้ควรจะช่วยลดความจำเป็นในการเปลี่ยนข้อมูลอีกในอนาคตได้อย่างมาก " "และรายการเมนูบูตต่างๆ ที่สร้างโดย GRUB ก็ไม่ควรได้รับผลกระทบ" #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "อย่างไรก็ดี เนื่องจากมีดิสก์หลายดิสก์อยู่ในระบบ จึงเป็นไปได้ที่ระบบจะอาศัยผังอุปกรณ์แบบเก่า " "กรุณาตรวจสอบว่ามีรายการเมนูบูตที่คุณกำหนดเองที่อ้างถึงไดรว์ด้วยหมายเลขในรูป (hdN) ของ GRUB " "อยู่หรือไม่ และกรุณาปรับแก้ถ้าจำเป็น" #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "ถ้าคุณไม่เข้าใจข้อความนี้ หรือถ้าไม่มีรายการเมนูบูตที่คุณกำหนดเอง คุณก็สามารถข้ามข้อความนี้ไปได้" debian/po/ro.po0000664000000000000000000004255512524662415010610 0ustar # translation of ro.po to Romanian # Romanian translations for grub package # Traducerea în limba română pentru pachetul grub. # Copyright (C) 2007 THE grub'S COPYRIGHT HOLDER # This file is distributed under the same license as the grub package. # # Eddy Petrișor , 2007,2008. # ioan-eugen STAN , 2010. # Lucian Adrian Grijincu , 2010. msgid "" msgstr "" "Project-Id-Version: ro\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-08-18 18:44+0300\n" "Last-Translator: Andrei POPESCU \n" "Language-Team: Romanian \n" "Language: ro\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: 2\n" "X-Generator: KBabel 1.11.4\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Încărcare înlănțuită din menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Scripturile de înnoire ale lui GRUB au detectat în /boot/grub o configurație " "pentru vechiul GRUB." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Pentru a înlocui vechea versiune a lui GRUB, se recomandă modificarea " "fișierului /boot/grub/menu.lst, astfel încât să încarce o imagine GRUB 2 din " "configurația existentă. Acest pas poate fi făcut chiar acum în mod automat." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Este recomandat să acceptați înlănțuirea lui GRUB 2 din menu.lst și să " "verificați că noua configurație pentru GRUB 2 funcționează, înainte de " "instalarea în înregistrarea principală de boot (MBR)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Indiferent ce decideți, puteți înlocui ulterior imaginea MBR veche cu GRUB 2 " "executând următoarea comandă cu privilegii root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Dispozitive pentru a instala GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Pachetul grub-pc este în curs de înnoire. Acest meniu vă permite să alegeți " "pentru ce dispozitive doriți să ruleze automat grub-install, dacă este cazul." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Rularea automată a utilitarului grub-install este recomandată în majoritatea " "situațiilor, pentru ca imaginea GRUB instalată fie sincronizată cu modulele " "GRUB sau grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Dacă nu știți sigur care unitate este desemnată ca unitatea de pornire de " "către BIOS este o idee bună să instalați GRUB pe toate unitățile." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Notă: este posibil să instalați GRUB în înregistrarea boot a unei partiții, " "iar unele partiții adecvate sunt prezentate aici. Totuși, aceasta va forța " "GRUB să utilizeze mecanismul blocklist, care este mai puțin fiabil. În " "consecință această metodă nu este recomandată." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Încărcătorul de sistem GRUB a fost instalat pe un disc care nu mai este " "prezent, sau al cărui identificator unic a fost modificat dintr-un motiv " "oarecare. Este important să vă asigurați că imaginea GRUB rămâne " "sincronizată cu modulele GRUB și grub.cfg. Vă rugăm verificați din nou, " "pentru a vă asigura că GRUB este scris pe dispozitivul boot corect." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Scrierea GRUB pe dispozitivul boot a eșuat. Se continuă?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Instalarea GRUB pe următoarele dispozitive a eșuat:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Doriți să continuați oricum? Dacă da, este posibil ca sistemul să nu " "pornească corespunzător." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Scrierea GRUB pe dispozitivul de pornire a eșuat. Se încearcă din nou?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Puteți instala GRUB pe alt dispozitiv, însă ar trebui să verificați dacă " "sistemul va porni de pe acel dispozitiv. Altfel, înnoirea de la GRUB Legacy " "va fi anulată." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Continuați fără să instalați GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Ați ales să nu instalați GRUB pe niciun dispozitiv. Dacă veți continua, este " "posibil ca încărcătorul de sistem să nu fie configurat corespunzător, iar la " "pornirea calculatorului acesta va folosi ce se afla deja în sectorul de " "pornire. Dacă există o versiune mai veche de GRUB 2 în sectorul de pornire " "este posibil ca aceasta să nu poată încărca modulele sau să proceseze " "fișierul de configurare curent." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Dacă folosiți deja un alt încărcător de sistem și doriți să continuați, sau " "dacă acesta este un mediu special în care nu aveți nevoie de încărcător de " "sistem, atunci ar trebui să continuați. Altfel, ar trebui să instalați GRUB " "undeva." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Se îndepărtează GRUB 2 din /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Doriți ca toate fișierele GRUB 2 să fie îndepărtate din /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Aceasta va împiedica pornirea sistemului, în afara cazului în care este " "instalat un alt încărcător de sistem." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Terminați acum conversia la GRUB 2?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Acest sistem mai are instalate fișiere din GRUB Legacy, dar acum are " "instalat și GRUB 2 pe aceste discuri:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Este foarte probabil ca GRUB Legacy să nu mai fie folosit și ar trebui să " "actualizați imaginile GRUB 2 pe aceste discuri și să definitivați trecerea " "la GRUB 2 îndepărtând fișierele GRUB Legacy vechi. Dacă nu actualizați " "aceste imagini GRUB 2, ele ar putea fi incompatibile cu noile pachete și ar " "putea împiedica sistemul să pornească corespunzător." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "În general este bine să încheiați conversia la GRUB 2, în afara cazului în " "care acele fișiere au fost create de o instalare GRUB 2 a altui sistem de " "operare." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linia de comandă Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Această linie de comandă Linux a fost extrasă din /etc/default/grub sau " "parametrul „kopt” din fișierul menu.lst al vechiului GRUB. Verificați " "corectitudinea acesteia și modificați-o, dacă este nevoie. Linia de comandă " "poate fi goală." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linia de comandă implicită Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Următorul șir va fi folosit ca parametru pentru Linux pentru poziția " "implicită din meniu, dar nu și pentru cea de recuperare." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Linia de comandă kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Această linie de comandă kFreeBSD a fost extrasă din /etc/default/grub sau " "parametrul „kopt” din fișierul menu.lst al vechiului GRUB. Verificați " "corectitudinea acesteia și modificați-o, dacă este nevoie. Linia de comandă " "poate fi goală." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Linia de comandă implicită kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Următorul șir va fi folosit ca parametru pentru kFreeBSD pentru poziția " "implicită din meniu, dar nu și pentru cea de recuperare." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map a fost regenerat" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Fișierul /boot/grub/device.map a fost rescris să folosească nume stabile de " "dispozitive. În majoritatea cazurilor, acest lucru va reduce semnificativ " "nevoia de a-l modifica ulterior și intrările în meniu generate de grub nu ar " "trebui să fie afectate. " #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Totuși, deoarece există mai mult de un disc în sistem, este posibil ca " "sistemul să depindă de vechea hartă de dispozitive. Verificați dacă aveți " "intrări personalizate în meniu care depind de numerotarea GRUB (hdN) și " "actualizați-le dacă este cazul." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Dacă nu înțelegeți acest mesaj, sau nu există poziții personalizate în " "meniu, îl puteți ignora." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "În orice caz, atunci când veți dori ca GRUB 2 sa fie încărcat direct din " #~ "MBR, puteți rula (ca root) comanda următoare:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Instalarea GRUB a eșuat. Continuați?" #~ msgid "GRUB 1.95 numbering scheme transition" #~ msgstr "Tranziția la schema de numerotare pentru GRUB 1.95" #~ msgid "" #~ "As of version 1.95, GRUB 2 has changed its numbering scheme. Partitions " #~ "are now counted starting from 1 rather than 0. This is to make it " #~ "consistent with device names of Linux and the other kernels used in " #~ "Debian. For example, when using Linux as the kernel, \"(hd0,1)\" refers " #~ "to the same partition as the /dev/sda1 device node." #~ msgstr "" #~ "Începând cu versiunea 1.95, GRUB 2 și-a schimbat schema de numerotare. " #~ "Partițiile sunt acum numerotate începând de la 1 (în loc de 0). Acest " #~ "lucru este consecvent cu numele de dispozitive ale Linux-ului și a altor " #~ "nuclee folosite în Debian. De exemplu, când se folosește nucleul Linux, " #~ "„(hd0,1)” se referă la aceiași partiție ca și nodul de dispozitiv /dev/" #~ "sda1." #~ msgid "" #~ "Because of this, there's a chance your system becomes unbootable if " #~ "update-grub(8) is run before GRUB is updated, generating a grub.cfg file " #~ "that your installed GRUB won't yet be able to parse correctly. To ensure " #~ "your system will be able to boot, you have to:" #~ msgstr "" #~ "De aceea, există riscul ca sistemul să nu mai pornească dacă update-grub" #~ "(8) este rulat înainte ca GRUB să fie actualizat, generând astfel un " #~ "fișier grub.cfg pe care GRUB-ul instalat nu-l va putea încă analiza " #~ "corect. Pentru a vă asigura că sistemul va putea porni, va trebui să:" #~ msgid "" #~ " - Reinstall GRUB (typically, by running grub-install).\n" #~ " - Rerun update-grub to generate a new grub.cfg." #~ msgstr "" #~ " - Reinstalați GRUB (în mod normal, prin rularea lui grub-install).\n" #~ " - Rulați din nou update-grub pentru a genera un nou grub.cfg." debian/po/gl.po0000664000000000000000000003654712524662415010576 0ustar # translation of grub2_1.98+20100804-2_gl.po to Galician # Galician translation of grub2's debconf templates # This file is distributed under the same license as the grub2 package. # # Jacobo Tarrio , 2007, 2008. # Jorge Barreiro , 2010, 2012. msgid "" msgstr "" "Project-Id-Version: grub2_1.98+20100804-2_gl\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-06-13 16:13+0200\n" "Last-Translator: Jorge Barreiro \n" "Language-Team: Galician \n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Cargar en cadea desde menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Os scripts de actualización de GRUB detectaron unha configuración do GRUB " "antigo en /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Para substituír a versión antiga de GRUB do sistema, recoméndase axustar /" "boot/grub/menu.lst para cargar unha imaxe de arranque de GRUB 2 desde a " "configuración existente do GRUB antigo. Pódese realizar este paso " "automaticamente agora." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Recoméndase que acepte cargar GRUB 2 en cadea desde menu.lst, e que " "verifique que a nova configuración de GRUB 2 funciona para vostede, antes de " "instalalo directamente no MBR (rexistro mestre de inicio)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Decida o que decida, poderá substituír a vella imaxe do MBR con GRUB 2 máis " "tarde, usando a seguinte orde como «root»:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Dispositivos onde instalar GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "O paquete «grub-pc» estase actualizando. Este menú permítelle escoller os " "dispositivos onde queira que se execute «grub-install» automaticamente, se " "quere facelo en algún." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Recoméndase executar «grub-install» automaticamente na maioría dos casos, " "para evitar que a imaxe do núcleo de GRUB se desincronice cos módulos de " "GRUB ou co ficheiro «grub.cfg»." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Se non está seguro de que dispositivo se escolle na BIOS como dispositivo de " "arranque, normalmente é unha boa idea instalar GRUB en todos eles." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Nota: tamén se pode instalar GRUB en rexistros de particións de arranque, e " "aquí ofrécense algunhas particións apropiadas. Sen embargo, isto obriga a " "GRUB a usar o mecanismo «blocklist», que o fai menos fiábel, polo que non se " "recomenda." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "O cargador de arranque GRUB foi anteriormente instalado en un disco que xa " "non está presente, ou que mudou o seu identificador único por algunha razón. " "É importante asegurarse de que a imaxe do núcleo de GRUB se manteña " "sincronizada cos módulos de GRUB e co ficheiro «grub.cfg». Comprobe de novo " "para asegurarse de que GRUB se escribiu no dispositivo de arranque apropiado." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "" "Produciuse un erro ao escribir GRUB no dispositivo de arranque. Quere " "continuar?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Non se puido instalar GRUB nos seguintes dispositivos:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Quere continuar de todas maneiras? Se o fai, pode que a súa computadora non " "poida iniciar correctamente." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "Produciuse un erro ao escribir GRUB no dispositivo de arranque. Quere " "tentalo de novo?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Ao mellor pode instalar GRUB en outro dispositivo, pero debería comprobar " "que o seu sistema pode iniciar desde él. Se non, a instalación desde GRUB " "Legacy cancelarase." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Quere continuar sen instalar GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Escolleu non instalar GRUB en ningún dispositivo. De continuar,pode que o " "cargador de arranque non quede adecuadamente configurado, e a próxima vez " "que arranque o sistema usarase o que houbese antes no sector de arranque. Se " "nel hai unha versión antiga de GRUB 2 pode que esta sexa incapaz de cargar " "os módulos ou de manexar o ficheiro de configuración actual." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Se xa está usando un cargador de arranque diferente e quere continuar " "usandoo, ou se este é un ambiente especial onde non necesita un cargador de " "arranque, debería continuar. En caso contrario debería instalar GRUB en " "algún lugar." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Quere eliminar GRUB 2 de /boot/grub ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Quere que todos os ficheiros de GRUB 2 se eliminen de /boot/grub ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Isto fará que o sistema non poida arrancar, a menos que teña outro cargador " "de arranque instalado." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Rematar a conversión a GRUB 2 agora?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Este sistema aínda ten instalados ficheiros do cargador de arranque GRUB " "Legacy, pero agora tamén ten rexistros de arranque de GRUB 2 nestes discos:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Asemella que GRUB Legacy xa non se usa, e que debería actualizar as imaxes " "de GRUB 2 nestes discos e rematar a conversión a GRUB 2 eliminando os " "ficheiros vellos de GRUB Legacy. Se non actualiza estas imaxes de GRUB 2, " "poderían ser incompatíbeis cos novos paquetes e provocar que sistema non " "arranque correctamente." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "En xeral, debería rematar a conversión a GRUB 2 a menos que estos rexistros " "de inicio fosen creatos por unha instalación de GRUB 2 en outro sistema " "operativo." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Liña de comando de Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "A seguinte liña de comando de Linux sacouse de /etc/default/grub ou do " "parámetro «kopt» no ficheiro menu.lst de GRUB Legacy. Verifique que sexa " "correcta e modifíquea de ser preciso. A liña de comando pódese deixar " "baleira." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Liña de comando por defecto para Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "A seguinte liña será usada como parámetros para Linux na entrada por defecto " "do menú, pero non no modo de recuperación." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Liña de comando de kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "A seguinte liña de comando de kFreeBSD sacouse de /etc/default/grub, ou do " "parámetro «kopt» no ficheiro menu.lst de GRUB Legacy. Verifique que sexa " "correcta e modifíquea de ser preciso. A liña de comando pódese deixar " "baleira." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Liña de comando por defecto para kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "A seguinte cadea usarase como parámetros para kFreeBSD para a entrada por " "defecto do menú, pero non para o modo de recuperación." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map foi rexenerado." #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "O ficheiro /boot/grub/device.map foi reescrito para usar nomes de " "dispositivos estábeis. Na maioría dos casos isto debería reducir " "significativamente a necesidade de cambialos en un futuro, e as entradas no " "menú de GRUB non se verían afectadas." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Porén, como ten máis de un disco no seu sistema, pode que dependa do vello " "«device map». Comprobe se ten algunha entrada personalizada no menú de " "arranque que use a numeración de unidades de GRUB (hdN) e actualícea de ser " "necesario." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Se non comprende esta mensaxe, ou se non ten ningunha entrada personalizada " "no menú de arranque, pode ignorala." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "En calquera caso, cando queira cargar GRUB 2 directamente desde o MBR, " #~ "pode facelo executando (coma administrador) a seguinte orde:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "A instalación de GRUB fallou. Quere continuar?" debian/po/ca.po0000664000000000000000000003701512524662415010546 0ustar # Catalan translation of grub2's debconf messages # Copyright © 2009, 2010, 2011 Free Software Foundation, Inc. # This file is distributed under the same license as the grub2 package. # # Jordi Mallach , 2009, 2010, 2011. # Juan Andrés Gimeno Crespo , 2009. msgid "" msgstr "" "Project-Id-Version: grub2 1.99-5\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-05-30 22:57+0200\n" "Last-Translator: Jordi Mallach \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Voleu carregar en cadena des del menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Els scripts d'actualització del GRUB han detectat una configuració del GRUB " "Legacy en /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "A l'hora de reemplaçar la versió Legacy del GRUB que hi ha al sistema, és " "recomanable que es modifique /boot/grub/menu.lst per a carregar una imatge " "d'arrencada del GRUB 2 des de la vostra configuració del GRUB Legacy " "existent. Aquest pas es pot dur a terme ara." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "És recomanable que accepteu la càrrega en cadena del GRUB 2 des del menu." "lst, per a verificar que la nova configuració del GRUB 2 funciona " "correctament, abans de que s'escriga al registre mestre d'arrencada (MBR)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Independentment de la vostra decisió, podeu reemplaçar la imatge antiga de " "l'MBR amb el GRUB2 executant l'ordre següent com a root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Dispositius d'instaŀlació del GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "S'està actualitzant el paquet grub-pc. Aquest menú us permet seleccionar " "sobre quins dispositius voleu que s'execute el grub-install automàticament, " "en cas de voler-ho." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "L'execució automàtica del grub-install és recomanable en la majoria de les " "situacions, per a evitar que la imatge del nucli del GRUB es desincronitze " "amb els mòduls del GRUB o el grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Si no esteu segur sobre quina és la unitat designada com a unitat " "d'arrencada per la BIOS, normalment és una bona idea instaŀlar el GRUB a " "tots ells." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Nota: també és possible instaŀlar el GRUB a registres d'arrencada de " "particions, i s'ofereixen algunes particions addients. Tanmateix, això força " "al GRUB a usar el mecanisme de llistes de blocs, que fa que siga menys " "fiable, per la qual cosa no és recomanable." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "El carregador GRUB estava instaŀlat a un disc que ja no és present, o per al " "qual ha canviat el seu identificador únic per alguna raó. És important " "assegurar-se que la imatge del nucli del GRUB roman sincronitzada amb els " "mòduls del GRUB i el grub.cfg. Comproveu de nou que el GRUB s'escriu als " "dispositius d'arrencada apropiats." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Ha fallat l'escriptura del GRUB al dispositiu. Voleu continuar?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "El GRUB no s'ha pogut instaŀlar als dispositius següents:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Voleu continuar tot i això? Si ho feu, és possible que l'ordinador no " "arrenque correctament." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "Ha fallat l'escriptura del GRUB al dispositiu. Voleu tornar a provar-ho?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "És possible que pugueu instaŀlar el GRUB en un altre dispositiu, tot i que " "hauríeu de comprovar que el sistema arrencarà des d'aquell dispositiu. En " "cas contrari, es canceŀlarà l'actualització des del GRUB Legacy." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Voleu continuar sense instaŀlar el GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Heu triat no instaŀlar el GRUB en cap dispositiu. Si continueu, és possible " "que el carregador no estiga configurat correctament, i quan s'arrenque " "l'ordinador la pròxima vegada, emprarà allò que estigués al sector " "d'arrencada. Si hi ha una versió anterior del GRUB2 al sector d'arrencada, " "és possible que no puga carregar mòduls o gestionar el fitxer de " "configuració actual." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Si ja esteu emprant un altre carregador i voleu continuar fent-ho, o aquest " "és un entorn especial on no necessiteu un carregador, hauríeu de continuar. " "Si no és així, hauríeu d'instaŀlar el GRUB en algun lloc." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Voleu suprimir el GRUB 2 de /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Voleu suprimir tots els fitxers del GRUB 2 de /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Això farà que el sistema no arrenque si no s'instaŀla un altre carregador." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Voleu finalitzar la conversió al GRUB 2 ara?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Aquest sistema encara té fitxers antics del carregador GRUB Legacy " "instaŀlats, però ara també té registres d'arrencada del GRUB 2 instaŀlats " "als discs següents:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Sembla probable que el GRUB Legacy no estiga ja en ús, i que hauríeu " "d'actualitzar les imatges del GRUB 2 presents a aquests discs per a " "finalitzar la conversió al GRUB 2, suprimint els fitxers vells del GRUB " "Legacy. Si no actualitzeu aquestes imatges del GRUB 2, és possible que " "romanen incompatibles amb els paquets nous i que causen que el sistema deixe " "d'arrencar correctament." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "En general, hauríeu de finalitzar la conversió al GRUB 2 a no ser que " "aquests registres d'arrencada els haja creat una instaŀlació del GRUB 2 des " "d'un altre sistema operatiu." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Línia d'ordres de Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La línia d'ordres de Linux següent ha sigut extreta de /etc/default/grub o " "del paràmetre «kopt» del fitxer menu.lst del GRUB Legacy. Verifiqueu que és " "correcta, i modifiqueu-la si és necessari. La línia d'ordres pot ser buida." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Línia d'ordres de Linux per defecte:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "La cadena següent serà emprada com a paràmetres del Linux per al menú " "d'entrada per defecte però no per al mode de recuperació." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Línia d'ordres de kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La línia d'ordres de kFreeBSD següent ha sigut extreta de /etc/default/grub " "o del paràmetre «kopt» del fitxer menu.lst del GRUB Legacy. Verifiqueu que " "és correcta, i modifiqueu-la si és necessari. La línia d'ordres pot ser " "buida." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Línia d'ordres de kFreeBSD per defecte:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "La cadena següent serà emprada com a paràmetres del kFreeBSD per al menú " "d'entrada per defecte però no per al mode de recuperació." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "S'ha regenerat el fitxer «/boot/grub/device.map»" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "S'ha reescrit el fitxer «/boot/grub/device.map» per a usar noms estables de " "dispositiu. En la majoria dels casos, això hauria de reduir la necessitat de " "canviar-ho en el futur, i no hauria d'afectar les entrades del menú " "d'arrencada generades pel GRUB." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Tanmateix, com hi ha més d'un disc al sistema, és possible que el sistema " "depenga del mapa de dispositius antic. Comproveu si hi ha entrades del menú " "d'arrencada personalitzades que requerisquen la numeració d'unitats del GRUB " "(hdN), i actualitzeu-les si és necessari." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Si no enteneu aquest missatge, o si no hi ha cap entrada del menú " "d'arrencada personalitzada, podeu descartar aquest missatge." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "En qualsevol cas, quan vulgueu que es carregue el GRUB 2 directament des " #~ "de l'MBR, podeu fer-ho executant (com a root) l'ordre següent:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Ha fallat la instaŀlació del GRUB. Voleu continuar?" debian/po/zh_TW.po0000664000000000000000000003433612524662415011221 0ustar # Copyright (C) 2009 Tetralet # This file is distributed under the same license as the grub2 package. # msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-04-22 17:31-0700\n" "Last-Translator: Vincent Chen \n" "Language-Team: Debian-user in Chinese [Big5] \n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "是否使用來自 menu.list 的 chainload 項目?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "GRUB 升級程式已在 /boot/grub 裡找到了 GRUB Legacy 的設定。" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "為了要能取代您系統上 Legacy 版的 GRUB,建議能修改 /boot/grub/menu.lst 來讓您" "原本的 GRUB Legacy 設定能載入 GRUB 2 影像檔。現在將要自動進行這個步驟。" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "在直接將 GRUB 2 安裝到 MBR(主要開機記錄)之前,建議您能同意在 menu.lst 裡先" "以 chainload 的方式啟動 GRUB 2,以確認新的 GRUB 2 設定能正常運作。" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "不管您的決定為何,您可以隨時讓 GRUB 2 取代舊有的 MBR 影像檔利用 root 身份執行" "以下指令:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB 安裝裝置:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "grub-pc 套件正在升級。這個選單讓您選擇 grub-install 要在哪一個裝置上自動執" "行,如果有的話。" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "在大多情況下建議自動執行 grub-install,以必免 GRUB 核心影像和 GRUB 模組或 " "grub.cfg 拖步。" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "如果您不確定 BIOS 用哪個磁碟作為開機磁碟,通常安裝 GRUB 到所有磁碟是個不錯的" "選擇。" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "注意:也可以將 GRUB 安裝到分割的開機記錄,這裡也提供了一些適當的分割選項。但" "是,GRUB 將被迫使用黑名單機制,導致可靠性降低,因此不建議使用。" #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB 的開機程式先前安裝到一個消失的磁碟上,或者它的唯一標識符因某種原因改變。" "確保安裝的 GRUB 核心映像和 GRUB 模組及 grub.cfg 的同步是非常重要的。請再次檢" "查以確保 GRUB 安裝到適當的開機裝置。" #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "將 GRUB 寫入開機裝置失敗了。是否繼續?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "在將 GRUB 安裝至以下裝置時失敗了:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "是否無論如何仍然繼續?但這樣話,您的電腦可能會無法正常開機。" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "將 GRUB 寫入開機裝置失敗了。再試一次?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "您也許可以把 GRUB 安裝至其它的裝置,只是您得設定好您的系統會從該裝置開機。否" "則,將中止 GRUB Legacy 的升級。" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "是否不安裝 GRUB 並繼續?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "您決定了不將 GRUB 安裝至任何裝置。如果您繼續,開機程式可能未經適當得設定,且" "當您電腦下次開機時,它會使用原本就位於開機磁區上的東西,而這可能會導至模組無" "法載入,或是無法處理目前所使用的設定檔。" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "如果您已在使用其它的開機程式,並且打算繼續使用;或是您的環境十分特殊所以不需" "要開機程式,您可以不在意並繼續進行。否則,您應當找個地方安裝 GRUB。" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "是否將 GRUB 2 從 /boot/grub 移除?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "您是否想將所有 GRUB 2 的檔案從 /boot/grub 移除?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "除非安裝另一個開機程式,否則將會造成系統無法開機。" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "是否要結束 GRUB 2 的轉換過程?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "這個系統上仍保有之前安裝 GRUB Legacy 所遺留下來的檔案,但它已有 GRUB 2 安裝於" "以下磁碟的開機磁區:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "這很可能表示再也用不到 GRUB Legacy 了,您應該替而升級這些裝置上的 GRUB 2 影像" "檔,並移除這些 GRUB Legacy 所遺留下來的檔案,以結束 GRUB 2 的轉換過程。如果您" "沒升級這些 GRUB 2 影像檔的話,它們可能和新的套件不相容,且會導致您的系統無法" "正常開機。" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "您應當逐漸得結束 GRUB 2 的轉換過程,除非這些開機記錄是由其它的作業系統所安裝" "的 GRUB 2 建立的。" #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux 命令列:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "以下的 Linux 命令列是由 /etc/default/grub,或是由 GRUB Legacy 的 menu.lst 中" "的 `kopt' 參數所擷取出來的。請確認它是否正確,若有必要請加以修改。此命令列可" "以留空。" #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linux 預設命令列:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "以下的字串將會用在預設的選單項目中做為 Linux 參數,但不會用於回復模式。" #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD 命令列:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "以下的 kFreeBSD 命令列是由 /etc/default/grub,或是由 GRUB Legacy 的 menu.lst " "中的 `kopt' 參數所擷取出來的。請確認它是否正確,若有必要請加以修改。此命令列" "可以留空。" #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "kFreeBSD 預設命令列:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "以下的字串將會用在預設的選單項目中做為 kFreeBSD 參數,但不會用於回復模式。" #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "已重新產生 /boot/grub/device.map" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "/boot/grub/device.map 這個檔案已使用不變的裝置名稱重新寫入。在大多數的狀況之" "下,如此可以有效得避免在日後還會有什麼變動,且也不會影響到 GRUB 所產生的選單" "項目。" #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "但由於您的系統上不只安裝了一顆硬碟,舊的裝置對應表可能還在使用中。請檢視您是" "否有還在使用著 GRUB 的 (hdN) 磁碟命名規則的自訂開機項目,若有必要請加以更新。" #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "如果您不了解這些訊息,或著沒有任何自訂的開機項目,您可以忽略這個訊息。" #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "不管您要採取何種方式,當您想讓 GRUB 2 可以由 MBR 直接啟動的話,您可以(以 " #~ "root 身份)執行以下的指令:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "GRUB 安裝失敗了。是否繼續?" debian/po/uk.po0000664000000000000000000004473612524662415010612 0ustar # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Олександр Яценко, 2010. # Yatsenko Alexandr , 2010. # Anton Gladky , 2011. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2010-12-09 23:57+0200\n" "Last-Translator: Yatsenko Alexandr \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.1\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Завантажити послідовно з menu.lst? " #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "Скрипт оновлення GRUB знайшов попередню Legacy версію в /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Перед повною заміною попередньої версії GRUB у вашій системі рекомендовано " "приєднати GRUB 2 як варіант завантаження у наявному меню GRUB Legacy. Цей " "крок може бути виконано автоматично зараз." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Рекомендовано спробувати послідовне завантаження GRUB 2 з menu.lst щоб " "переконатися, що ваш новий GRUB 2 функціонує, до того як встановити його " "напряму до MBR (Головного завантажувального сектору)" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Залежно від вашого бажання, можна замінити старий завантажувач в MBR на GRUB " "2 пізніше увівши наступну команду користувачем root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Дискові пристрої для встановлення GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Пакунок grub-pc було оновлено. Це меню дозволить вам обрати дискові пристрої " "з яких grub-install буде автоматично запускатися." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Автоматичний запуск grub-install рекомендовано в більшості випадків, щоб " "запобігти розсинхронізації встановленого базового ядра GRUB з його модулями " "чи grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Якщо ви не знаєте напевне, який дисковий пристрій призначено " "завантажувальним у вашому BIOS, можете встановити GRUB на всі наявні." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Увага: є можливим встановити GRUB до завантажувальних записів дискових " "розділів і деякі підходящі розділи запропоновано нижче. Проте, це заставить " "GRUB вжити механізм блокування, що зробить його менш надійним, а тому не " "рекомендується." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Завантажувач GRUB раніше було встановлено на дисковий пристрій, що наразі " "відсутній, або його унікальний ідентифікатор з якихось причин було змінено. " "Важливо переконатися, що встановлене базове ядро GRUB відповідає наявним " "модулям та grub.cfg. Будь ласка, перевірте знову чи GRUB записано на " "відповідні завантажувальні дискові розділи." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} МБ; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} МБ; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Не вдалося записати GRUB до завантажувального пристрою. Продовжити?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Не вдалося встановити GRUB до наступних дискових пристроїв:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Ви всеодно бажаєте продовжити? Не виключено, що ваш комп'ютер не зможе " "завантажитися нормально." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "Не вдалося записати GRUB до завантажувальних пристроїв. Спробувати знову?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Ви можете встановити GRUB до іншого завантажувального пристрою, але для " "цього потрібно переконатися, що система завантажиться з нього. Інакше, " "оновлення з GRUB Legacy не буде виконано." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Продовжити без встановлення GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Ви обрали не встановлювати GRUB на жоден пристрій. Якщо так продовжувати, " "завантажувач може бути не до кінця налаштований і при наступному запуску " "комп'ютера буде використано те, що є наразі у завантажувальному секторі. " "Якщо там виявиться попередня версія GRUB 2, вона, можливо, не зможе " "завантажити модулі чи опрацювати поточний конфігураційний файл." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Якщо ви використовуєте інший завантажувач і хочете залишити його, або маєте " "особливе оточення, де немає потреби в завантажувачі, можете продовжити, " "інакше маєте встановити GRUB." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Вилучити GRUB 2 з /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Ви бажаєте вилучити всі файли GRUB 2 з /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Ця дія зробить систему не здатною завантажитися, доки інший завантажувач не " "буде встановлено." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Завершити перехід до GRUB 2 зараз?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Ваша система містить встановлені файли з GRUB Legacy, але на наступних " "дисках присутній завантажувач GRUB 2:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Схоже, GRUB 2 більше не використовується, тому ви можете замінити його, " "оновивши образи GRUB 2 на цих дисках та завершити перехід до GRUB 2, " "вилучивши старі файли від GRUB Legacy. Якщо ви не оновите ці образи, вони " "можуть бути несумісні з новими пакунками і ваша система не зможе нормально " "завантажуватися." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Ви маєте повністю завершити перехід на GRUB 2, якщо ці завантажувальні " "записи було створено GRUB 2 іншої операційної системи." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Рядок параметрів ядра Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Наступний рядок параметрів ядра Linux було взято із /etc/default/grub чи з " "параметру 'kopt' в menu.lst із GRUB Legacy. Перевірте будь ласка його " "правильність і, за потреби, внесіть зміни. Рядок параметрів ядра може бути " "порожнім." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Типовий рядок параметрів ядра Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Даний рядок буде використано як параметри ядра Linux для типового пункту " "меню, проте не для режиму відновлення." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Рядок параметрів ядра kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Наступний рядок параметрів ядра kFreeBSD було взято із /etc/default/grub чи " "з параметру 'kopt' в menu.lst із GRUB Legacy. Перевірте будь ласка його " "правильність і, за потреби, внесіть зміни. Рядок параметрів ядра може бути " "порожнім." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Типовий рядок параметрів ядра kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Даний рядок буде використано як параметри ядра kFreeBSD для типового пункту " "меню, проте не для режиму відновлення." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map було створено наново" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Файл /boot/grub/device.map було переписано з використанням сталих імен " "пристроїв. В більшості випадків це значно зменшить потребу змінювати його в " "майбутньому і пункти меню завантажувача GRUB не будуть змінюватися." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Якщо в системі наявний більше, ніж один дисковий пристрій, можливо вона " "налаштована на стару карту пристроїв. Будь ласка, перевірте, чи не " "використано в користувацьких пунктах меню завантажувача нумерації дисків " "типу hdN, та оновіть їх, якщо потрібно." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Якщо ви не розумієте цього повідомлення, або не маєте користувацьких пунктів " "меню завантажувача, проігноруйте це повідомлення." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "В іншому випадку, якщо ви бажаєте завантажити GRUB 2 прямо до MBR, ви " #~ "можете зробити це, задавши (з правами root) наступну команду:" debian/po/POTFILES.in0000664000000000000000000000012612524662415011371 0ustar [type: gettext/rfc822deb] grub-pc.templates.in [type: gettext/rfc822deb] templates.in debian/po/eu.po0000664000000000000000000003550612524662415010577 0ustar # translation of grub2_1.99-5_eu.po to Basque # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Piarres Beobide , 2008. # Iñaki Larrañaga Murgoitio , 2008, 2009, 2010. # Iñaki Larrañaga Murgoitio , 2011. msgid "" msgstr "" "Project-Id-Version: grub2_1.99-5_eu\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-05-31 18:21+0200\n" "Last-Translator: Iñaki Larrañaga Murgoitio \n" "Language-Team: Basque \n" "Language: eu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Kargatu menu.lst fitxategitik?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "GRUB eguneratzeko script-ek GRUB zahar baten konfigurazioa aurkitu dute /" "boot/grub-en." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Sistemako GRUB zaharraren bertsioa behar bezala ordezkatzeko, gomendagarria " "da /boot/grub/menu.lst doitzea GRUB 2 dagoeneko instalatuta duzun GRUB " "zaharraren bidez kargatzeko. Urrats hau automatikoki egin daiteke orain." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Gomendagarria da GRUB 2 menu.lst bidez kargatzea onartzea, eta GRUB 2-ren " "konfigurazioak zure beharrak betetzen dituela egiaztatzea MBRan (Master Boot " "Record) idatzi aurretik." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Berdin dio zer erabakitzen duzun, MBRren irudi zaharra GRUB 2rekin ordeztu " "dezakezu supererabiltzaile (root) gisa honako komandoa exekutatuz:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB instalatzeko gailuak:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "grub-pc paketea eguneratzen ari da. Menu honek zer gailuentzako automatikoki " "grub-install exekutatzea nahi duzun hautatzea (hautatzen baduzu) uzten dizu." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Egoera gehienetan grub-install automatikoki exekutatzea gomendatzen da, " "instalatutako GRUBaren bihotzaren irudia GRUBaren modulu edo grub.cfg " "fitxategiarekin sinkronizatzetik kanpo gelditzea saihesteko." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Ez badakizu BIOSak zer gailu izendatuta daukan abioko gailu gisa, burutazio " "ona izan ohi da GRUB guztietan instalatzea." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Oharra: GRUB, partizio bateko abioko erregistroan instala daiteke baita ere, " "hori dela eta, partizio egoki batzuk eskaintzen dira hemen. Hala ere, honek " "GRUBek bloke-zerrenden mekanismoa erabiltzera derrigortzen du, ondorioz " "fidagarritasuna jaitsiz, eta gauzak horrela ez da bat ere gomendagarria." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Lehenago GRUB abioko kargatzailea agertzen ez den disko batean instalatu " "zen, edo edozer arrazoirengatik identifikatzaile esklusiboa aldatuta dauka. " "Garrantzitsua da instalatutako GRUBaren bihotzaren irudia sinkronizatuta " "egotea GRUBaren modulu eta grub.cfg fitxategiarekin. Egiaztatu ezazu berriro " "GRUB abioko gailu egokian idatzi dela." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Huts egin du GRUB abioko gailuan idaztean - jarraitu?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUBek huts egin du honako gailuetan instalatzean:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Jarraitzea nahi duzu dena den? Jarraituz gero, baliteke ordenagailua ongi ez " "abiaraztea." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Huts egin du GRUB abioko gailuan idaztean - saiatu berriro?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "GRUB beste gailu batean instalatzeko aukera duzu, hala ere, sistema beste " "gailu horretatik abiatzeko ahalmena duela egiaztatu behar duzu. Bestela, " "'GRUB Legacy' eguneratzea bertan behera utz daiteke." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Jarraitu GRUB instalatu gabe?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "GRUB inolako gailuetan ez instalatzea aukeratu duzu. Jarraitzen baduzu, " "baliteke abioko kargatzailea ongi konfiguratuta ez egotea, eta abioko " "sektorean aurretik zegoena erabiliko da ordenagailua hurrengo batean " "abiatzean. Abioko sektorean GRUB 2ren aurreko bertsio bat egonez gero, agian " "ezin izango du moduluak kargatu edo uneko konfigurazioko fitxategia kudeatu." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Unean bestelako abioko kargatzaile bat erabiltzean ari bazara, eta horrela " "jarraitzea nahi baduzu, edo hau abioko kargatzailearen beharrik ez duen " "ingurune berezi bat bada, aurrera jarrai dezakezu. Bestela, GRUB nonbaiten " "instalatu beharko zenuke." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Kendu 'GRUB 2' /boot/grub direktoriotik?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Nahi duzu GRUB 2ren fitxategi guztiak /boot/grub-etik kentzea?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Honek sistema ezin abiaraztea eragingo du bestelako abioko kargatzaile bat " "instalatzen ez bada." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Amaitu GRUB 2-rako bihurketa orain?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Sistemak oraindik 'GRUB Legacy' abioko kargatzailearen fitxategiak ditu " "oraindik, baina orain GRUB 2 bertsioko abioko erregistroak ere baditu honako " "diskoetan:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Badirudi 'GRUB Legacy' ez denez aurrerantzean erabiliko, disko hauetako GRUB " "2 bertsioko irudiak eguneratu eta 'GRUB Legacy'-ko fitxategiak kenduz GRUB 2-" "ren eguneraketa amaitu beharko zenuke. GRUB 2-ko irudi hauek ez badituzu " "eguneratzen, pakete berriekin ez dira bateragarriak izango eta sistema ongi " "abiatzea galaraz dezake." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "GRUB 2-rako bihurketa amaitu beharko zenuke, abioko erregistro hauek beste " "sistema eragile batzuetako GRUB 2 bertsioaren instalazioan ez badira sortuak " "izan." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux-eko komando-lerroa:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Linux-eko komando-lerro hau /etc/default/grub edo GRUB zaharraren menu.lst " "fitxategiko 'kopt' parametrotik atera da. Egiaztatu zuzena dela, eta " "eraldatu behar izanez gero. Komando-lerroa hutsik egotea baimenduta dago." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linux-eko komando-lerro lehenetsia:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Honako katea menuko sarrera lehenetsiaren Linux-eko parametro gisa erabiliko " "da, baina ez berreskuratzeko moduan." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "KFreeBSD-ko komando-lerroa:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "KFreeBSD-ko komando-lerro hau /etc/default/grub edo GRUB zaharraren menu.lst " "fitxategiko 'kopt' parametrotik atera da. Egiaztatu zuzena dela, eta " "eraldatu behar izanez gero. Komando-lerroa hutsik egotea baimenduta dago." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "KFreeBSD-ko komando-lerro lehenetsia:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Honako katea menuko sarrera lehenetsiaren KFreeBSD-ko parametro gisa " "erabiliko da, baina ez berreskuratzeko moduan." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map berriro sortu da" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "/boot/grub/device.map fitxategia berriro idatzi da gailuen izen egonkorrak " "erabiltzeko. Gehienetan, etorkizunean hau aldatzeko beharra asko murriztu " "beharko luke, eta GRUBek sortutako menuko sarrerei ez die eragingo." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Hala ere, sisteman disko bat baino gehiago dagoenez, baliteke sistema " "gailuen mapa zaharrean mende egotea. Egiaztatu ezazu GRUBen unitateko " "zenbaketan oinarrituta abioaren menuko sarrera pertsonalizaturen bat duzun " "edo ez, eta egunera itzazu beharrezkoa izanez gero." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Mezu hau ez baduzu ulertzen, edo abioaren menuko sarrera pertsonalizaturik " "ez baduzu, ezikusi egin diezaiokezu mezu honi." debian/po/km.po0000664000000000000000000005772112524662415010600 0ustar # translation of grub_debian_po.po to Khmer # Khoem Sokhem , 2012. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. msgid "" msgstr "" "Project-Id-Version: grub_debian_po\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-04-05 15:38+0700\n" "Last-Translator: Khoem Sokhem \n" "Language-Team: Khmer \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" "X-Language: ki-KH\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "ផ្ទុក​ពី menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "GRUB ធ្វើ​ឲ្យ​ស្គ្រីប​ប្រសើរ​ឡើង បាន​រកឃើញ​ការ​រៀបចំ​ចាស់ៗ​របស់ GRUB នៅ​ក្នុង /boot/grub ។" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "ដើម្បី​ជំនួស​កំណែ​ចាស់ៗ​របស់ GRUB នៅ​ក្នុង​ប្រព័ន្ធ​របស់​អ្នក វា​បានផ្ដល់​អនុសាសន៍​ឲ្យ​កែសម្រួល /boot/grub/" "menu.lst ដើម្បី​ផ្ទុក​រូប​ភាព​ចាប់ផ្ដើម GRUB 2 ពី​ការ​រៀបចំ​ចាស់ៗ​នៃ​ GRUB ដែល​មាន​ស្រាប់​របស់​អ្នក ។ " "ជំហាន​នេះ​អាច​ត្រូវ​បាន​អនុវត្ត​ដោយ​ស្វ័យ​ប្រវត្ត​ឥឡូវ ។" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "វា​បានផ្ដល់​អនុសាសន៍​ឲ្យ​អ្នក​ទទួល​យក​​កា​រផ្ទុក​ GRUB 2 ពី menu.lst ហើយ​ផ្ទៀងផ្ទាត់​ថា​ការ​រៀបចំ GRUB 2 " "ថ្មី​ដំណើរការ​មុន​ពេល​វា​ត្រូវ​បាន​សរសេរ​ទៅ​កាន់ MBR (Master Boot Record) ។" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "មិន​ថា​អ្នក​សម្រេចចិត្ត​ថា​ម៉េច​ក៏​ដោយ អ្នក​អាច​ជំនួស​រូបភាព MBR ចាស់​ដោយ​ GRUB 2 ពេល​​ក្រោយ ដោយ​ប្រើ​ពាក្យ​" "បញ្ជា​​ដូ​ចខា​ងក្រោម​ជា root ៖" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB ដំឡើង​ឧបករណ៍ ៖" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "កញ្ចប់ grub-pc កំពុង​ត្រូវ​បាន​ធ្វើ​ឲ្យ​ប្រសើរឡើង ។ ម៉ឺនុយ​នេះ​អនុញ្ញាត​ឲ្យ​អ្នក​ជ្រើស​ឧបករណ៍​ណាមួយ​ ដែល​អ្នក​" "ចង់​ grub-install ដំណើរការ​ដោយ​ស្វ័យ​ប្រវត្តិ ប្រសិនបើ​មាន ។" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "ករណី​ភាគ​ច្រើន​កា​រដំណើរការ grub-install ដោយ​ស្វ័យ​ប្រវត្តិ​ត្រូវ​បាន​ផ្ដល់​អនុសាសន៍ ដើម្បីការពារ​រូបភាព " "GRUB សំខាន់​ដែល​បាន​ដំឡើង​ពី​ការ​ធ្វើ​សមកាលកម្ម​ជា​មួយ​ម៉ូឌុល GRUB ឬ grub.cfg ។" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "ប្រសិនបើ​អ្នក​​មិន​ប្រាកដ​ថា​ដ្រាយ​ណាមួយ​ត្រូវ​បាន​ផ្ដល់​ជា​ដ្រាយ​ចាប់ផ្ដើម ដោយ​ BIOS របស់​អ្នក វា​ជា​គំនិត​ដ៏​ល្អ​គឺ​" "ត្រូវ​ដំឡើង​ GRUB ទៅ​កាន់​ពួក​វា​ទាំងអស់ ។" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "ចំណាំ ៖ អាច​ដំឡើង GRUB ទៅ​ភាគ​​ចាប់ផ្ដើម​បាន​ផង​ដែរ ភាគ​ដែលសមស្រប​មួយ​ចំនួន​ត្រូវ​បាន​ផ្ដល់​នៅ​ទីនេះ ។ ទោះ​" "ជា​យ៉ាង​ណា​ក៏​ដោយ វា​បង្ខំ GRUB ឲ្យ​ប្រើ​យន្តការ​បញ្ជី​ទប់ស្កាត់ ដែល​ធ្វើ​ឲ្យ​វា​អាច​ទុកចិត្ត​បាន​តិចតួច ហើយ​" "ដូច្នេះ​មិន​ត្រូវ​បាន​ផ្ដល់​អនុសាសន៍​ទេ ។" #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "កម្មវិធី​ចាប់ផ្ដើម​ប្រព័ន្ធ GRUB ត្រូវ​បាន​ដំឡើង​ពី​មុន ទៅ​ថាស​ដែល​លែង​ប្រើ ឬ​អត្តសញ្ញាណ​តែ​មួយ​គត់​របស់​វា​បាន​" "ផ្លាស់ប្ដូរ​ដោយ​​មូលហេតុ​មួយ​ចំនួន ។ វា​មាន​សារៈ​សំខាន់​ត្រូវ​​ប្រាកដថា រូបភាព​ GRUB ដែល​បាន​ដំឡើង​ធ្វើ​" "សមកាលកម្ម​ជា​មួយ​ម៉ូឌុល GRUB និង grub.cfg ។ សូម​ពិនិត្យ​មើល​ម្ដង​ទៀត ដើម្បី​ប្រាកដថា GRUB ត្រូវ​បាន​" "សរសេរ​ទៅ​កាន់​ឧបករណ៍​ចាប់ផ្ដើម​ដែល​ត្រឹមត្រូវ ។" #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "បាន​បរាជ័យ​ក្នុង​ការ​សរសេរ​ GRUB ទៅ​​ឧបករណ៍​ចាប់ផ្ដើម បន្ត ?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB បាន​បរាជ័យ​ក្នុង​ការ​ដំឡើង​ឧបករណ៍​ដូ​ចខាង​ក្រោម ៖" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "អញ្ចឹង តើ​អ្នក​ចង់​បន្ត​ដែរ​ឬទេ ? ប្រសិន​បើ​អ្នក​បន្ត កុំព្យូទ័រ​របស់​អ្នក​មិន​អាច​ចាប់ផ្ដើម​បាន​ត្រឹមត្រូវ​ទេ ។" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "បាន​បរាជ័យ​ក្នុង​ការ​សរសេរ GRUB ទៅ​ឧបករណ៍​ចាប់ផ្ដើម ព្យាយាម​ម្ដង​ទៀត ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "អ្នក​អាច​ដំឡើង GRUB ទៅ​ឧបករណ៍​មួយ​ចំនួន​បាន ទោះ​បី​ជា​អ្នក​​ដឹង​ថា ប្រព័ន្ធ​របស់​អ្នក​នឹង​ចាប់ផ្ដើម​ពី​ឧបករណ៍​នោះ​ក៏​" "ដោយ ។ បើ​មិន​ដូច្នេះ​ទេ ការ​ធ្វើ​ឲ្យ​ប្រសើរ​ឡើង​ពី GRUB ចាស់ៗ​នឹង​ត្រូវ​បាន​បោះបង់ ។" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "បន្ត​ដោយ​មិន​ដំឡើង GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "អ្នក​បាន​ជ្រើសរើស​ថា​មិន​ដំឡើង​ GRUB ក្នុង​ឧបករណ៍​ណាមួយ​ទេ ។ ប្រសិនបើ​អ្នក​បន្ត ​កម្មវិធី​ចាប់ផ្ដើម​ប្រព័ន្ធ​អាច​" "មិន​​ត្រូវ​បាន​កំណត់​រចនាសម្ព័ន្ធ​ត្រឹមត្រូវ​ទេ ហើយ​នៅ​ពេល​កុំព្យូទ័រ​នេះ​ចាប់ផ្ដើម​ពេល​ក្រោយ វា​នឹង​ប្រើ​អ្វី​ដែល​មាន​" "ពីមុន​នៅ​ក្នុង​ផ្នែក​ចាប់ផ្ដើម ។ ប្រសិន​បើ​គ្មាន​កំណែ GRUB 2 ពី​មុន​នៅ​ក្នុង​ផ្នែក​ចាប់ផ្ដើម​ទេ វា​​មិន​អាច​ផ្ទុក​" "ម៉ូឌុល ឬ​ដោះស្រាយ​ឯកសារ​កំណត់​រចនាសម្ព័ន្ធ​បច្ចុប្បន្ន​បាន​ទេ ។" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "ប្រសិ​ន​បើ​អ្នក​កំពុង​ប្រើ​កម្មវិធី​ចាប់ផ្ដើម​ប្រព័ន្ធ​ផ្សេង​ហើយ ហើយ​ចង់​បន្ត​ប្រើ​វា​ទៀត​នោះ ឬ​ប្រសិន​បើ​មាន​បរិស្ថាន​" "ពិសេស​ដែល​អ្កន​មិន​ត្រូវ​ការ​កម្មវិធី​ចាប់ផ្ដើម​ប្រព័ន្ធ នោះ​អ្នក​គួរ​បន្ត ។ បើ​មិន​ដូច្នេះ​ទេ អ្នក​គួរ​ដំឡោះង " "GRUB នៅ​កន្លែង​ណាមួយ ។" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "យក GRUB 2 ចេញ ពី /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "តើ​អ្នក​ចង់​​យក​ឯកសារ​របស់ GRUB 2 ទាំង​អស់​ចេញ​ពី /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "វា​នឹង​ធ្វើ​ឲ្យ​ប្រព័ន្ធ​មិន​អាច​ចាប់ផ្ដើម​បាន លុះត្រា​តែ​​ដំឡើង​កម្មវិធី​ចាប់ផ្ដើម​ប្រព័ន្ធ​ផ្សេង ។" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "បញ្ចប់ការ​បម្លែងទៅ​ GRUB 2 ឥឡូវ ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "ប្រព័ន្ធ​នេះ​នៅ​តែ​មាន​ឯកសារ​ពី​កម្មវិធី​ចាប់ផ្ដើម​ប្រព័ន្ធ​ចាស់​ៗ​របស់ GRUB ដែល​បាន​ដំឡើង ប៉ុន្តែ​ឥឡូវ​ក៏​មាន​ផ្នែក​" "ចាប់ផ្ដើម GRUB 2 បាន​ដំឡើង​នៅ​ក្នុង​ថាស​ទាំង​នេះ​ដែរ ៖" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "វា​ហាក់បី​ដូចជា​ភាព​ចាស់ៗ​របស់​ GRUB លែង​ប្រើ​ហើយ ហើយ​អ្នក​គួរ​ជំនួស​ការ​ធ្វើ​ឲ្យ​រូបភាព GRUB 2 ប្រសើ​រឡើង​" "នៅ​លើ​ថាស​ទាំង​នេះ ហើយ​បញ្ចប់​ការ​បម្លែង​ទៅ GRUB 2 ដោយ​​យក​ឯកសារ​ចាស់ៗ​របស់ GRUB ចាស់​ចេញ ។ ប្រសិន​បើ​" "អ្នក​មិន​ធ្វើ​ឲ្យ​រូបភាព GRUB 2 ទាំង​នេះ​ប្រសើ​រឡើង​ទេ នោះ​ពួក​វា​អាច​មិន​ត្រូវ​គ្នា​ជា​មួយ​នឹង​កញ្ចប់​ថ្មីៗ ហើយ​" "ធ្វើ​ឲ្យ​ប្រព័ន្ធ​របស់​អ្នក​បញ្ឈប់​ការ​ចាប់ផ្ដើម​ ។" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "ជា​ទូទៅ អ្នក​គួរ​តែ​បញ្ចប់​ការ​បម្លែង​ទៅ GRUB 2 លុះត្រា​តែ​ផ្នែក​ចាប់ផ្ដើម​ត្រូវ​បាន​បង្កើត​ដោយ​ការ​ដំឡើង " "GRUB 2 នៅ​លើ​ប្រព័ន្ធ​ប្រតិបត្តិការ​ផ្សេង ។" #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "ពាក្យ​បញ្ជា​លីនុច ៖" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "ពាក្យ​បញ្ជា​លីនុច​ដូច​ខាង​ក្រោម​ត្រូវ​បាន​ដកស្រង់​ចេញ​ពី /etc/default/grub ឬ​ប៉ារ៉ាម៉ែត្រ `kopt' នៅ​ក្នុង " "menu.lst ចាស់​របស់​ GRUB ។ សូម​ផ្ទៀងផ្ទាត់​ថា​តើ​វា​ត្រឹមត្រូវ​ដែរឬទេ ហើយ​កែប្រែ​វា​ប្រសិន​បើ​ចាំបាច់ ។ " "ពាក្យ​បញ្ជា​ត្រូវ​បាន​អនុញ្ញាត​ឲ្យ​ទទេរ ។" #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "ពាក្យ​បញ្ជា​លំនាំ​ដើម​របស់​លីនុច ៖" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "ឃ្លា​ដូច​ខាង​ក្រោម​នឹង​ត្រូវ​បាន​ប្រើ​ជា​ប៉ារ៉ាម៉ែត្រ​លីនុច​សម្រាប់​ធាតុ​ម៉ឺនុយ​លំនាំដើម ប៉ុន្តែ​មិន​សម្រាប់​របៀប​សង្គ្រោះ​" "ទេ ។" #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "ពាក្យ​បញ្ជា kFreeBSD ៖" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "ពាក្យ​បញ្ជា kFreeBSD ដូច​ខាង​ក្រោម​ត្រូវ​បាន​ដកស្រង់​ចេញ​ពី /etc/default/grub ឬ menu.lst ចាស់ៗ​" "នៅ​ក្នុង GRUB ។ សូម​ផ្ទៀងផ្ទាត់​ថា​វា​ត្រឹមត្រូវ ។ ពាក្យ​បញ្ជា​ត្រូវ​បាន​អនុញ្ញាត​ឲ្យ​ទទេ ។" #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "ពាក្យ​បញ្ជា​លំនាំដើម​របស់ kFreeBSD ៖" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "ឃ្លា​ដូច​ខាង​ក្រោម​នឹង​ត្រូវ​បាន​ប្រើ​ជា​ប៉ារ៉ាម៉ែត្រ kFreeBSD សម្រាប់​ធាតុ​ម៉ឺនុយ​លំនាំដើម ប៉ុន្តែ​មិន​សម្រាប់​របៀប​" "សង្គ្រោះ​ទេ ។" #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map ត្រូវ​បាន​បង្កើត​ឡើង​វិញ" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "ឯកសារ /boot/grub/device.map ត្រូវ​បាន​សរសេរ​ឡើង​វិញ ដើម្បី​ប្រើ​ឈ្មោះ​ឧបករណ៍​ថេរ ។ ក្នុង​ករណី​ភាគ​" "ច្រើន វា​គួរ​កាត់​បន្ថយ​តម្រូវការ ដើម្បី​ផ្លាស់ប្ដូរ​វា​​នា​ពេល​អនាគត់ ហើយ​ធាតុ​ម៉ឺមុយ​ចាប់ផ្ដើម​ដែល​បាន​បង្កើត​" "ដោយ GRUB មិន​គួរ​ប៉ះពាល់​ទេ ។" #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "ទោះ​ជា​យ៉ាង​ណា​ក៏​ដោយ ព្រោះ​ថា​មាន​ថាស​ច្រើន​ជាង​មួយ​នៅ​ក្នុង​ប្រព័ន្ធ ​ប្រព័ន្ធ​អាស្រ័យ​លើ​ការ​ផ្គូផ្គង​ឧបករណ៍​ចាស់ " "។ សូម​ពិនិត្យ​មើល​ថាតើ មាន​ធាតុ​​ម៉ឺនុយ​ចាប់ផ្ដើម​ផ្ទាល់ខ្លួន​ដែល​អាស្រ័យ​លើ​​ចំនួន​ដ្រាយ GRUB's (hdN) ហើយ​ធ្វើ​" "បច្ចុប្បន្ន​ភាព​ពួក​វា​ប្រសិនបើ​ចាំបាច់ ។" #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "ប្រសិន​បើ​អ្នក​មិន​យល់​សារ​នេះ​ទេ ឬ​ប្រសិនបើ​គ្មាន​ធាតុម៉ឺនុយ​ចាប់ផ្ដើម​ផ្ទាល់​ខ្លួន អ្នក​អាច​មិនអើពើ​សារ​នេះ ។" debian/po/ast.po0000664000000000000000000003576312524662415010762 0ustar # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-01-27 11:10+0100\n" "Last-Translator: Mikel González \n" "Language-Team: Asturian \n" "Language: ast\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "¿Cadena de carga dende menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "El scripts d'actualización GRUB detectó una configuración GRUB Legacy en /" "boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Cola fin de trocar la versión Legacy de GRUB nel to sistema, ye recomendable " "que /boot/grub/menu.lst seya axustáu a la cadena de carga GRUB 2 dende la to " "configuración Legacy GRUB existente. Esti pasu puede ser fechu " "automáticamente agora." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Ye recomendable que aceptes la cadena de carga GRUB 2 dende'l menu.lst, y " "compruebes que la to nueva configuración de GRUB 2 ye funcional pa ti, " "anantes de que lo instales directamente nel to MBR (Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Independientemente de la to decisión, puedes trocar la imaxe vieya MBR con " "GRUB 2 más tarde executando como root el comandu que vien darréu:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB falló al instalar nos siguientes preseos:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Anovóse'l paquete grup-pc. Esti menú val pa esbillar en que preseos quie " "que'l grub-install s'execute automáticamente, si hai dalgún." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Executar grub-install automaticamente ye recomendable na mayoría de les " "situaciones, pa evitar que la imaxe del motor de GRUB quede ensin " "sincronizase colos módulos de GRUB o grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Si nun tas seguru/a de que discu t'asignau como discu d'arranque pola BIOS, " "ye una bona idea instalar GRUB en tolos discos." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Nota: puedes instalar GRUB nos rexistros d'arranque de les particiones " "tamién, y úfrense dalgunes particiones apropiaes. Sicasí, esto fuercia a " "GRUB a usar un mecanismu de llista de torgues, que lo fai menos fiable poro " "nun ye recomendable." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "El xestor d'arranque GRUB instalóse nun discu que nun ta presente, o que " "cambió d'identificador únicu por dalguna razón. Ye importante asegurase de " "que la imaxe del motor de GRUB sigui sincronizada colos módulos de GRUB y " "grub.cfg. Por favor prueba otra vuelta p'asegurate de que GRUB ta escritu " "nel preséu d'arranque correutu." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Fallu al escribir GRUB al preséu d'arranque - ¿siguir?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Falló GRUB al instalar nos siguientes preseos:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "¿Quies siguir igualmente? Si quies, el to ordenador podría nun arrancar bien." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "La instalación de GRUB falló. ¿Intentalo otra vegada?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Puedes instalar GRUB a otru preséu, aunque deberíes comprobar que'l to " "sistema arrancará dende esi preséu. De lo contrario, l'anovamientu de GRUB " "encaboxarase." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "¿Siguir ensin instalar GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Escoyistes nun instalar GRUB en dengún preséu. De siguir, el xestor " "d'arranque podría nun tar configuráu dafechu, y nel siguiente aniciu del " "ordenador usarás lo que teníes previamente nel sector d'arranque. Si hai un " "versión anterior de GRUB 2 nel sector d'arranque, podría ser capaz de cargar " "módulos o remanar el ficheru de configuración actual." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Si ya tas executando un xestor d'arranque distintu y quies siguir " "faciéndolo, o si ye un ambiente especial onde nun necesites un xestor " "d'arranque, entós puedes siguir. D'otra miente, deberíes instalar GRUB en " "dalgún sitiu." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "¿Desaniciar GRUB 2 de /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "¿Quiés desaniciar tolos ficheros de GRUB 2 de /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Esto fadrá qué nun puedas aniciar el sistema a nun ser qu'instales otru " "xestor d'arranque." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "¿Finar agora conversión a GRUB 2?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Esti sistema tovía tien ficheros del xestor d'arranque GRUB instaláu, pero " "agora tamién registros d'arranque GRUB 2 instaláu n'estos discos:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Parez probable que GRUB ya nun ta n'usu, y que deberíes anovar les imáxenes " "de GRUB 2 d'estos discos y finar la conversión a GRUB 2, desaniciando vieyos " "ficheros heredaos de GRUB. Si nun anoves estes imáxenes de GRUB, entós " "pueden ser incompatibles colos nuevos paquetes y facer que'l to sistema nun " "arranque correutamente." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "En xeneral, deberíes finar la conversión a GRUB 2 a menos qu'estos rexistros " "d'arranque fueren creaos por una instalación de GRUB 2 en dalgún otru " "sistema operativu." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linia comandos Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La siguiente llinia de comandu Linux salió de /etc/default/grub o del " "parámetru `kopt' nel menú Legacy GRUB menu.lst. Por favor, comprueba que ye " "correuto, y modificalo si ye necesario. La llinia de comandu puede tar erma." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linia comandos por defeutu de Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "La siguiente cadena será usada como parámetros Linux pa la entrada del menú " "por defeutu, pero non pal mou recuperación." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Linia comandos kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La siguiente llinia de comandu kFreeBSD salió de /etc/default/grub o del " "parámetru `kopt' nel menú Legacy GRUB menu.lst. Por favor, comprueba que ye " "correuto, y modificalo si ye necesario. La lliniea de comandu puede tar erma." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Llínia comandos por defeutu kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "La siguiente cadena será usada cómo parametros kFreeBSD pa la entrada del " "menú por defeutu, pero non pal mou recuperación." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map foi xeneráu" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "El ficheru /boot/grub/device.map foi sobroescritu pa usar nomes estables pal " "preséu. Na mayoría de los casos, esto va a amenorgar considerablemente la " "necesidá de camudar nel futuru, y les entraes del menú d'arranque GRUB " "xeneraos nun deberíen vese afectaes." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Sicasí, ya tienes más d'un discu nel to sistema, ye posible que dependieres " "del mapa antigüu del preséu. Por favor, comprueba si tienes o non entraes " "d'arranque del menú personalizaes que se basen na númberación de la unidá " "GRUB's (hdN), y anovalos si ye necesario." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Si nun entiendes esti mensaxe, o si nun tienes nenguna entrada personalizada " "nel menú d'arranque, puedes ignorar esti mensaxe." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "En cualisquier casu, cuando quieras que GRUB 2 seya cargáu directamente " #~ "dende'l MBR, puedes facelo col siguiente comandu (como root):" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "La instalación de GRUB falló. ¿Siguir?" debian/po/fi.po0000664000000000000000000003621312524662415010560 0ustar # Esko Arajärvi , 2009, 2010. msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-08-24 19:21+0300\n" "Last-Translator: Timo Jyrinki \n" "Language-Team: Finnish \n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Finnish\n" "X-Poedit-Country: FINLAND\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Ladataanko ketjutettuna tiedostosta menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "GRUBin päivityskomentosarjat ovat löytäneet vanhoja GRUB-asetuksia " "tiedostosta /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Järjestelmässä olevan vanhan GRUB-version korvaamiseksi on suositeltavaa " "muokata tiedostoa /boot/grub/menu.lst siten, että GRUB 2 ladataan olemassa " "olevista vanhoista GRUB-asetuksista. Tämä voidaan tehdä automaattisesti nyt." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "On suositeltavaa, että hyväksyt GRUB 2:n ketjutetun lataamisen tiedostosta " "menu.lst ja varmistat uusien GRUB 2 -asetusten toimivuuden ennen kuin " "asennat ne pääkäynnistyslohkoon (MBR)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Riippumatta valinnasta vanha MBR voidaan korvata GRUB 2:lla myöhemmin " "suorittamalla seuraava komento pääkäyttäjänä:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Laitteet joille GRUB asennetaan:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "grub-pc-pakettia päivitetään. Tästä valikosta voit valita, mille laitteille " "grub-install suoritetaan automaattisesti." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "grub-install:n suorittaminen automaattisesti on suositeltavaa useimmissa " "tilanteissa, jotta asennettu GRUB-ydin ei tulisi epäyhteensopivaksi GRUB-" "moduulien tai grub.cfg:n kanssa." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Jos et ole varma, mikä asema on määritelty käynnistysasemaksi koneen BIOS-" "asetuksissa, on usein hyvä ajatus asentaa GRUB kaikille asemille." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Huomaa: GRUB voidaan asentaa myöt osion käynnistystietoihin, ja joitain " "sopivia osioita on ohessa tarjolla. Tämä kuitenkin pakottaa GRUBin " "käyttämään lohkoluettelomekanisia, mikä tekee siitä vähemmän luotettavan " "eikä ole suositeltavaa." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB-käynnistyslatain oli aiemmin asennettuna levylle, jota ei ole enää " "käytössä tai jonka yksilöllinen tunniste on muuttunut jostain syystä. On " "tärkeää varmistaa, että asennettu GRUB-ydinkuva pysyy ajan tasalla GRUB-" "moduulien ja grub-cfg:n kanssa. Tarkista vielä uudelleen varmistaaksesi, " "että GRUB kirjoitetaan oikeille käynnistyslaitteille." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "GRUBin kirjoittaminen käynnistyslaitteelle epäonnistui. Jatketaanko?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUBia ei voitu asentaa seuraaville laitteille:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Valitse haluatko jatkaa tästä huolimatta. Jos jatkat, järjestelmä ei " "välttämättä käynnisty kunnolla." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "GRUBin kirjoittaminen käynnistyslaitteelle epäonnistui. Yritetäänkö " "uudelleen?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Voit ehkä asentaa GRUBin jollekin toiselle levylle. Varmista tällöin, että " "järjestelmäsi voidaan käynnistää kyseiseltä levyltä. Muussa tapauksessa " "GRUBin aiemman version päivitys perutaan." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Jatketaanko asentamatta GRUBia?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Päätit olla asentamatta GRUBia millekään laitteelle. Jos jatkat, " "alkulatausohjelman asetukset saattavat olla väärät ja kun kone käynnistetään " "uudelleen seuraavan kerran, se käyttää käynnistyslohkon aiempia asetuksia. " "Jos käynnistyslohkossa on GRUB 2:n aiempi versio, se ei välttämättä pysty " "lataamaan moduuleja tai käsittelemään nykyistä asetustiedostoa." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Jos käytät jo muuta alkulatausohjelmaa ja haluat jatkaa sen käyttöä tai jos " "käytössäsi on erityinen ympäristö, jossa et tarvitse alkulatausohjelmaa, " "voit jatkaa asennusta. Muussa tapauksessa sinun tulisi asentaa GRUB johonkin." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Poistetaanko GRUB 2 kohteesta /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Haluat poistaa kaikki GRUB 2 -tiedostot kohteesta /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Tämä tekee järjestelmästä käynnistyskelvottoman, ellei toista " "käynnistyslatainta ole asennettu." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Saatetaanko siirtyminen GRUB 2:een loppuun nyt?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Järjestelmässä on edelleen GRUBin aiemman version tiedostoja, mutta myös " "GRUB 2:n käynnistystiedot on asennettu seuraaville levyille:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "GRUBin aiempi versio ei luultavasti ole enää käytössä ja näillä levyillä " "olevat GRUB 2:n levykuvat tulisi päivittää ja siirtyminen GRUB 2:een saattaa " "loppuun poistamalla vanhat GRUB-tiedostot. Jos et päivitä GRUB 2:n kuvia, " "uusien pakettien kanssa voi tulla yhteensopivuusongelmia ja järjestelmän " "käynnistys ei ehkä toimi oikein." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Yleisesti ottaen siirtyminen GRUB 2:een tulisi saattaa loppuun ellei näitä " "käynnistystietoja luotu johonkin toiseen käyttöjärjestelmään asennetulla " "GRUB 2:lla." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linuxin komentorivi:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "GRUBin aiemman version tiedostosta menu.lst parametrista ”kopt” tai " "tiedostosta /etc/default/grub löydettiin seuraava Linuxin komentorivi. " "Varmista, että se on kunnossa ja muuta sitä tarvittaessa. Komentorivin on " "sallittua myös olla tyhjä." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linuxin oletuskomentorivi:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Seuraavaa merkkijonoa käytetään Linuxin käynnistysvalikon oletusvalinnan " "parametreina, mutta ei toipumistilassa." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD:n komentorivi:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "GRUBin aiemman version tiedostosta menu.lst parametrista ”kopt” tai " "tiedostosta /etc/default/grub löydettiin seuraava kFreeBSD:n komentorivi. " "Varmista, että se on kunnossa ja muuta sitä tarvittaessa. Komentorivin on " "sallittua myös olla tyhjä." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "kFreeBSD:n oletuskomentorivi:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Seuraavaa merkkijonoa käytetään kFreeBSD:n käynnistysvalikon oletusvalinnan " "parametreina, mutta ei toipumistilassa." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map on luotu uudelleen" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Tiedosto /boot/grub/device.map on kirjoitettu uudelleen käyttäen pysyviä " "laitenimiä. Useimmissa tapauksissa tämän pitäisi huomattavasti vähentää " "tarvetta sen muuttamiseen ja GRUBin luomien käynnistysvalikon rivien pitäisi " "toimia edelleen." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Koska järjestelmässä kuitenkin on useampia levyjä, on mahdollista, että " "järjestelmä on riippuvainen vanhasta laitekartasta. Tarkista onko " "käynnistysvalikossa rivejä, joissa käytetään GRUBin laitenumerointia (hdN), " "ja päivitä ne tarvittaessa." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Jos et ymmärrä tätä viestiä tai käynnistysvalikossa ei ole erityisiä rivejä, " "voit jättää tämän viestin huomiotta." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Kun haluat asentaa GRUB 2:n latautumaan suoraan pääkäynnistyslohkosta, " #~ "voit joka tapauksessa tehdä sen ajamalla pääkäyttäjänä seuraavan komennon:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "GRUBin asennus epäonnistui. Jatketaanko?" debian/po/sl.po0000664000000000000000000003555012524662415010603 0ustar # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-04-27 12:42+0100\n" "Last-Translator: Vanja Cvelbar \n" "Language-Team: Slovenian \n" "Language: sl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n" "%100==4 ? 3 : 0);\n" "X-Poedit-Language: Slovenian\n" "X-Poedit-Country: SLOVENIA\n" "X-Poedit-SourceCharset: utf-8\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Verižno nalaganje iz menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "Skript za nadgradnjo je zaznal namestitev GRUB Legacy v /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Da zamenjate različico GRUB Legacy na vašem sistemu vam priporočamo, da se /" "boot/grub/menu.lst spremeni tako, da verižno naloži GRUB 2 iz vaše obstoječe " "namestitve GRUB Legacy. To dejanje lahko zdaj izvedete samodejno." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Priporočamo vam, da sprejmete verižno nalaganje GRUB 2 iz datoteke menu.lst " "in preverite delovanje namestitve GRUB2 preden ga namestite na MBR (Master " "Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Kakorkoli se odločite, stari MBR lahko kasneje vedno zamenjate z GRUB 2, če " "izvedete kot root sledeči ukaz:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Namestitvene naprave za GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Nadgrajevanje paketa grub-pc. Ta meni vam omogoči izbiro naprav za katere " "želite samodejno zagnati grub-install." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "V večini primerov je priporočen samodejni zagon grub-install, da preprečite " "neskladja med jedrom GRUBa in moduli ali grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "V primeru, da niste prepričani kateri pogon je označuje vaš BIOS za " "zagonskega, je ponavadi dobro, da namestite GRUB kar na vse." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Opomba: GRUB je mogoče namestiti tudi na zagonski zapis razdelka. Primerni " "razdelki so na tem spisku. To pa zahteva uporabo mehanizma blocklist, ki je " "manj zanesljiv in zato ni priporočen." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Zagonski nalagalnik GRUB je bil nameščen na disku, ki ni več prisoten ali se " "mu je spremenil enolični identifikator. Važno je, da so jedro GRUBa in " "moduli ter grub.cfg skladni. Preverite prosim, da je GRUB zapisan na " "pravilno zagonsko napravo." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Napaka pri pisanju na zagonsko napravo za GRUB. Želite nadaljevati?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Napaka pri nameščanju GRUBa na sledeče naprave:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Želite vseeno nadaljevati? V primeru, da boste nadaljevali se računalnik " "mogoče ne bo pravilno zagnal." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "Nameščanje GRUBa na zagonsko napravo ni uspelo. Želite še enkrat poskusiti?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Mogoče lahko namestite GRUB na katero drugo napravo, preveriti pa morate, da " "se bo lahko vaš sistem zagnal iz te naprave. Drugače bo posodobitev iz " "zastarelega GRUB prekinjena ." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Želite nadaljevati, ne da bi namestili GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Izbrali ste, da ne boste namestili GRUBa na nobeno napravo. V primeru, da " "nadaljujete zagonski nalagalnik ne bo pravilno nastavljen. Računalnik bo ob " "naslednjem zagonu uporabil karkoli je bilo prej nameščeno na zagonskem " "sektorju. V primeru, da se tam nahaja starejša različica GRUB 2 mogoče ta ne " "bo uspela naložiti modulov ali brati sedanje nastavitvene datoteke." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "V primeru, da že uporabljate različen zagonski nalagalnik in želite s tem " "nadaljevati ali pa je to posebno zagonsko okolje kjer ne rabite zagonskega " "nalagalnika lahko vsekakor nadaljujete. V ostalih primerih bi morali nekam " "namestiti GRUB." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Želite odstraniti GRUB 2 iz /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "" "Želite odstraniti iz /boot/grub vse datoteke, ki se nanašajo na GRUB 2?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Zaradi tega se sistem ne bo mogel zagnati, razen, če uporabite drugi " "zagonski nalagalnik." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Želite zdaj dokončati pretvorbo v GRUB 2?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Na tem sistemu so še nameščene datoteke iz zastarelega GRUBa, a zdaj je " "nameščen tudi zagonski zapis GRUB 2 na sledečih diskih:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Zdi se verjetno, da zastareli GRUB ni več v uporabi in da bi morali namesto " "tega nadgraditi te diske na GRUB 2 ter dokončati pretvorbo v GRUB 2 z " "odstranitvijo datotek za zastareli GRUB. V primeru, da ne boste izvedli " "nadgradnje na GRUB 2 lahko pride do nezdružljivosti z novimi paketi in težav " "pri zagonu." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Običajno bi morali dokončati pretvorbo v GRUB 2 razen, če so bili ti " "zagonski zapisi ustvarjeni pri nameščanju GRUB 2 na drugem operacijskem " "sistemu." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Ukazna vrstica Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Sledeči ukaz za Linux je vzet iz datoteke /etc/default/grub ali iz parametra " "`kopt' v datoteki menu.lst sistema GRUB Legacy. Preverite prosim, da je " "točen in ga po potrebi popravite. Ukazna vrstica je lahko tudi prazna." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Privzeta ukazna vrstica Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Sledeča vrstica bo uporabljena kot parameter Linuxa za privzeti vnos v " "meniju, ne pa za reševalni način." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Ukazna vrstica kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Sledeči ukaz za kFreeBSD je vzet iz datoteke /etc/default/grub ali iz " "parametra `kopt' v datoteki menu.lst sistema GRUB Legacy. Preverite " "prosim, da je točen in ga po potrebi popravite. Ukazna vrstica je lahko tudi " "prazna." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Privzeta ukazna vrstica kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Sledeča vrstica bo uporabljena kot parameter kFreeBSD za privzeti vnos v " "meniju, ne pa za reševalni način." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "ustvarjena je bila datoteka /boot/grub/device.map" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Datoteka /boot/grub/device.map je bila prepisana s stabilnimi imeni naprav. " "V večini primerov bo to v prihodnosti močno zmanjšalo potrebo po njenih " "spremembah. Na vnose v zagonskem meniju, ki jih ustvari GRUB to ne bi smelo " "imeti učinka." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Ker imate več kot en disk na vašem sistemu je možno, da ste bili odvisni od " "starega spiska naprav. Preverite prosim ali imate kakšen vnos po meri v " "zagonskem meniju, ki se naslanja na poimenovanje diskov (hdN) v GRUBu in ga " "posodobite, če je to potrebno." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "V primeru, da tega sporočila ne razumete ali nimate nobenih vnosov po meri " "v zagonskem meniju se za to sporočilo ne menite." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "V primeru, da želite, da se GRUB 2 naloži neposredno iz MBRja, lahko v " #~ "obeh primerih zaženete (kot sistemski skrbnik) sledeči ukaz:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "GRUB ni bil nameščen. Želite nadaljevati?" debian/po/templates.pot0000664000000000000000000002234712524662415012347 0ustar # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" debian/po/cy.po0000664000000000000000000003512712524662415010600 0ustar # Translation of grub2 debconf template to Welsh # # Copyright (C) 2012 # # This file is distributed under the same license as the grub2 package. # # Dafydd Tomos , 2012 # msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-06-16 22:25-0000\n" "Last-Translator: Dafydd Tomos \n" "Language-Team: Welsh\n" "Language: cy\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Welsh\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Cadwyn-lwytho o menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Mae sgriptiau uwchraddio GRUB wedi canfod gosodiad GRUB etifeddol yn /boot/" "grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Er mwyn disodli yr hen fersiwn o GRUB yn eich system, argymhellir fod /boot/" "grub/menu.lst yn cael ei addasu i lwytho delwedd ymgychwyn GRUB 2 o'ch " "gosodiad GRUB etifeddol. Gall y cam hwn gael ei wneud yn awtomatig nawr." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Argymhellir eich bod yn derbyn cadwyn-lwytho GRUB 2 o menu.lst, a gwirio fod " "y gosodiad GRUB 2 yn gweithio cyn iddo gael ei ysgrifennu i'r Cofnod " "Ymgychwyn Meistr (MBR)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Beth bynnag yw eich dewis, fe allwch chi ddisodli eich hen ddelwedd MBR gyda " "GRUB 2 nes ymlaen drwy redeg y gorchymyn canlynol fel root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Dyfeisiau sefydlu GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Mae'r pecyn grub-bc yn cael ei uwchraddio. Mae'r fwydlen yma yn eich " "caniatáu i ddewis pa ddyfeisiau yr hoffech redeg grub-install arno, os o " "gwbl." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Argymhellir rhedeg grub-install yn awtomatig yn y rhan fwyaf o sefyllfaoedd, " "i wneud yn siwr fod y ddelwedd GRUB craidd yn gyson gyda'r modiwlau GRUB a " "grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Os nad ydych yn siwr pa ddisg sydd wedi ei benodi fel disg ymgychwyn gan " "eich BIOS, mae yn syniad da fel arfer i sefydlu GRUB i bob un." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Nodyn: mae'n bosibl sefydlu GRUB i gofnodion ymgychwyn rhaniadau hefyd, a " "mae rhai rhaniadau addas yn cael eu cynnig yma. Fodd bynnag, mae hyn yn " "gorfodi GRUB i ddefnyddio techneg rhestr flocio, sy'n ei wneud yn llai " "dibynnadwy, a felly ni argymhellir ei ddefnyddio." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Roedd y llwythwr ymgychwyn GRUB wedi ei osod yn flaenorol i ddisg sydd ddim " "yn bresennol bellach, neu fod ei rif unigryw wedi newid am rhyw reswm. Mae'n " "bwysig i wneud yn siwr fod y ddelwedd craidd GRUB a osodwyd yn gyson gyda " "modiwlau GRUB a grub.cfg. Gwiriwch eto i wneud yn siwr fod GRUB yn " "ysgrifennu i'r dyfeisiau ymgychwyn addas." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Methwyd ysgrifennu GRUB i'r ddyfais ymgychwyn - parhau?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Methwyd sefydlu GRUB i'r dyfeisiau canlynol:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Ydych am barhau beth bynnag? Os ydych, mae'n bosib na fydd eich cyfrifiadur " "yn dechrau'n gywir." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Methwyd ysgrifennu GRUB o'r ddyfais ymgychwyn - ceisio eto?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Mae'n bosib y gallwch sefydlu GRUB i ryw ddyfais arall, ond fe ddylech wirio " "fod y system yn gallu ymgychwyn o'r ddyfais honno. Fel arall, i fydd " "uwchraddio o GRUB etifeddol yn cael ei ganslo." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Parhau heb sefydlu GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Fe ddewisoch i beidio sefydlu GRUB i unrhyw ddyfeisiau. Os ydych yn parhau, " "mae'n bosib na fydd y llwythwr ymgychwyn wedi ei gyflunio'n gywir, a'r tro " "nesa fydd y cyfrifiadur hwn yn dechrau mi fydd yn defnyddio beth bynnag oedd " "yn y sector ymgychwyn o'r blaen. Os oes fersiwn cynharach o GRUB 2 yn y " "sector ymgychwyn, mae'n bosib na fydd yn gallu llwytho modiwlau na deall y " "ffeil gyfluniad presennol." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Os ydych yn defnyddio llwythwr ymgychwyn gwahanol yn barod ac eisiau parhau " "i wneud hynny, neu os yw hwn yn amgylchedd arbennig lle nad oes angen " "llwythwr ymgychwyn, yna fe allwch barhau beth bynnag. Fel arall, fe ddylech " "sefydlu GRUB yn rhywle." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Dileu GRUB 2 o /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Ydych am i holl ffeiliau GRUB 2 cael eu dileu o /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Mi fydd hyn yn golygu na fydd y system yn gallu cychwyn nes i lwythwr " "ymgychwyn arall ei sefydlu." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Cwblhau y newid i GRUB 2 nawr?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Mae yna ffeiliau o lwythwr ymgychwyn GRUB etifeddol dal i fod ar y system " "hwn, ond mae yna hefyd gofnodion ymgychwyn GRUB 2 wedi ei sefydlu ar y " "disgiau hyn:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Mae'n edrych yn debyg nad yw GRUB etifeddol yn cael ei ddefnyddio rhagor, a " "fe ddylech uwchraddio i'r delweddau GRUB 2 ar y disgiau hyn a cwblhau y " "newid i GRUB 2 drwy ddileu yr hen ffeiliau GRUB etifeddol. Os nad ydych yn " "uwchraddio'r delweddau GRUB 2, mae'n bosib y byddant yn anghydnaws gyda'r " "pecynnau newydd a fe allai hyn atal eich system rhag dechrau yn gywir." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Yn gyffredinol, fe ddylech gwblhau'r newid i GRUB 2 heblaw fod y cofnodion " "ymgychwyn hyn wedi eu creu gan sefydliad GRUB 2 gan ryw system weithredu " "arall." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Llinell orchymyn Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Mae'r llinell orchymyn Linux canlynol wedi ei dynnu o /etc/default/grub " "neu'r paramedr 'kopt' yn ffeil menu.lst GRUB etifeddol. Gwiriwch fod hyn yn " "gywir a newidwch os oes angen. Caniateir i'r linell orchymyn fod yn wag." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Llinell orchymyn ddiofyn Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Defnyddir y llinyn canlynol fel paramedrau Linux ar gyfer y cofnod bwydlen " "diofyn ond ddim ar gyfer y modd achub." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Llinell orchymyn kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Mae'r llinell orchymyn kFreeBSD canlynol wedi ei dynnu o /etc/default/grub " "neu'r paramedr 'kopt' yn ffeil menu.lst GRUB etifeddol. Gwiriwch fod hyn yn " "gywir a newidwch os oes angen. Caniateir i'r linell orchymyn fod yn wag." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Llinell orchymyn ddiofyn kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Defnyddir y llinyn canlynol fel paramedrau kFreeBSD ar gyfer y cofnod " "bwydlen diofyn ond ddim ar gyfer y modd achub." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "Mae'r ffeil /boot/grub/device.map wedi ei ail-greu" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Mae'r ffeil /boot/grub/device.map wedi ei ailsgrifennu i ddefnyddio enwau " "dyfeisiau sefydlog. Yn y rhan fwyaf o achosion, fe ddylai hwn leihau'n " "sylweddol yr angen i'w newid yn dyfodol, a ni ddylai hyn effeithio ar y " "cofnodion bwydlen ymgychwyn a gynhyrchir gan GRUB." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Fodd bynnag, gan fod mwy na un disg yn bresennol yn y system, mae'n bosib " "fod y system yn dibynnu ar hen fap dyfais. Gwiriwch os oes unrhyw gofnodion " "bwydlen ymgychwyn sydd wedi'i addasu ac yn dibynnu ar rhifo disg GRUB (hdN), " "a diweddarwch nhw os oes angen." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Os nad ydych yn deall y neges hwn, neu os nad oes unrhyw gofnodion bwydlen " "ymgychwyn wedi'i addasu, fe allwch chi anwybyddu'r neges hwn." debian/po/vi.po0000664000000000000000000004100612524662415010574 0ustar # Vietnamese translation for Grub2_Debian. # Copyright © 2010 Free Software Foundation, Inc. # Clytie Siddall , 2010. # Hai Lang , 2012. # msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-04-23 20:48+0700\n" "Last-Translator: Hai Lang \n" "Language-Team: Vietnamese \n" "Language: vi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: LocFactoryEditor 1.8\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Nạp dãy từ menu.lst ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Văn lệnh nâng cấp GRUB phát hiện được một thiết lập GRUB Thừa Tự (GRUB " "Legacy) trong « /boot/grub »." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Để thay thế phiên bản Thừa Tự của GRUB trong hệ thống này, nên điều chỉnh /" "boot/grub/menu.lst để nạp ảnh khởi động GRUB 2 từ thiết lập GRUB Thừa Tự đã " "có. Bước này có thể được tự động thực hiện ngay bây giờ." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Bạn nên đồng ý việc nạp dãy GRUB 2 từ menu.lst, và kiểm tra rằng thiết lập " "GRUB 2 mới có thể làm việc được trước khi nó được ghi vào MBR (Mục ghi Khởi " "động Chủ)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Dù bạn quyết định thế nào, sau này bạn vẫn có thể thay thế ảnh MBR cũ bởi " "GRUB 2 bằng cách thực hiện câu lệnh sau với quyền root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Những thiết bị cài đặt GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Gói grub-pc sắp được cập nhật. Trình đơn này cho bạn chọn thiết bị nào, nếu " "có, mà bạn muốn grub-install tự động chạy trên đó." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Nên chạy grub-install một cách tự động trong hầu hết các trường hợp, để " "tránh sự mất đồng bộ giữa ảnh lõi GRUB đã được cài đặt với các mô-đun GRUB " "hay grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Nếu bạn không chắc ổ đĩa nào được chỉ định làm ổ đĩa khởi trọng trong BIOS " "của bạn, tốt nhất là cài đặt GRUB vào tất cả các ổ đĩa." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Ghi chú: vẫn có thể cài GRUB vào các bản ghi khởi động của phân vùng, và một " "vài phân vùng phù hợp được đưa ra ở đây. Tuy nhiên, việc này bắt buộc GRUB " "dùng cơ chế danh sách ngăn chặn, làm cho nó ít tin cậy hơn, và do đó không " "nên dùng." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Trình nạp khởi động GRUB trước đây đã được cài đặt trên một đĩa không còn " "tồn tại, hay số định danh duy nhất của đĩa đó đã thay đổi vì lý do nào đó. " "Quan trọng là phải chắc chắn rằng ảnh lõi GRUB đã được cài còn đồng bộ với " "các mô-đun GRUB và grub.cfg. Vui lòng kiểm tra lại để chắc chắn rằng GRUB " "được ghi vào các thiết bị khởi động phù hợp." # Variable: don't translate; Biến: đừng dịch #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" # Variable: don't translate; Biến: đừng dịch #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Việc ghi GRUB vào thiết bị khởi động bị lỗi - tiếp tục không?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB không cài đặt được vào những thiết bị theo đây:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Bạn vẫn muốn tiếp tục không? Nếu có thì máy tính có thể không khởi động đúng." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Lỗi khi ghi GRUB vào thiế bị khởi động - thử lại nhé?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Có thể là bạn cài đặt được GRUB vào một thiết bị khác (trước tiên nên kiểm " "tra nếu hệ thống sẽ khởi động từ thiết bị đó). Không thì tiến trình nâng cấp " "từ GRUB Cũ (Legacy) sẽ bị thôi." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Tiếp tục lại mà không cài đặt GRUB ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Bạn đã chọn không cài đặt GRUB vào thiết bị nào. Nếu tiếp tục thì bộ nạp " "khởi động có thể bị cấu hình sai, và khi máy tính khởi động lại nó sẽ sử " "dụng dữ liệu bất kỳ trước đây có trong rãnh ghi khởi động. Nếu rãnh ghi khởi " "động chứa một phiên bản GRUB 2 cũ, nó có thể không nạp được mô-đun hoặc " "không xử lý được tập tin cấu hình hiện thời." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Nếu bạn đã dùng một bộ nạp khởi động khác và muốn tiếp tục dùng, hoặc nếu " "đây là một môi trường đặc biệt mà không cần thiết bộ nạp khởi động, thì bạn " "nên tiếp tục. Nếu không thì bạn nên cài đặt GRUB vào một nơi nào đó." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Gỡ bỏ GRUB 2 khỏi /boot/grub không?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Bạn có muốn gỡ bỏ tất cả tập tin GRUB 2 khỏi /boot/grub không?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Việc này làm cho hệ thống không khởi động được trừ khi trình nạp khởi động " "khác được cài đặt." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Kết thúc chuyển đổi sang GRUB2 ngay bây giờ ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Hệ thống này vẫn còn có tập tin được cài đặt bởi bộ nạp khởi động GRUB Cũ " "(Legacy), nhưng mà cũng có mục ghi GRUB2 được cài đặt vào những đĩa này:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Rất có thể là GRUB Cũ (Legacy) không còn được sử dụng, vì thế bạn nên nâng " "cấp các ảnh GRUB2 trên những đĩa này và kết thúc chuyển đổi sang GRUB2 bằng " "cách gỡ bỏ tất cả các tập tin GRUB Cũ. Không nâng cấp các ảnh GRUB2 thì " "chúng có thể không tương thích với gói mới và gây ra hệ thống này không khởi " "động đúng." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Nói chung bạn nên kết thúc chuyển đổi sang GRUB2 nếu các mục ghi khởi động " "này không được tạo bởi một bản cài đặt GRUB2 trên một hệ điều hành khác." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Dòng lệnh Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Dòng lệnh Linux theo đây đã được trích ra từ /etc/default/grub hoặc từ tham " "số `kopt' trong menu.lst của GRUB Thừa Tự. Hãy kiểm tra rằng nó vẫn đúng, và " "sửa đổi nó nếu cần. Dòng lệnh có thể được để trống." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Dòng lệnh Linux mặc định:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Chuỗi theo đây sẽ được sử dụng làm các tham số Linux cho mục nhập trình đơn " "mặc định, mà không phải cho chế độ phục hồi." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Dòng lệnh kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Dòng lệnh kFreeBSD sau đây đã được trích ra từ /etc/default/grub hoặc từ " "tham số `kopt' trong menu.lst của GRUB Thừa Tự. Hãy kiểm tra rằng nó vẫn " "đúng, và sửa đổi nó nếu cần. Dòng lệnh có thể được để trống." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Dòng lệnh kFreeBSD mặc định:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Chuỗi theo đây sẽ được sử dụng làm các tham số kFreeBSD cho mục nhập trình " "đơn mặc định, mà không phải cho chế độ phục hồi." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "Tập tin /boot/grub/device.map đã được tạo lại." #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Tập tin /boot/grub/device.map đã được ghi nhớ lại để sử dụng tên thiết bị " "kiểu ổn định. Trong phần lớn các trường hợp, bản cập nhật này nên giảm một " "cách đáng kể sự cần sửa đổi về sau, và không nên tác động trình đơn khởi " "động được GRUB tạo." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Tuy nhiên, vì bạn có nhiều hơn một ổ đĩa trong hệ thống, có thể là hệ thống " "này vẫn còn phụ thuộc vào sơ đồ thiết bị cũ. Hãy kiểm tra xem có những mục " "trình đơn khởi động tùy thích nào dựa vào số thứ tự ổ đĩa của GRUB (hdN), và " "cập nhật chúng nếu cần." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Nếu bạn không hiểu thông điệp này, hoặc nếu không có mục trình đơn khởi động " "tùy thích nào, thì bạn có thể bỏ qua thông điệp này." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Trong cả hai trường hợp, khi nào bạn muốn nạp GRUB2 một cách trực tiếp từ " #~ "MBR, chỉ cần chạy (dưới người chủ) câu lệnh theo đây:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Lỗi cài đặt GRUB. Tiếp tục ?" debian/po/ja.po0000664000000000000000000004117312524662415010555 0ustar # Copyright (C) 2008-2010 GRUB Maintainers # This file is distributed under the same license as the grub2 package. # Hideki Yamane , , 2008-2011. # msgid "" msgstr "" "Project-Id-Version: grub2 1.99-5\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-05-28 23:44+0900\n" "Last-Translator: Hideki Yamane \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "menu.lst 経由で起動 (チェーンロード) しますか?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "GRUB のアップグレードプログラムは、/boot/grub に GRUB Legacy の設定があるのを" "検出しました。" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "システム中に存在している古いバージョンの GRUB を置き換えるには、/boot/grub/" "menu.lst にある GRUB Legacy の設定を使って GRUB2 の起動イメージを読み込むよう" "に設定するのがお勧めです。この作業はここで自動的に実行されます。" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "MBR (マスターブートレコード) に直接インストールする前に、GRUB 2 が menu.lst " "からチェーンロードするように設定し、新しい GRUB 2 の設定が動作するかどうかを" "確認する事をお勧めします。" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "どの設定を選ぶにせよ、root として以下のコマンドを実行することによって、後から" "でも古い MBR イメージを GRUB 2 に置き換えられます。" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB をインストールするデバイス:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "grub-pc パッケージのアップグレード中です。このメニューでは、もしデバイスがあ" "れば、どのデバイスに自動的に grub-install を実行するかを選べます。" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "インストール済みの GRUB コアイメージが GRUB モジュールや grub.cfg との同期が" "ずれるのを防ぐため、ほとんどの場合、自動的に grub-instsall を実行するのがお勧" "めです。" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "BIOS でどのドライブが起動ドライブとして設定されているのか判らないのであれば、" "すべてに GRUB をインストールするのが大抵の場合良い考えです。" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "注意: パーティションブートレコードに GRUB をインストールするのも可能です。そ" "して、ここでは適切なパーティションが表示されます。しかし、これによって GRUB " "がブロックリストの仕組みを強制的に使うようになります。この仕組みは信頼性に欠" "けるため、お勧めはしません。" #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "以前、GRUB ブートローダーは、すでに存在しない、あるいは何らかの理由で一意の識" "別子が変更されたディスクにインストールされていました。インストールされている " "GRUB コアイメージが GRUB モジュールや grub.cfg と一致しているのを確認するのは" "重要です。もう一度、GRUB が適切な起動デバイスに書き込まれているか確かめてくだ" "さい。" #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "起動デバイスへの GRUB の書き込みが失敗しました - 続行しますか?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB は以下のデバイスへのインストールに失敗しました:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "とにかく続行しますか? その場合、コンピュータが正常に起動しないかもしれませ" "ん。" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "ブートデバイスへの GRUB の書き込みに失敗しました。もう一度試してみますか?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "別のデバイスに GRUB をインストールできるかもしれませんが、そのデバイスからシ" "ステムが起動するかどうかを確認しておく必要があります。どのデバイスにもインス" "トールを行わない場合は、GRUB Legacy からのアップグレードは中止されます。" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "GRUB をインストールせずにパッケージのインストールを続行しますか?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "どのデバイスに対しても GRUB をインストールしないことが選択されました。ブート" "ローダーが正しく設定されていない可能性があり、このまま続行するとこのコン" "ピュータの次回起動時には、以前に起動セクタにインストールされていたものを何で" "あろうとも利用しようとします。以前のバージョンの GRUB 2 が起動セクタにある場" "合は、モジュールの読み込みや現在の設定ファイルの取り扱いが出来なくなる可能性" "があります。" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "既に別のブートローダーを利用していてそれを使い続けたい場合、あるいはブート" "ローダーを必要としない特殊な環境の場合は、とにかく続行してしまって構いませ" "ん。そうでない場合は、どこかに GRUB をインストールしてください。" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "/boot/grub から GRUB 2 を削除しますか?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "/boot/grub から GRUB 2 のファイルをすべて削除しますか?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "この作業は、別のブートローダーがインストールされていないとシステムが起動でき" "なくなります。" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "ここで GRUB 2 へのコンバートを終了しますか?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "このシステムには GRUB Legacy のブートローダーがインストールしたファイルがあり" "ますが、GRUB 2 のブートレコードも以下のディスクにインストールされています:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "GRUB Legacy はもはや使われてはいないようなので、代わりにこれらのディスク上の " "GRUB 2 イメージをアップグレードして、古い GRUB Legacy のファイルを削除するこ" "とで GRUB 2 へのコンバートを完了する必要があります。これらの GRUB 2 イメージ" "をアップグレードしていない場合は、新しいパッケージとの互換性がないためにシス" "テムが正常に起動しない可能性があります。" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "他の OS 上での GRUB 2 のインストールによって作成されていたブートレコードを除" "き、GRUB 2 へのコンバートはほぼ完了しました。" #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux コマンドライン:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "以下の Linux のコマンドラインは /etc/default/grub か GRUB Legacy の menu.lst " "上の「kopt」パラメータから取得されています。これが正しいものであるかを確認し" "て、必要であれば修正してください。コマンドラインは空でも構いません。" #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linux デフォルトコマンドライン:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "以下の文字列は、リカバリーモードではない通常のメニューエントリでの Linux パラ" "メータとして使われます。" #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD コマンドライン:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "以下の kFreeBSD のコマンドラインは、/etc/default/grub か GRUB Legacy の menu." "lst 上の「kopt」パラメータから取得されています。これが正しいものであるかを確" "認して、必要であれば修正してください。コマンドラインは空でも構いません。" #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "kFreeBSD デフォルトコマンドライン:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "以下の文字列はリカバリーモードではない通常のメニューエントリでの kFreeBSD パ" "ラメータとして使われます。" #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map が再生成されました" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "/boot/grub/device.map ファイルは固定のデバイス名を使うように書き換えられまし" "た。多くの場合は、今後このファイルを変更する必要が大幅に減っており、GRUB に" "よって生成される起動メニューの項目は影響を受けないはずです。" #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "しかし、システムに 2 個以上ディスクがあるので、起動メニューの項目が古いデバイ" "ス情報に依存していた可能性があります。起動メニューの項目が GRUB でのドライブ" "の順番 (hdN) に関連していないかどうかを確認して、必要であれば更新してくださ" "い。" #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "このメッセージの意味が分からない、あるいは変更した起動メニュー項目が無い場合" "は、このメッセージを無視して構いません。" debian/po/dz.po0000664000000000000000000006240412524662415010600 0ustar # Translation of grub2 debconf templates to Dzongkha # Copyright (C) 2010 Dzongkha Localization # This file is distributed under the same license as the PACKAGE package. # Jurmey Rabgay , 2010. # msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2001-12-31 19:57-0500\n" "Last-Translator: Dawa \n" "Language-Team: Dzongkha \n" "Language: dz\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2;plural=(n!=1)\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "menu.lst ནང་ལས་ ཅེན་ལོཌི་འབད་ནི་ཨིན་ན?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "GRUB དུས་མཐུན་ཡིག་ཚུགས་ཚུ་གིས་ /boot/grub ནང་ལུ་ GRUB སྔོན་བཤུལ་གཞི་སྒྲིག་ཅིག་སྐྱོན་འཛིན་འབད་ནུག" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "ཁྱོད་རའི་རིམ་ལུགས་ནང་ལུ་ GRUB གི་སྔོན་བཤུལ་ཐོན་རིམ་ཚབ་བཙུགས་འབད་ནི་གི་དོན་ལུ་ /boot/grub/menu." "lst འདི་ ཁྱོད་རའི་ཡོད་བཞིན་པའི་སྔོན་བཤུལ་གཞི་སྒྲིག་ནང་ལས་ ཅེན་ལོཌི་ GRUB ༢ ལུ་ བདེ་སྒྲིག་འབད་དགོཔ་སྦེ་" "འོས་སྦྱོར་འབད་ནུག། གཞི་སྒྲིག་འདི་ ཡང་ཅིན་ འཕྲལ་ར་རང་བཞིན་གྱིས་ལཱ་འབད་བཏུབ།" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "ཁྱོད་ཀྱིས་ menu.lst ནང་ལས་ ཅེན་ལོ་ཌིང་དང་ལེན་འབད་དེ་ GRUB ༢ གཞི་སྒྲིག་གསརཔ་འདི་ MBR " "(Master Boot Record) ལུ་ཐད་ཀར་གཞི་བཙུགས་མ་འབད་བའི་ཧེ་མ་ གཡོག་བཀོལ་བཏུབ་མི་བཏུབ་བལྟ་དགོ་" "པའི་འོས་སྦྱོར་འབད་དེ་ཡོད།" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "ཁྱོད་ཀྱིས་ག་དེ་སྦེ་ གྲོས་ཐག་གཅད་རུང་ ཤུལ་ལས་ MBR གཟུགས་བརྙན་་རྙིངམ་འདི་ འོག་གི་བརྡ་བཀོད་འདི་ རུཊི་སྦེ་" "སྤྲོད་ཐོག་ལས་ GRUB 2 གིས་ཚབ་བཙུགས་འབད་ཚུགས།" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB གཞི་བཙུགས་ ཐབས་འཕྲུལ་ཚུ :" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "grub-pc ཐུམ་སྒྲིལ་འདི་ ཡར་བསྐྱེད་འབད་ཡོདཔ། དཀར་ཆག་འདི་གིས་ རང་བཞིན་ གཡོག་བཀོལ་ grub-གཞི་" "བཙུགས་ གང་རུང་ཡོད་པ་ཅིན་ ཐབས་འཕྲུལ་ སེལ་འཐུ་འབད་བཅུགཔ་ཨིན།" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" " GRUB core གཟུགས་བརྙན་ འདི་ GRUB modulesཡང་ན་ grub.cfg ལས་ སོ་སོ་སྦེ་མི་འགྱོ་ནིའི་དོན་ལུ་ " "གནས་སྟངས་མང་ཤོས་ཅིག་ནང་ རང་བཞིན་གྱི་ grub-གཞི་བཙུགས་ གཡོག་བཀོལ་ནི་འདི་ འོས་སྦྱོར་འབད་ཡོདཔ་ཨིན། " #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "ག་དེམ་ཅིག་སྦེ་ ཁྱོད་རའི་BIOS གིས་ ཌའིབ་ག་འདི་ བུཊི་ ཌའིབ་སྦེ་ ངོས་འཛིན་འབད་འབདཝ་ཨིན་ན་མ་ཤེས་པ་" "ཅིན་ ཆ་མཉམ་ལུ་ GRUB གཞི་བཙུགས་འབད་ནི་འི་ཐབས་ལམ་ལེགས་ཤོམ་ཅིག་ཨིན།" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "དྲན་འཛིན: GRUB འདི་ བར་བཅད་ བུཊི་ དྲན་ཐོ་ལུ་ཡང་ གཞི་བཙུགས་འབད་ཚུགསཔ་ཨིནམ་དང་ འོས་ལྡན་ བར་" "བཅད་ལ་ལོ་གཅིག་ནཱ་ལུ་བྱིན་ཏེ་ཡོདཔ་ཨིན། ཨིན་རུང་ འདི་གིས་ GRUB ལུ་ blocklist ཐབས་རིག་ལག་ལེ་ན་" "འཐབ་ཅབུག་སྟེ་ བློ་གཏད་མ་ཚུགསཔ་བཟོཝ་ཨིནམ་ལས་ འདི་ངོ་སྦྱོར་མི་འབད།" #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB བུཊི་ མངོན་གསལ་པ་འདི་ ཧེ་མ་ལས་ ཌིཀསི་མེད་མི་ ཡང་ན་ མཐུན་མོང་མ་ཡིན་པའི་ངོས་འཛིན་པ་འདི་ " "དོན་དག་གང་རུང་ལུ་བརྟེན་ བསྒྱུར་བཅོས་སོང་ཡོད་མི་ལུ་གཞི་བཙུགས་འབད་ནུག། གཞི་བཙུགས་འབད་ཡོད་པའི་ GRUB " "core གཟུགས་བརྙན་འདི་ GRUB མོ་ཌུལསི་ དང་ grub.cfg དང་ མཉམ་འབྱུང་སྦེ་སྡོད་བཏུབ་ ངེས་བདེན་བཟོ་" "དགོ། GRUB འདི་ བུཊི་ཐབས་འཕྲུལ་ འོས་ལྡན་ལུ་འབྲི་ཡོདཔ་ངེས་བདེན་་སྦེ་ཤེས་ཚུགས་ནིའི་དོལུ་ ལོག་ཞིབ་དཔྱད་" "འབད་གནང་།" #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr " GRUB བུཊི་ ཐབས་འཕྲུལ་ལུ་འབྲི་ནི་ འཐུས་ཤོར་འབྱུང་ཡོདཔ - འཕྲོ་མཐུད་དེ་འབད་ནི་ཨིན་ན?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB འདི་ འོག་གི་ཐབས་འཕྲུལ་ཚུ་ནང་གཞི་བཙུགས་འབད་མ་ཚུགས་པས:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "ག་དེ་འབད་རུང་ འཕྲོ་མཐུད་འབད་ནི་ཨིན་ན? འཕྲོ་མཐུད་འབད་བ་ཅིན་ ཁྱོད་ཀྱི་གློག་རིག་འདི་ལེགས་ཤོམ་སྦེ་འགོ་" "བཙུགས་མི་ཚུགས།" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "GRUB གཞི་བཙུགས་འཐུས་ཤོར་བྱུང་ཡོདཔ། - ལོག་འབད་རྩོལ་བསྐྱེད་ནི་ཨིན་ན?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "ཁྱོད་ཀྱིས་ ཐབས་འཕྲུལ་གཞན་ཚུ་ནང་ GRUB གཞི་བཙུགས་འབད་ཚུགསཔ་འོང་ ཨིན་རུང་ ཁྱོད་རའི་རིམ་ལུགས་འདི་ " "ཐབས་འཕྲུལ་དེ་ལས་བུཊི་འབད་བཏུབ་ག་ཞིབ་དཔྱད་འབད་དགོ། དེ་མེན་པ་ཅིན་ GRUB སྔོན་བཤུལ་ལས་དུས་མཐུན་" "འབད་མི་དེ་ཆ་མེད་འགྱོ་འོང་།" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "GRUB གཞི་བཙུགས་མ་འབད་བར་འཕྲོ་མཐུད་ནི་ཨིན་ན?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "ཁྱོད་ཀྱིས་ ཐབས་འཕྲུལ་གང་རུང་ནང་ GRUB གཞི་བཙུགས་མ་འབད་ནི་སྦེ་གདམ་ཁ་བརྐྱབས་ནུག འཕྲོ་མཐུད་དེ་འབད་བ་" "ཅིན་ བུཊི་མངོན་གསལ་པ་འདི་ ལེགས་ཤོམ་སྦེ་རིམ་སྒྲིག་མི་འབདཝ་་འོང་། དེ་ལས་ ཁྱོད་ཀྱི་གློག་རིག་འདི་ཤུལ་ལས་" "འགོ་བཙུགསཔ་ད་ ཧེ་མ་ལས་བུཊི་ས་ཁོངས་ག་ཅི་ཡོད་རུང་ ལག་ལེན་འཐབ་འོང་། གལ་སྲིད་ བུཊི་ས་ཁོངས་ ནང་ ཧེ་" "མའི་ཐོན་རིམ་ GRUB ༢ འདི་ཡོད་པ་ཅིན་ མོ་ཌུལ་འདི་མངོན་གསལའབད་མི་ཚུགས་ནི་ ཡང་ན་ ད་ལྟོའི་རིམ་སྒྲིག་ཡིག་" "སྣོད་འདི་ལེགས་སྐྱོང་འཐབ་མི་ཚུགསཔ་འོང་།" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "ཁྱོད་ཀྱིས་ ཧེ་མ་ལས་ བུཊི་མངོན་གསལ་འབད་མི་སོར་སོ་ཅིག་གཡོག་བཀོལ་འདོད་ཡོད་པ་ཅིན་ ཡང་ན་ འ་ནི་འདི་ " "བུཊི་མངོན་གསལ་འབད་མི་ཅིག་དགོཔ་མེད་པའི་དམིགས་བསལ་གྱི་ས་ཁོངས་མེན་པ་ཅིན་ འཕྲོ་མཐུད་མ་འབད། དེ་མེན་པ་" "ཅིན་ ག་ཏེ་འབད་རུང་ GRUB གཞི་བཙུགས་འབད་དགོ།" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "/boot/grub ནང་ལས་GRUB 2 རྩ་བསྐྲད་གཏང་ནི་ཨིན་ན?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "/boot/grub ནང་ལས་ GRUB 2 ཡིག་སྣོད་ཆ་མཉམ་ རྩ་བསྐྲད་གཏང་ནི་ཨིན་ན?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "འདི་གིས་ བུཊི་མངོན་གསལ་པ་སོ་སོ་གཅིག་གཞི་བཙུགས་མ་འབད་ཚུན་ རིམ་སྒྲིག་འདི་ བུཊི་འབད་མ་བཏུབ་བཟོ་འོང་།" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "ད་ལྟོ་ར་ GRUB ༢ ལུ་གཞི་བསྒྱུར་མཇུག་བསྡུ་ནི་ཨིན་ན?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "རིམ་ལུགས་འདི་ལུ་ གཞི་བཙུགས་འབད་ཡོད་པའི་ GRUB སྔོན་བཤུལ་བུཊི་མངོན་གསལ་འབད་མིའི་ནང་ལས་ཡིག་སྣོད་ཚུ་" "འདུག ཨིན་རུང་ ད་ལྟོ་འབདཝ་ད་ ཌིཀསི་ཚུ་གུ་ GRUB ༢ བུཊི་དྲན་ཐོ་གཞི་བཙུགས་འབད་དེ་ཡོད:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "GRUB སྤྱོད་ཤུལ་འདི་ ལག་ལེན་འཐབ་སྟེ་མེདཔ་བཟུམ་ཅིག་ཡོདཔ་དང་ འདི་གི་ཚབ་ལུ་ ཌིཀསི་གུ་ཡོད་མི་ GRUB 2 " "གཟུགས་བརྙན་ཚུ་དུས་མཐུན་བཟོ་ཞིནམ་ལས་ GRUB སྤྱོད་ཤུལ་ཡིག་སྣོད་རྙིངམ་ཚུ་ གཞི་བསྒྱུར་འབད་ནི་མཇུག་བསྡུ། ཁྱོད་" "ཀྱིས་ GRUB 2 གཟུགས་བརྙན་ཚུ་དུས་མཐུན་མ་བཟོ་བ་ཅིན་ འདི་ཚུ་ ཐུམ་སྒྲིལ་གསརཔ་ཚུ་དང་གཅིག་ཁར་མཐུན་འགྱུར་" "ཅན་མི་འོང་ནི་ཨིནམ་དང་ ཁྱོད་ཀྱི་རིམ་ལུགས་ཚུལ་མཐུན་སྦེ་ཊི་འབད་ནི་ལས་བཀག་ཆ་འབད་འོང་།" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "GRUB 2 གཞི་བཙུགས་ཀྱིས་ བཀོད་སྤྱོད་རིམ་ལུགས་ གཞན་གཅིག་གུ་ བུཊི་དྲན་ཐོ་འདི་ཚུ་ གསར་བསྐྲུན་མ་འབདཝ་" "ལས་ GRUB 2 ལུ་ གཞི་བསྒྱུར་འབད་ཚར་དགོ།" #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "ལི་ནགསི་བརྡ་བཀོད་གྲལ་ཐིག་:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "འོག་གི་ ལི་ནགསི་བརྡ་བཀོད་གྲལཐིག་འདི་ from from /etc/default/grub or the `kopt' " "parameter in GRUB Legacy's menu.lst. ལས་ ཕྱིར་དོན་འབད་འབདཝ་ཨིན། འདི་ངེས་བདེན་ཨིནམ་" "བདེན་སྦྱོར་འབད་ཞིནམ་ལས་ དགོས་མཁོ་ཡོད་པ་ཅིན་ལེགས་བཅོས་འབད། བརྡ་བཀོད་གྲལ་ཐིག་འདི་སྟོངམ་ཨིན་རུང་བཏུབ།" #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "ལི་ནགསི་སྔོན་སྒྲིག་བརྡ་བཀོད་གྲལ་ཐིག་:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "འོག་གི་ཡིག་རྒྱུན་འདི་ སྔོན་སྒྲིག་དཀར་ཆག་ཐོ་བཀོད་ཀྱི་དོན་ལུ་ ལི་ནགསི་ཚད་འཛིན་སྦེ་ལག་ལེན་འཐབ་ནི་ཨིན་ དེ་" "འབདཝ་ད་ སླར་གསོ་ཐབས་ལམ་གྱི་དོན་ལུ་མེན།" #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD བརྡ་བཀོད་གྲལ་ཐིག་:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "འོག་གི་ kFreeBSD བརྡ་བཀོད་གྲལ་ཐིག་འདི་ /etc/default/grub or the `kopt' parameter " "in GRUB Legacy's menu.lst ལས་ ཕྱིར་འདོན་འབད་འབདཝ་ཨིན། འདི་ངེས་དེན་ཨིནམ་བདེན་སྦྱོར་འབད་" "ཞིནམ་ལས་ དགོས་མཁོ་ཡོད་པ་ཅིན་ ལེགས་བཅོས་འབད། བརྡ་བཀོད་གྲལ་ཐིག་འདི་ སྟོངམ་ཨིན་རུང་བཏུབ།" #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "kFreeBSD སྔོན་སྒྲིག་བརྡ་བཀོད་གྲལ་ཐིག་:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "འོག་གི་ཡིག་རྒྱུན་ཚུ་ སྔོན་སྒྲིག་དཀར་ཆག་ཐོ་བཀོད་ཀྱི་དོན་ལུ་ kFreeBSD སྦེ་ལག་ལེན་འཐབ་འོང་ དེ་འབདཝད་ " "སླར་གསོ་ཐབས་ལམ་གྱི་དོན་ལུ་ལག་ལེན་མི་འཐབ།" #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map འདི་ ལོག་བཟོ་ཡོདཔ།" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "ཡིག་སྣོད་ /boot/grub/device.map འདི་ རྩ་བརྟན་ ཐབས་འཕྲུལ་མིང་ཚུ་ལག་ལེན་འཐབ་སྦེ་ལོག་འབྲི་ཡོདཔ་" "ཨིན། གནད་དོན་མང་ཤོས་ཅིག་ནང་ འདི་གིས་ མ་འོངས་པའི་ནང་བསྒྱུར་བཅོས་འབད་ནི་མར་ཕབ་འབད་དགོཔ་་ཨིནམ་" "དང་ GRUB གིས་ བཟོ་བཏོན་འབད་ཡོད་པའི་ བུཊི་དཀར་ཆག་ཐོ་བཀོད་ཚུ་ལུ་གནོད་སྐྱོན་འབྱུ་ཕཅུག་ནི་མི་འོང་།" #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "ག་དེ་སྦེ་རངུ་ ཁྱོད་ཀྱི་རིམ་ལུགས་ནང་ ཌིཀསི་གཅིག་ལས་ལྷགཔ་སྦེ་ཡོདཔ་ལས་ ཁྱོད་ ཐབས་འཕྲུ་ས་ཁྲ་རྙིངམ་འདི་ལུ་" "བརྟེན་ཚུགས། ཁྱོད་ལུ་ GRUB's (hdN) འདྲེན་འཕྲུལ་ ཨང་བཏགས་ནིའི་་སྲོལ་སྒྲིག་ བུཊི་དཀར་ཆག་ཐོ་བཀོད་ཚུ་" "ཡོད་མེད་ཞིབ་དཔྱད་འབད་ཞིནམ་ལས་ དགོས་མཁོ་དང་བསྟུན་ཏེ་ དུས་མཐུན་བཟོ།" #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "འཕྲིན་དོན་འདི་ཧ་མ་གོཝ་ ཡང་ན་ ཁྱོད་ལུ་ སྲོལ་སྒྲིག་དཀར་ཆག་ཐོ་བཀོད་གང་རངུ་མེད་པ་ཅིན་ འཕྲིན་དོན་འདི་" "སྣང་མེད་སྦེ་བཞག།" #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "ཡང་ཅིན་ ཁྱོད་ར་ལུ་ GRUB ༢ འདི་ MBR ལས་ ནམ་ཨིན་རུང་ མངོན་གསལ་འབད་འདོད་ཡོད་པ་ཅིན་ འོག་" #~ "གི་བརྡ་བཀོད་འདི་ རྩ་བའི་ཐོག་ལས་འབད་བཏུབ:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "GRUB གཞི་བཙུགས་འཐུས་ཤོར་བྱུང་ཡོདཔ། འཕྲོ་མཐུད་འབད་ནི་ཨིན་ན?" debian/po/de.po0000664000000000000000000003675212524662415010562 0ustar # Translation of GRUB 2 debconf templates to German # Copyright (C) Helge Kreutzmann , 2007-2009. # Martin Eberhard Schauer , 2010, 2011. # This file is distributed under the same license as the grub2 package. # msgid "" msgstr "" "Project-Id-Version: grub2 1.98+20100710-2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-07-13 00:10+0100\n" "Last-Translator: Martin Eberhard Schauer \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Aus »menu.lst« laden (Chainload)?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Die Upgrade-Skripte von GRUB haben eine Installation von »GRUB Legacy« in /" "boot/grub gefunden." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Um die Legacy-Version von GRUB auf Ihrem System zu ersetzen, wird die " "Anpassung von /boot/grub/menu.lst empfohlen, so dass GRUB 2 aus Ihrer " "bestehenden GRUB-Legacy-Konfiguration heraus geladen wird. Dieser Schritt " "kann jetzt automatisch vollzogen werden." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Es wird empfohlen, dass Sie dem Laden von GRUB 2 aus menu.lst zustimmen und " "überprüfen, dass Ihre neue »GRUB 2«-Installation funktioniert, bevor diese " "in den MBR (Master Boot Record) geschrieben wird." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Unabhängig von Ihrer Entscheidung können Sie den alten MBR später durch GRUB " "2 ersetzen. Geben Sie dazu als »root« den folgenden Befehl ein:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Geräte für die GRUB-Installation:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Für das Paket grub-pc wird gerade ein Upgrade durchgeführt. In diesem Menü " "können Sie auswählen, ob und für welche Geräte grub-install automatisch " "ausgeführt werden soll." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Für die Mehrzahl der Fälle wird empfohlen, grub-install automatisch laufen " "zu lassen. So wird vermieden, dass das installierte GRUB-Image nicht zu den " "GRUB-Modulen oder grub.cfg passt." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Wenn Sie nicht sicher sind, welches Gerät das BIOS zum Booten benutzt, ist " "es oft eine gute Idee, GRUB auf allen Geräten zu installieren." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Hinweis: Sie können GRUB auch in die Boot-Blöcke von Partionen schreiben." "Hier werden auch einige geeignete Partitionen angeboten. Das zwingt GRUB " "allerdings dazu, den Blocklist-Mechanismus zu verwenden. Dieser ist weniger " "zuverlässig und wird daher nicht empfohlen." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Der GRUB-Bootloader wurde zuvor auf einem Datenträger, der nicht mehr im " "System vorhanden ist oder dessen eindeutige Kennung aus irgendeinem Grund " "geändert wurde, installiert. Es ist wichtig, sicherzustellen, dass das " "installierte GRUB-Core-Image synchron mit den GRUB-Modulen und grub.cfg " "bleibt. Bitte prüfen Sie erneut, um sicherzustellen, dass GRUB auf die " "entsprechenden Boot-Geräte geschrieben wird." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "GRUB konnte nicht auf das Boot-Gerät geschrieben werden - fortfahren?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB konnte nicht auf den folgenden Geräten installiert werden:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Wollen Sie trotzdem fortfahren? Falls ja, wird Ihr Rechner vielleicht nicht " "problemlos hochfahren." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "" "Das Schreiben von GRUB auf das Boot-Gerät ist fehlgeschlagen. Noch einmal " "versuchen?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Vielleicht können Sie GRUB auf einem anderen Gerät installieren. Sie sollten " "aber prüfen, ob Ihr System von diesem Gerät startet. Sonst wird das Upgrade " "von GRUB Legacy abgebrochen." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Fortsetzen, ohne Grub zu installieren?" # (mes) Seht Ihr einen Unterschied zwischen der alten und der neuen Version? # Ich habe jetzt nur das fuzzy rausgenommen. #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Sie haben sich entschieden, GRUB auf kein Gerät zu installieren. Wenn Sie " "fortfahren, könnte der Boot-Loader nicht richtig konfiguriert sein. Beim " "nächsten Hochfahren dieses Computers wird der Boot-Loader benutzen, was " "immer sich vorher im Boot-Sektor befand. Wenn sich schon eine ältere Version " "von GRUB 2 im Boot-Sektor befindet, kann sie möglicherweise keine Module " "laden oder nicht mehr mit der aktuellen Konfigurationsdatei umgehen." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Falls Sie bereits einen anderen Boot-Loader einsetzen und diesen beibehalten " "wollen oder Ihre spezielle Umgebung keinen Boot-Loader erfordert, dann " "sollten Sie trotzdem fortfahren. Anderenfalls sollten Sie GRUB irgendwo " "installieren." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "GRUB 2 aus /boot/grub entfernen?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Wollen Sie alle Daten von GRUB 2 aus /boot/grub entfernen lassen?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Wenn kein anderer Boot-Loader installiert ist, kann Ihr System anschließend " "nicht mehr booten (hochfahren)." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Jetzt die Umstellung auf GRUB 2 abschließen?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Auf diesem System sind noch Dateien des GRUB-Legacy-Boot-Loaders " "installiert, aber es sind nun auch GRUB-2-Boot-Sektoren auf den folgenden " "Datenträgern installiert:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Es sieht so aus, als ob Sie GRUB Legacy nicht mehr verwenden. Daher sollten " "Sie stattdessen ein Upgrade der GRUB-2-Images auf diesen Datenträgern " "durchführen und die Umstellung auf GRUB 2 abschließen, indem Sie die alten " "GRUB-Legacy-Dateien entfernen. Falls Sie das Upgrade für diese GRUB-2-Images " "nicht durchführen, könnten diese mit den neuen Paketen nicht kompatibel sein " "und dazu führen, dass Ihr System nicht mehr einwandfrei startet." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Grundsätzlich sollten Sie die Umstellung auf GRUB 2 abschließen, es sei " "denn, diese GRUB-2-Boot-Sektoren wurden von einem anderen Betriebssystem " "installiert." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux-Befehlszeile:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Die folgende Linux-Befehlszeile wurde aus /etc/default/grub oder dem " "Parameter »kopt« in der Datei menu.lst von GRUB Legacy extrahiert. Bitte " "überprüfen Sie, ob die Befehlszeile korrekt ist und ändern Sie diese, wenn " "es notwendig ist. Diese Befehlszeile darf leer sein." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Standard-Befehlszeile für Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Die folgende Zeichenkette wird als Linux-Parameter für den " "Standardmenüeintrag, nicht aber für den Rettungsmodus verwandt." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Befehlszeile für kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Die folgende kFreeBSD-Befehlszeile wurde aus /etc/default/grub oder dem " "Parameter »kopt« in der Datei menu.lst von GRUB Legacy extrahiert. Bitte " "überprüfen Sie, ob diese korrekt ist und passen Sie sie an, wenn das " "erforderlich ist. Diese Befehlszeile darf leer sein." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Standard-Befehlszeile für kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Die folgende Zeichenkette wird als kFreeBSD-Parameter für den " "Standardmenüeintrag, nicht aber für den Rettungsmodus verwandt." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map wurde neu erstellt." #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Die Datei /boot/grub/device.map wurde umgeschrieben, um stabile Gerätenamen " "zu verwenden. In der Mehrzahl der Fälle sollte dies die Notwendigkeit " "zukünftiger Änderungen deutlich verringern. Von GRUB erstellte Boot-Menü-" "Einträge sollten nicht betroffen sein." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Da sich in diesem System mehrere Festplatten befinden, ist es möglich, dass " "das System von der alten »device map« abhängig ist. Bitte überprüfen Sie, " "obbenutzerdefinierte Boot-Menü-Einträge mit der (hdn)-Laufwerkszählung von " "GRUB vorhanden sind und aktualisieren Sie diese gegebenenfalls." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Wenn Sie diese Nachricht nicht verstehen oder wenn keine modifizierten Boot-" "Menü-Einträge vorhanden sind, können Sie diese Nachricht ignorieren." debian/po/sv.po0000664000000000000000000003666112524662415010621 0ustar # translation of grub2 debconf messages to Swedish # Swedish translation for grub2. # Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. # This file is distributed under the same license as the grub2 package. # # Daniel Nylander , 2007. # Martin Ågren , 2008, 2009. # Martin Bagge , 2010. msgid "" msgstr "" "Project-Id-Version: grub2_sv\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-06-02 03:22+0100\n" "Last-Translator: Martin Bagge / brother \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Language: Swedish\n" "X-Poedit-Country: Sweden\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Kedjeladda från menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "GRUB:s uppgraderingsskript har upptäckt en gammal GRUB-inställning i /boot/" "grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Om du vill ersätta den gamla versionen av GRUB i systemet, rekommenderas " "att /boot/grub/menu.lst justeras till att kedjeladda GRUB 2 från din " "existerande, gamla GRUB-inställning. Detta steg kan utföras automatiskt nu." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Det rekommenderas att GRUB 2 kedjeladdas från menu.lst så att det kan " "säkerställas att den nya GRUB 2-inställningen fungerar innan den installeras " "direkt till huvudstartsektorn (MBR)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Oberoende av ditt beslut kan den gamla MBR-avbildningen ersättas med GRUB 2 " "vid ett senare tillfälle genom att följande kommando utförs som root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB installationsenheter:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Paketet grub-pc uppdateras. Denna meny ger dig möjlighet att välja vilka, om " "några, enheter som grub-install ska köras automatiskt för." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Att köra grub-install automatiskt är rekomenderat i de flesta situationer " "för att förhindra att den installerade GRUB-huvudavbidlningen för att hamna " "i ett förhållande där GRUB-moduler eller grub.cfg inte är i korrekt läge." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Om du är osäker på vilken disk som är uppstartsdisken enligt BIOS så är det " "vanligen en god idé att installera GRUB på alla." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "OBS: det är möjligt att installera GRUB i partitionens uppstartsområde " "också, några av dessa visas nedan. Dock innebär installation där att GRUB " "tvingas använda en blockeringslista, som gör funktionen mindre pålitlig, och " "detta rekomenderas inte." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Uppstartshanteraren GRUB var tidigare installerad på en disk som inte längre " "finns tillgänglig eller vars unika identifikation har ändrats av någon " "anledning. Det är viktigt att säkerställa att den installerade GRUB-" "huvudavbildningen är korrekt i förhållande till GRUB-moduler och grub.cfg. " "Kontrollera återigen att GRUB är tillgänglig på rätt uppstartsenhet." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Skriva GRUB till uppstartsenhet misslyckades - fortsätta?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB kunde inte installeras på följande enheter:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Vill du fortsätta i alla fall? Det kan innebära att systemet inte kan starta " "korrekt." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Skrivningen av GRUB till uppstartsenheten misslyckades - försöka igen?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Du kan kanske installera GRUB till någon annan enhet, du bör dock " "kontrollera att systemet kommer att starta från den enheten. I annat fall " "kommer uppgraderingen från äldre GRUB-version att avbrytas." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Fortsätt utan att installera GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Du valde att inte installera GRUB på några enheter. Om du fortsätter kommer " "uppstartshanteraren kanske inte att få korrekta inställningar och när ditt " "system startar nästa gång kommer det att använda vad som tidigare fanns i " "boot-sektorn. Om en tidigare version av GRUB 2 används i boot-sektorn finns " "risk att vissa moduler inte kan laddas och hantera de aktuella " "inställningsfilerna." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Om du redan kör en annan uppstartshanterare och vill fortsätta med det eller " "om detta är en specialmiljö som inte behöver en uppstartshanterare ska du " "fortsätta i alla fall. I annat fall ska du installera GRUB någonstans." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Radera GRUB 2 från /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Vill du att alla GRUB 2-filer ska raderas från /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Detta innebär att systemet inte kan starta om ingen annan uppstartshanterare " "är installerad." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Avsluta konverteringen till GRUB 2 nu?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Detta system har fortfarande filer från den äldre GRUB-uppstartshanteraren " "installerade men nu finns det dessutom GRUB 2 uppstartsinformation på " "följande enheter:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Det är troligt att den äldre GRUB-versionen inte längre används och du bör " "istället uppgradera till GRUB 2-avbildningar på dessa enheter och avsluta " "konverteringen till GRUB 2 genom att ta bort äldre GRUB-filer. Om du inte " "vill uppgradera dessa GRUB 2-avbildningar kan de bli oanvändbara tillsammans " "med det nya paketet och systemet sluta att fungera korrekt." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Det generella rådet är att avsluta konverteringen till GRUB 2 om dessa filer " "inte skapats av en GRUB 2-installation på ett annat opertivsystem." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Kommandorad för Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Följande Linux-kommandorad hämtades från /etc/default/grub eller \"kopt\"-" "parametern i gamla GRUB:s menu.lst. Verifiera att den är korrekt och " "modifiera den om nödvändigt. Kommandoraden kan vara tom." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Standardkommandorad för Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Följande sträng kommer användas som Linux-parametrar för standardmenyvalet " "men inte för återhämtningsläge (eng. recovery)." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Kommandorad för kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Följande kFreeBSD-kommandorad hämtades från /etc/default/grub eller \"kopt\"-" "parametern i gamla GRUB:s menu.lst. Verifiera att den är korrekt och " "modifiera den om nödvändigt. Kommandoraden kan vara tom." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Standardkommandorad för kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Följande sträng kommer användas som Linux-parametrar för standardmenyvalet " "men inte för återhämtningsläge (eng. recovery)." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map har skapats på nytt" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Filen /boot/grub/device.map har skrivits om för att använda stabila " "enhetsnamn. I de allra flesta fall kommer detta innebära att anledningarna " "att byta namn i framtiden minskar drastiskt. Posterna i uppstartsmenyn som " "skapas av GRUB ska inte påverkas." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Dock, eftersom mer än en disk finns i systemet kan det innebära att systemet " "är beroende av den gamla enhetskopplingen. Kontrollera om det finns manuellt " "införda poster i uppstartsmenyn som är beroende av GRUB:s enhetsnumrering " "(hdN) och uppdatera dessa om nödvändigt." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Om du inte förstår detta meddelande eller om du inte har några alterantiva " "menyposter kan du ignorera detta meddelande." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "När GRUB 2 ska laddas direkt från huvudstartsektorn, kan detta " #~ "åstadkommas genom att (som root) köra följande kommando:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Installationen av GRUB misslyckades. Fortsätta?" debian/po/id.po0000664000000000000000000003563512524662415010565 0ustar # Grub2 translation to Bahasa Indonesia. # Copyright (C) Grub2 Developer # This file is distributed under the same license as the Grub2 package. # Arief S Fitrianto , 2010. # msgid "" msgstr "" "Project-Id-Version: grub2\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-01-20 12:28+0700\n" "Last-Translator: Mahyuddin Susanto \n" "Language-Team: Debian Indonesian Translation Team \n" "Language: id\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Indonesian\n" "X-Poedit-Country: INDONESIA\n" "X-Poedit-SourceCharset: utf-8\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Chainload dari menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Script pemutakhiran GRUB menemukan konfigurasi GRUB jadul di /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Untuk mengganti GRUB jadul pada sistem Anda, sangat disarankan menyesuaikan /" "boot/grub/menu.lst agar memuat citra boot GRUB2 dari konfigurasi GRUB Jadul. " "Langkah ini mungkin akan dilakukan otomatis sekarang." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Sangat disarankan Anda menerima hasil penyesuaian GRUB 2 dari menu.lst dan " "memastikan bahwa konfigurasi GRUB 2 bekerja dengan baik sebelum Anda " "memasangnya pada MBR (Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Apapun pilihan Anda, Anda dapat mengganti citra MBR lama dengan GRUB2 di " "lain waktu dengan menjalankan perintah berikut sebagai root: " #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Piranti pemasangan GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Paket grub-pc sedang diperbaharui. Menu ini memungkinkan Anda memilih " "piranti yang Anda inginkan untuk menjalankan grub-install." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Menjalankan grub-install secara otomatis sangat disarankan dalam kebanyakan " "kasus. Hal ini untuk mencegah citra inti GRUB yang terpasang tidak sesuai " "dengan modul GRUB atau grub.cfg" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Jika Anda tidak yakin piranti yang dijadikan piranti boot oleh BIOS, sangat " "disarankan untuk memasang GRUB di semua piranti dimaksud." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Catatan: sangat mungkin memasang GRUB di partisi boot dan beberapa partisi " "yang sesuai disajikan di sini. Tetapi, hal ini akan memaksa GRUB menggunakan " "mekanisme blocklist, yang membuatnya kurang handal dan oleh karenanya tidak " "disarankan." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "Pemuat boot GRUB sebelumnya telah dipasang di harddisk yang sekarang sudah " "lenyap atau identifikasi unik telah berubah karena suatu hal. Sangat penting " "memastikan citra inti GRUB yang terpasang selalu sesuai dengan modul GRUB " "dan grub.cfg. Mohon periksa kembali untuk memastikan GRUB ditulis di piranti " "boot yang sesuai." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Gagal menulis GRUB ke piranti boot -- lanjutkan?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Gagal memasang GRUB pada piranti berikut ini:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Anda yakin akan lanjut terus? Jika ya, komputer Anda mungkin tidak dapat " "beroperasi." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Gagal menulis GRUB ke piranti boot. Coba lagi?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Anda dapat memasang GRUB pada piranti lainnya. Tetapi, Anda harus memastikan " "komputer dapat boot dari piranti tersebut. Jika tidak, pemutakhiran dari " "GRUB jadul akan dibatalkan." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Lanjutkan tanpa memasang GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Anda memilih tidak memasang GRUB di piranti apapun. Jika Anda lanjutkan, " "pemuat boot mungkin tidak terkonfigurasi dengan benar. Jika komputer ini " "dinyalakan kembali, maka apapun yang sebelumnya ada di bootsector akan " "digunakan. Jika ada versi awal GRUB2 di bootsector, mungkin tidak dapat " "memuat modul-modul atau menangani berkas konfigurasi mutakhir." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Jika Anda telah menggunakan pemuat boot yang berbeda dan ingin tetap seperti " "itu, atau ada kebutuhan khusus yang membuat Anda tidak memerlukan pemuat " "boot, maka Anda bisa melanjutkan terus. Jika tidak, Anda harus memasang GRUB " "di tempat lain." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Hapus GRUB 2 dari /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Yakinkah Anda ingin menghapus semua berkas GRUB 2 dari /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Hal ini akan membuat sistem tidak dapat booting kecuali Anda memasang pemuat " "boot lainnya." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Selesaikan proses konversi ke GRUB2 sekarang?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Sistem ini masih memiliki berkas-berkas dari pemuat boot GRUB Jadul, tapi " "sekarang juga memiliki rekam boot GRUB2 di piranti berikut:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Tampaknya GRUB Jadul sudah tidak terpakai, dan Anda sebaiknya memasang citra " "GRUB2 pada harddisk ini, lalu menyelesaikan proses konversi ke GRUB2 dengan " "menghapus berkas-berkas GRUB Jadul. Jika Anda tidak memutakhirkan citra " "GRUB2, maka mungkin akan ada masalah inkompatibilitas dengan paket-paket " "baru dan membuat sistem Anda tidak dapat booting dengan benar." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Anda sebaiknya menyelesaikan konversi ke GRUB2 kecuali jika rekam boot ini " "dibuat melalui pemasangan GRUB2 pada sistem operasi lain." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Baris perintah Linux:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Baris perintah Linux berikut ini disadur dari /etc/default/grub atau " "parameter 'kopt' di menu.lst pada GRUB jadul. Pastikan kebenarannya dan " "suntinglah bila perlu. Baris perintahnya diperbolehkan dikosongi." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Baris perintah standar Linux:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "String berikut ini akan digunakan sebagai parameter Linux untuk menu standar " "tetapi tidak digunakan untuk modus darurat." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Baris perintah kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Baris perintah kFreeBSD berikut ini disadur dari /etc/default/grub atau " "parameter 'kopt' di menu.lst pada GRUB jadul. Pastikan kebenarannya dan " "suntinglah bila perlu. Baris perintahnya diperbolehkan dikosongi." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Baris perintah standar kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "String berikut ini digunakan sebagai parameter kFreeBSD untuk menu standar, " "tetapi tidak digunakan untuk modus darurat." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map telah dibuat ulang." #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Berkas /boot/grub/device.map telah ditulis ulang agar menggunakan nama " "piranti yang stabil. Dalam kebanyakan kasus, hal ini berarti mengurangi " "kemungkinan perubahan di masa datang, dan isian menu boot yang dibuat oleh " "GRUB tidak akan terpengaruh." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Akan tetapi, karena ada lebih dari satu harddisk pada sistem ini, sangat " "mungkin bahwa Anda bergantung pada peta piranti yang lama. Mohon periksa " "apakah Anda memiliki isian menu boot GRUB secara manual yang menggunakan " "penomoran harddisk (hdN). Jika ya, perbaiki yang diperlukan. " #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Jika Anda tidak mengerti pesan ini atau jika tidak memiliki isian menu boot " "secara manual, Anda bisa mengabaikan pesan ini." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Di semua kasus, ketika Anda ingin agar GRUB 2 dimuatkan langsung dari " #~ "MBR, Anda dapat melakukan (sebagai root) perintah berikut:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "Gagal memasang GRUB. Lanjutkan?" debian/po/is.po0000664000000000000000000003610712524662415010577 0ustar # translation of grub_debian_po_is.po to Icelandic # Copyright (C) 2010 Free Software Foundation # This file is distributed under the same license as the GRUB package. # # Sveinn í Felli , 2010, 2011, 2012. msgid "" msgstr "" "Project-Id-Version: grub_debian_po_is\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-01-20 09:44+0000\n" "Last-Translator: Sveinn í Felli \n" "Language-Team: Icelandic \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" ">\n" "X-Generator: KBabel 1.11.4\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Raðhlaða (chainload) úr menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Uppfærsluskriftur GRUB hafa fundið eldri uppsetningu GRUB í /boot/grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Til að skipta eldri uppsetningu GRUB út af kerfinu, þá er mælt með því að /" "boot/grub/menu.lst sé stillt til að raðhlaða (chainload) GRUB 2 ræsidiskmynd " "frá þessari eldri uppsetningu á GRUB. Hægt er að framkvæma þetta skref " "sjálfvirkt núna." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Mælt með því að þú samþykkir að raðhlaða GRUB 2 úr menu.lst, auk þess að þú " "skoðir hvort nýja GRUB 2 uppsetningin virki fyrir þig, áður en þetta er " "skrifað á MBR ræsigeirann (Master Boot Record)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Hvað svosem þú ákveður, þá getur þú síðar skipt gömlu MBR myndinni út fyrir " "GRUB2 með því að gefa eftirfarandi skipun (sem kerfisstjóri/root):" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB uppsetningartæki:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "Verið er að uppfæra grub-pc pakkann. Þessi valmynd gerir þér kleift að velja " "af hvaða tækjum hægt er að keyra grub-install sjálfvirkt, ef þá nokkrum." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Mælt er með í flestum tilfellum að keyra grub-install sjálfvirkt, til þess " "að koma í veg fyrir að uppsetta GRUB aðalmyndin hætti að vera samstillt við " "GRUB-einingar eða grub.cfg stilliskrána." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Ef þú ert ekki viss um hvaða diskur er skilgreindur sem ræsidrif í BIOS, þá " "er oft góð hugmynd að setja GRUB upp á alla diskana." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Athugasemd: Það er líka hægt að setja GRUB upp á ræsigeira disksneiða, hér " "eru nokkrar viðeigandi disksneiðar í boði. Á móti kemur að þetta þvingar " "GRUB til að nota blokklista (blocklist mechanism), sem gerir GRUB ekki eins " "áreiðanlegt; því er ekki mælt með þessu." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "GRUB ræsistjórinn vað áður uppsettur á disk sem ekki er lengur til staðar " "eða sem hefur af einhverjum ástæðum fengið nýtt auðkenni/tilvísun. Það er " "mikilvægt að ganga úr skugga um að uppsetta GRUB aðalmyndin sé samstillt við " "GRUB-einingar og grub.cfg stilliskrána.. Athugaðu aftur hvort GRUB sé " "skrifað á viðeigandi ræsitæki." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Uppsetning GRUB á ræsitæki mistókst. Halda áfram?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "Uppsetning GRUB mistókst á eftirfarandi tækjum:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Viltu samt halda áfram? Ef þú gerir það er ekki víst að tölvan þín ræsist " "aftur eðlilega." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Uppsetning GRUB á ræsitæki mistókst. Reyna aftur?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Þú gætir hugsanlega sett GRUB upp á eitthvað annað tæki, samt ættirðu að " "skoða vel hvort kerfið þitt sé fært um að ræsa upp af því tæki. Að öðrum " "kosti verður hætt við uppfærslu gamla GRUB ræsistjórans." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Halda áfram án þess að setja upp GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Þú valdir að setja GRUB ekki upp á neitt tæki. Ef þú heldur áfram verður " "ræsistjórinn ekki rétt stilltur, og þegar tölvan þín ræsist næst mun hún " "nota hvað það sem fyrir er núna á ræsigeiranum. Ef á ræsigeiranum er til " "dæmis eldri útgáfa af GRUB 2, er möguleiki á að hún ráði ekki við að hlaða " "inn ákveðnum kjarnaeiningum eða nái ekki að lesa stillingaskrána fyrir þetta " "stýrikerfi." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Ef þú ert þegar að nota einhvern annan ræsistjóra og ætlar að halda því " "áfram, eða ef þetta er eitthvað sérhannað kerfi sem ekki þarfnast " "ræsistjóra; þá ættirðu að halda samt áfram. Ef ekki, ættirðu að setja GRUB " "upp einhversstaðar." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Fjarlægja GRUB 2 úr /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Viltu láta fjarlægja allar GRUB 2 skrár úr /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Þetta mun gera kerfið óræsanlegt nema einhver annar ræsistjóri sé settur upp." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Ljúka núna umbreytingu í GRUB 2 ?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Þetta kerfi er ennþá með uppsettar skrár frá eldri uppsetningu GRUB, en er " "núna einnig með GRUB 2 ræsifærslur uppsettar á þessum diskum:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Það lítur út fyrir að eldra GRUB sé ekki lengur í notkun og að þú ættir þá " "að uppfæra GRUB 2 myndirnar á þessum diskum og ljúka svo yfirfærslunni í " "GRUB 2 með því að fjarlægja gömlu GRUB skrárnar. Ef þú uppfærir ekki þessar " "GRUB 2 myndir gætu þær orðið ósamhæfðar við nýju pakkana og koma í veg fyrir " "að kerfið ræsist eðlilega." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Almennt ættirðu að ljúka umbreytingu í GRUB 2 nema ef þessar ræsifærslur " "hafi verið útbúnar af GRUB 2 uppsetningu í einhverju öðru stýrikerfi." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linux skipanalína:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Eftirfarandi Linux skipanalína fannst í /etc/default/grub eða í `kopt' " "viðfanginu í eldri GRUB menu.lst. Gakktu úr skugga um að þetta sé rétt og " "breyttu því ef það er nauðsynlegt. Skipanalínan má vera auð." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Sjálfgefin Linux skipanalína:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "Eftirfarandi strengur verður notaður sem Linux viðfang í sjálfgenu " "valmyndarfærslunni en ekki í viðgerðarham." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD skipanalína:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "Eftirfarandi kFreeBSD skipanalína fannst í /etc/default/grub eða í `kopt' " "viðfanginu í eldri GRUB menu.lst. Gakktu úr skugga um að þetta sé rétt og " "breyttu því ef það er nauðsynlegt. Skipanalínan má vera auð." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Sjálfgefin kFreeBSD skipanalína:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "Eftirfarandi strengur verður notaður sem kFreeBSD viðfang í sjálfgenu " "valmyndarfærslunni en ekki í viðgerðarham." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map var endurskrifað" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "Skráin /boot/grub/device.map hefur verið endurskrifuð til að nota föst " "tækjaheiti. Í flestum tilfellum þýðir þetta að færri ástæður geta komið upp " "til að breyta þeim í framtíðinni og að færslur í GRUB ræsivalmyndinni ættu " "síður að verða fyrir breytingum." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Aftur á móti, þar sem fleiri en einn diskur eru til staðar í kerfinu, þá er " "alveg hugsanlegt að kerfið reiði sig á gömlu tækjaskrána (device map). " "Athugaðu hvort það séu einhverjar sérsniðnar ræsifærslur sem nota eldri GRUB " "(hdN) diskaskilgreiningar, og uppfærðu þær þá ef nauðsyn krefur." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Ef þú skilur ekki þessi skilaboð, eða ef þú hefur engar sérsniðnar " "ræsifærslur, þá geturðu hunsað skilaboðin." debian/po/eo.po0000664000000000000000000003561612524662415010573 0ustar # grub2 po-debconf translation to Esperanto # Copyright (C) 2010, 2011 Software in the Public Interest # This file is distributed under the same license as the grub2 package. # Felipe Castro , 2010, 2011. # msgid "" msgstr "" "Project-Id-Version: grub2 1.99-5\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2011-06-29 21:08-0300\n" "Last-Translator: Felipe Castro \n" "Language-Team: Esperanto \n" "Language: eo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "Ĉu ĉen-ŝargi (chainload) el menu.lst?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "" "Aktualigaj skriptoj de GRUB detektis agordon de la malaktuala GRUB en /boot/" "grub." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "Por anstataŭigi la malaktualan version de GRUB en via sistemo, oni " "rekomendas ke /boot/grub/menu.lst estu akomodita por ŝargi je ekŝarga bildo " "GRUB 2 el via ekzistanta agordo de malaktuala GRUB. Tiu ĉi paŝo povas esti " "aŭtomate farata nun." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "Oni rekomendas ke vi akceptu ĉen-ŝargi je GRUB 2 el menu.lst, kaj kontrolu " "ĉu via nova agordo de GRUB 2 bone funkcias antaŭ ol ĝi estu skribata al la " "MBR (Mastra Ekŝarga Registro)." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "Kia ajn estu via decido, per GRUB 2 vi povos poste anstataŭigi la malnovan " "bildon MBR, uzante la jenan komandon kiel root:" #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "Aparatoj instalataj de GRUB:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "La pako grub-pc estas ĝisdatigata. Tiu ĉi menuo ebligas al vi elekti iujn " "ajn aparatojn por esti aŭtomate instalotaj de grub-install." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "Lanĉi grub-install aŭtomate estas rekomendinda plej kutime, por eviti ke la " "instalita kerna bildo GRUB malsinkroniĝu kun la moduloj GRUB aŭ grub.cfg." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "Se vi ne certas pri kiu pelilo estas difinita kiel ekŝarga por via BIOS, " "ordinare estas bona ideo instali GRUB por ĉiuj el ili." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "Rimarko: eblas instali GRUB ankaŭ al diskpartaj ekŝargaj registroj, kaj " "kelkaj taŭgaj diskpartoj estas disponigataj ĉi tie. Tamen, tio devigas ke " "GRUB uzu meĥanismon bloklisto, kio igas ĝin malpli fidinda, do tio ne estas " "rekomendinda afero." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "La ekŝargilo GRUB estis antaŭe instalita al disko kiu ne plu ekzistas, " "aŭ kies unika identigilo ŝanĝis ial ajn. Estas grave certigi ke la instalita " "kerna bildo GRUB teniĝu sinkrona kun la moduloj GRUB kaj grub.cfg. Bonvolu " "rekontroli por certigi ke GRUB estas skribota al taŭgaj ekŝargaj aparatoj." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} MB; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} MB; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "Skribado de GRUB al ekŝarga aparato malsukcesis - ĉu daŭrigi?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB malsukcesis instali al la jenaj aparatoj:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "Ĉu vi volas daŭrigi iel ajn? Se jes, eble via komputilo ne ekŝargiĝu ĝuste." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "Skribado de GRUB al ekŝarga aparato malsukcesis - ĉu reprovi?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "Vi povas instali GRUB en iu alia aparato, kvankam vi devos kontroli ĉu via " "sistemo ekŝargiĝos el tiu aparato. Alimaniere, la aktualigo el malnova GRUB " "estos nuligata." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "Ĉu daŭrigi sen instali GRUB?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "Vi elektis ne instali GRUB al iu ajn aparato. Se vi daŭrigas, la ekŝargilo " "eble ne estos ĝuste agordita, kaj kiam tiu ĉi komputilo sekve ekŝaltos, ĝi " "uzos kion ajn estu antaŭe en la ekŝarga sektoro. Se ekzistas pli frua versio " "de GRUB 2 en la ekŝarga sektoro, ĝi eble ne povos ŝargi je moduloj aŭ trakti " "la nunan agordo-dosieron." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "Se vi jam uzas malsaman ekŝargilon kaj vi volas daŭrigi kun tio, aŭ se tio " "ĉi estas speciala medio kie vi ne bezonas ekŝargilon, tiam vi devos daŭrigi " "tiel mem. Alie, vi devos instali GRUB ien ajn." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "Ĉu forviŝi GRUB 2 el /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "Ĉu vi volas forviŝi ĉiujn dosierojn GRUB 2 el /boot/grub?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "" "Tio ĉi igos la sistemon ne ekŝargebla, krom se alia ekŝargilo estu instalita." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "Ĉu finigi konverton al GRUB 2 nun?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "Tiu ĉi sistemo ankoraŭ havas dosierojn el la malaktuala ekŝargilo GRUB " "instalita, sed ĝi nun ankaŭ havas ekŝargajn registrojn de GRUB 2 instalitaj " "en tiuj ĉi diskoj: " #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "Ŝajnas ke la malaktuala GRUB ne plu estas uzata, kaj ke vi devos anstataŭe " "aktualigi al bildoj GRUB 2 en tiuj ĉi diskoj, kaj finigi la konverton al " "GRUB 2 forigante malnovajn malaktualajn dosierojn GRUB. Se vi ne aktualigos " "tiujn ĉi bildojn GRUB 2, tiel ili povos esti malkongruaj al la novaj pakoj " "igante ke via sistemo ĉesu ekŝargi senprobleme." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "Vi devos ordinare finigi la konverton al GRUB 2, malkondiĉe ke tiuj ĉi " "ekŝarg-registroj estu kreitaj de sistemo kun GRUB 2 instalita, en alia " "operaciuma sistemo." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "Linuksa komand-linio:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La jena linuksa komand-linio estas elprenita el /etc/default/grub aŭ el la " "parametro 'kopt' en la menu.lst de malaktuala GRUB. Bonvolu kontroli ĉu ĝi " "estas korekta, kaj modifu ĝin laŭ neceso. Estas permesate ke la komand-linio " #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "Linuksa implicita komand-linio:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "La jena ĉeno estos uzata kiel linuksajn parametrojn por la ordinara menuero " "sed ne por la restariga reĝimo." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "Ordon-linio de kFreeBSD:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "La jena linuksa komand-linio de kFreeBSD estas elprenita el /etc/default/" "grub aŭ el la parametro 'kopt' en la menu.lst de malaktuala GRUB. Bonvolu " "kontroli ĉu ĝi estas korekta, kaj modifu ĝin laŭ neceso. Estas permesate ke " "la komand-linio estu malplena." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "Implicita komand-linio de kFreeBSD:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "La jena ĉeno estos uzata kiel parametrojn de kFreeBSD por la ordinara " "menuero sed ne por la restariga reĝimo." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map estas regenerita" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "La dosiero /boot/grub/device.map estas reskribita por uzi stabilajn aparat-" "nomojn. En la plejparto de la situacioj, tio devus multe malpliigi la " "bezonon ŝanĝi ĝin estonte, kaj ekŝarg-menueroj kreitaj de GRUB ne devos esti " "influataj." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "Tamen, ĉar vi havas pli ol unu disko en via sistemo, eblas ke la sistemo " "dependas de malnova aparat-mapo. Bonvolu kontroli ĉu ekzistas iun " "personigitan ekŝarg-menueron, kiu surbaziĝas en disk-numerigo de GRUB (hdN), " "kaj ĝisdatigu ĝin se necese." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "Se vi ne komprenas tiun ĉi mesaĝon, aŭ se vi havas neniun personigitan " "ekŝargan menueron, vi povas preteratenti ĉi tiun mesaĝon." #~ msgid "" #~ "In either case, whenever you want GRUB 2 to be loaded directly from MBR, " #~ "you can do so by issuing (as root) the following command:" #~ msgstr "" #~ "Ĉiukondiĉe, kiam vi volos ke GRUB 2 estu rekte ŝargata el MBR, vi povos " #~ "fari tion per lanĉado (kie root) de la jena komando:" #~ msgid "GRUB installation failed. Continue?" #~ msgstr "La instalado de GRUB malsukcesis. Ĉu daŭrigi?" debian/po/gu.po0000664000000000000000000005036512524662415010601 0ustar # Gujarati translation of grub2. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Kartik Mistry , 2012. # msgid "" msgstr "" "Project-Id-Version: grub-gu\n" "Report-Msgid-Bugs-To: grub2@packages.debian.org\n" "POT-Creation-Date: 2011-05-27 13:33+0100\n" "PO-Revision-Date: 2012-03-04 09:56+0530\n" "Last-Translator: Kartik Mistry \n" "Language-Team: Gujarati \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "Chainload from menu.lst?" msgstr "menu.lst માંથી ચેઈનલોડ કરશો?" #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub." msgstr "GRUB સુધારાની સ્ક્રિપ્ટએ /boot/grub માં પરંપરાગત GRUB ગોઠવણીની જાણ મેળવી છે." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "In order to replace the Legacy version of GRUB in your system, it is " "recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image " "from your existing GRUB Legacy setup. This step can be automatically " "performed now." msgstr "" "તમારી સિસ્ટમમાંથી પરંપરાગત GRUB ને બદલવા માટે, એ સલાહભર્યું છે કે /boot/grub/menu.lst " "એ GRUB 2 બૂટ ઈમેજ લાવવા માટે તમારી હાલના પરંપરાગત GRUB ગોઠવણીમાંથી ગોઠવેલ હોય. આ " "ગોઠવણી હવે પછી આપમેળે રજૂ કરવામાં આવશે." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "It's recommended that you accept chainloading GRUB 2 from menu.lst, and " "verify that the new GRUB 2 setup works before it is written to the MBR " "(Master Boot Record)." msgstr "" "એ સલાહભર્યું છે કે તમે menu.lst માંથી GRUB 2 ચેઈનલોડિંગ સ્વિકારો, અને ચકાસો કે નવી GRUB " "2 ગોઠવણી MBR (માસ્ટર બૂટ રેકોર્ડ) માં લખાય તે પહેલાં કામ કરી રહી છે." #. Type: boolean #. Description #: ../grub-pc.templates.in:2001 msgid "" "Whatever your decision, you can replace the old MBR image with GRUB 2 later " "by issuing the following command as root:" msgstr "" "તમારો નિર્ણય કંઈ પણ હોય, તમે પાછળથી નીચેના આદેશનો રુટ તરીકે ઉપયોગ કરીને જૂની MBR ઈમેજને " "GRUB 2 વડે બદલી શકો છો." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "GRUB install devices:" msgstr "GRUB સ્થાપન ઉપકરણો:" #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "The grub-pc package is being upgraded. This menu allows you to select which " "devices you'd like grub-install to be automatically run for, if any." msgstr "" "grub-pc પેકેજ સુધારાઈ રહ્યું છે. આ મેનુ તમને કયા ઉપકરણોમાં તમે grub-install આપમેળે સ્થાપિત " "કરવા માટે ચલાવવા માંગો છો તે પસંદગી કરવા દે છે, જો કોઈ હોય તો." #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 msgid "" "Running grub-install automatically is recommended in most situations, to " "prevent the installed GRUB core image from getting out of sync with GRUB " "modules or grub.cfg." msgstr "" "સ્થાપિત GRUB મુખ્ય ઈમેજને GRUB મોડ્યુલ્સ અથવા grub.cfg સાથે અસંગત ન થવા દેવા માટે, grub-" "install આપમેળે ચલાવવું એ મોટાભાગની પરિસ્થિતિઓમાં સલાહભર્યું છે." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "If you're unsure which drive is designated as boot drive by your BIOS, it is " "often a good idea to install GRUB to all of them." msgstr "" "જો તમે અચોક્કસ હોવ કે તમારા BIOS વડે કયું ડ્રાઈવ એ બૂટ ડ્રાઈવ તરીકે ગોઠવેલ છે, એ સારો " "વિચાર છે કે તે દરેક ઉપર GRUB સ્થાપિત કરવામાં આવે." #. Type: multiselect #. Description #. Type: multiselect #. Description #: ../grub-pc.templates.in:3001 ../grub-pc.templates.in:4001 msgid "" "Note: it is possible to install GRUB to partition boot records as well, and " "some appropriate partitions are offered here. However, this forces GRUB to " "use the blocklist mechanism, which makes it less reliable, and therefore is " "not recommended." msgstr "" "નોંધ: GRUB ને પાર્ટિશન બૂટ રેકોર્ડ પર સ્થાપિત કરવાનું પણ શક્ય છે, અને કેટલાક સંબંધિત " "પાર્ટિશન્સ અહીં આપવામાં આવે છે. તેમ છતાં, આ GRUB ને બ્લોકલિસ્ટ પધ્ધતિ વાપરવા માટે મજબૂર કરે " "છે, જે તેને ઓછું ભરોસાપાત્ર બનાવે છે, અને તેથી, આ સલાહભર્યું નથી." #. Type: multiselect #. Description #: ../grub-pc.templates.in:4001 msgid "" "The GRUB boot loader was previously installed to a disk that is no longer " "present, or whose unique identifier has changed for some reason. It is " "important to make sure that the installed GRUB core image stays in sync with " "GRUB modules and grub.cfg. Please check again to make sure that GRUB is " "written to the appropriate boot devices." msgstr "" "ડિસ્ક પર પહેલાં સ્થાપન કરેલ GRUB બૂટ લોડર હવે હાજર નથી, અથવા તેની ઐક્ય ઓળખ કોઈ " "કારણોસર બદલાઈ ગઈ છે. એ મહત્વનું છે કે સ્થાપિત GRUB મુખ્ય ઈમેજ GRUB મોડ્યુલ્સ અને grub.cfg " "જોડે સંગત રહે તેની ખાતરી કરાઈ હોય. મહેરબાની કરી ફરીથી ખાતરી કરી ચકાસો કે GRUB એ " "યોગ્ય બૂટ ઉપકરણોમાં લખાયેલ છે." #. Type: text #. Description #. Disk sizes are in decimal megabytes, to match how disk manufacturers #. usually describe them. #: ../grub-pc.templates.in:5001 msgid "${DEVICE} (${SIZE} MB; ${MODEL})" msgstr "${DEVICE} (${SIZE} એમબી; ${MODEL})" #. Type: text #. Description #. The "-" is used to indicate indentation. Leading spaces may not work. #: ../grub-pc.templates.in:6001 msgid "- ${DEVICE} (${SIZE} MB; ${PATH})" msgstr "- ${DEVICE} (${SIZE} એમબી; ${PATH})" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "Writing GRUB to boot device failed - continue?" msgstr "GRUB ને બૂટ ઉપકરણમાં લખવાનું નિષ્ફળ ગયું - ચાલુ રાખશો?" #. Type: boolean #. Description #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 ../grub-pc.templates.in:8001 msgid "GRUB failed to install to the following devices:" msgstr "GRUB નીચેના ઉપકરણોમાં સ્થાપિત થવામાં નિષ્ફળ ગયું:" #. Type: boolean #. Description #: ../grub-pc.templates.in:7001 msgid "" "Do you want to continue anyway? If you do, your computer may not start up " "properly." msgstr "" "તમે તેમ છતાં આગળ વધવા માંગો છો? જો તમે તેમ કરશો તો, તમારું કોમ્પ્યુટર કદાચ યોગ્ય રીતે " "શરુથશે નહી." #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "Writing GRUB to boot device failed - try again?" msgstr "GRUB ને બૂટ ઉપકરણમાં લખવાનું નિષ્ફળ ગયું - ફરી પ્રયત્ન કરશો?" #. Type: boolean #. Description #: ../grub-pc.templates.in:8001 msgid "" "You may be able to install GRUB to some other device, although you should " "check that your system will boot from that device. Otherwise, the upgrade " "from GRUB Legacy will be canceled." msgstr "" "તમે કદાચ GRUB બીજા ઉપકરણમાં સ્થાપિત કરી શકો છો, તેમ છતાં ચકાસો કે તમારી સિસ્ટમ આ " "ઉપકરણમાંથી બૂટ થઈ શકશે. અથવા તો, GRUB પરંપરાગતમાંથી સુધારો રદ કરવામાં આવશે." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "Continue without installing GRUB?" msgstr "GRUB સ્થાપન કર્યા વગર આગળ વધશો?" #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "You chose not to install GRUB to any devices. If you continue, the boot " "loader may not be properly configured, and when this computer next starts up " "it will use whatever was previously in the boot sector. If there is an " "earlier version of GRUB 2 in the boot sector, it may be unable to load " "modules or handle the current configuration file." msgstr "" "તમે GRUB ને કોઈપણ ઉપકરણમાં સ્થાપિત કરવાનું પસંદ કરેલ નથી, જો તમે ચાલુ રાખશો તો, બૂટ " "લોડર કદાચ યોગ્ય રીતે ગોઠવાયેલ નહી હોય, અને આ કોમ્પ્યુટર હવે ફરી શરુ થાય ત્યારે તે પહેલાંનું " "જે હોય તે બૂટ વિભાગ ઉપયોગ કરશે. જો તેમાં પહેલાની GRUB 2 આવૃત્તિ બૂટ સેક્ટર પર હશે તો, " "કદાચ તે મોડ્યુલ લાવવા અથવા હાલનાં રુપરેખાંકન ફાઈલને સંભાળવામાં અસમર્થ બનશે." #. Type: boolean #. Description #: ../grub-pc.templates.in:9001 msgid "" "If you are already using a different boot loader and want to carry on doing " "so, or if this is a special environment where you do not need a boot loader, " "then you should continue anyway. Otherwise, you should install GRUB " "somewhere." msgstr "" "જો તમે પહેલાથી બીજું બૂટ લોડર વાપરી રહ્યા હોવ અને તેમ કરવાનું ચાલુ રાખવા માંગતા હોય તો, " "અથવા આ ખાસ પર્યાવરણ હોય જ્યાં તમારે બૂટ લોડરની જરુર ન હોય તો તમે આગળ વધી શકો છો. " "નહીતર, તમારે ક્યાંક GRUB સ્થાપિત કરવું જોઈએ." #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Remove GRUB 2 from /boot/grub?" msgstr "/boot/grub માંથી GRUB ૨ દૂર કરશો?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "Do you want to have all GRUB 2 files removed from /boot/grub?" msgstr "તમે /boot/grub માંથી બધી GRUB 2 ફાઈલ્સ દૂર કરવા માંગો છો?" #. Type: boolean #. Description #: ../grub-pc.templates.in:10001 msgid "" "This will make the system unbootable unless another boot loader is installed." msgstr "આ તમારી સિસ્ટમને શરુ ન કરવા જેવી બનાવશે જ્યાં સુધી બીજું બૂટ લોડર સ્થાપિત નહી હોય." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "Finish conversion to GRUB 2 now?" msgstr "GRUB ૨ માં રુપાંતર હવે પૂર્ણ થયું?" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "This system still has files from the GRUB Legacy boot loader installed, but " "it now also has GRUB 2 boot records installed on these disks:" msgstr "" "આ સિસ્ટમમાં સ્થાપિત કરેલ GRUB પરંપરાગત બૂટ લોડરમાંથી ફાઈલ્સ હાજર રહેલ છે, પણ તેમાં નીચેની " "ડિસ્ક્સ પર GRUB 2 બૂટ રેકોર્ડ્સ સ્થાપિત કરેલ છે:" #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "It seems likely that GRUB Legacy is no longer in use, and that you should " "instead upgrade the GRUB 2 images on these disks and finish the conversion " "to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these " "GRUB 2 images, then they may be incompatible with the new packages and cause " "your system to stop booting properly." msgstr "" "એવું જણાય છે કે GRUB પરંપરાગત હવે વપરાશમાં નથી, અને તમારે આ ડિસ્ક્સ પર GRUB 2 ઈમેજ સુધારી " "અને GRUB 2 માં રુપાંતરણ GRUB પરંપરાગત ફાઈલ્સ દૂર કરીને પુરું કરવું જોઈએ. જો તમે આ GRUB 2 " "ઈમેજ સુધારશો નહી તો, તે નવાં પેકેજીસ સાથે અસંગત હશે અને તમારી સિસ્ટમને યોગ્ય રીતે શરુ થતા " "અટકાવી શકે છે." #. Type: boolean #. Description #: ../grub-pc.templates.in:11001 msgid "" "You should generally finish the conversion to GRUB 2 unless these boot " "records were created by a GRUB 2 installation on some other operating system." msgstr "" "તમે સામાન્ય રીતે GRUB 2 માં રુપાંતર કરી લીધું છે સિવાય કે આ બૂટ રેકોર્ડ GRUB 2 સ્થાપન વડે " "કોઈ બીજી ઓપરેટિંગ સિસ્ટમમાં બનાવવામાં આવ્યા હોય." #. Type: string #. Description #: ../templates.in:1001 msgid "Linux command line:" msgstr "લિનક્સ આદેશ:" #. Type: string #. Description #: ../templates.in:1001 msgid "" "The following Linux command line was extracted from /etc/default/grub or the " "`kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "નીચેનાં લિનક્સ આદેશ /etc/default/grub અથવા GRUB પરંપરાગત menu.lst ના `kopt' " "પરિમાણમાંથી નીકાળવામાં આવ્યા છે. મહેરબાની કરી ખાતરી કરો કે એ સાચા છે, અને જરુરી હોય " "તો તેને બદલો. આદેશ ખાલી રાખવાનું માન્ય છે." #. Type: string #. Description #: ../templates.in:2001 msgid "Linux default command line:" msgstr "લિનક્સ મૂળભૂત આદેશ:" #. Type: string #. Description #: ../templates.in:2001 msgid "" "The following string will be used as Linux parameters for the default menu " "entry but not for the recovery mode." msgstr "" "નીચેનું વાક્ય મૂળભૂત મેનુ રીત માટે લિનક્સ પરિમાણો માટે વાપરવામાં આવશે પણ રીકવરી સ્થિતિ માટે " "નહી." #. Type: string #. Description #: ../templates.in:3001 msgid "kFreeBSD command line:" msgstr "kFreeBSD આદેશ:" #. Type: string #. Description #: ../templates.in:3001 msgid "" "The following kFreeBSD command line was extracted from /etc/default/grub or " "the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is " "correct, and modify it if necessary. The command line is allowed to be empty." msgstr "" "નીચેનાં kFreeBSD આદેશ /etc/default/grub અથવા GRUB પરંપરાગત menu.lst ના `kopt' " "પરિમાણમાંથી નીકાળવામાં આવ્યા છે. મહેરબાની કરી ખાતરી કરો કે એ સાચા છે, અને જરુરી હોય " "તો તેને બદલો. આદેશ ખાલી રાખવાનું માન્ય છે." #. Type: string #. Description #: ../templates.in:4001 msgid "kFreeBSD default command line:" msgstr "kFreeBSD મૂળભૂત આદેશ:" #. Type: string #. Description #: ../templates.in:4001 msgid "" "The following string will be used as kFreeBSD parameters for the default " "menu entry but not for the recovery mode." msgstr "" "નીચેનું વાક્ય મૂળભૂત મેનુ રીત માટે kFreeBSD પરિમાણો માટે વાપરવામાં આવશે પણ રીકવરી સ્થિતિ " "માટે નહી." #. Type: note #. Description #: ../templates.in:5001 msgid "/boot/grub/device.map has been regenerated" msgstr "/boot/grub/device.map ફરી બનાવવામાં આવી છે" #. Type: note #. Description #: ../templates.in:5001 msgid "" "The file /boot/grub/device.map has been rewritten to use stable device " "names. In most cases, this should significantly reduce the need to change it " "in future, and boot menu entries generated by GRUB should not be affected." msgstr "" "ફાઈલ /boot/grub/device.map સ્થિત ઉપકરણ નામો ઉપયોગ કરવા માટે ફરી લખાઈ છે. " "મોટાભાગનાં કિસ્સાઓમાં, આ ભવિષ્યમાં મોટાભાગે તેને બદલવાની જરુરિયાત ઓછી કરી દેશે, અને GRUB " "વડે બનાવેલ દાખલાઓ પર અસર નહી કરે." #. Type: note #. Description #: ../templates.in:5001 msgid "" "However, since more than one disk is present in the system, it is possible " "that the system is depending on the old device map. Please check whether " "there are any custom boot menu entries that rely on GRUB's (hdN) drive " "numbering, and update them if necessary." msgstr "" "તેમ છતાં, સિસ્ટમમાં એક કરતાં વધુ ડિસ્ક હાજર હોવાથી, એ શક્ય છે કે સિસ્ટમ જૂનાં ઉપકરણ નકશા " "પર આધાર રાખતી હોય. મહેરબાની કરી ચકાસો કે અહીં કોઈ પોતાની મેનુ યાદી છે જે GRUB ના " "(hdN) ડ્રાઈવ આંકડાઓ પર આધાર રાખતી હોય, અને તેને જરુરી હોય તો સુધારો." #. Type: note #. Description #: ../templates.in:5001 msgid "" "If you do not understand this message, or if there are no custom boot menu " "entries, you can ignore this message." msgstr "" "જો તમને આ સંદેશ સમજવામાં ન આવે, અથવા કોઈ પોતાની બૂટ મેનુ રીત ન હોય તો, તમે આ સંદેશ " "અવગણી શકો છો." debian/grub-common.init0000664000000000000000000000212112524662415012305 0ustar #! /bin/sh ### BEGIN INIT INFO # Provides: grub-common # Required-Start: $all # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: # Short-Description: Record successful boot for GRUB # Description: GRUB displays the boot menu at the next boot if it # believes that the previous boot failed. This script # informs it that the system booted successfully. ### END INIT INFO which grub-editenv >/dev/null 2>&1 || exit 0 # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. . /lib/lsb/init-functions case $1 in start|restart|force-reload) [ "$VERBOSE" != no ] && log_action_msg "Recording successful boot for GRUB" [ -s /boot/grub/grubenv ] || rm -f /boot/grub/grubenv mkdir -p /boot/grub grub-editenv /boot/grub/grubenv unset recordfail [ "$VERBOSE" != no ] && log_end_msg $? ;; stop) ;; status) exit 0 ;; *) echo "Usage: $0 {start|stop|status|restart|force-reload}" >&2 exit 3 ;; esac exit 0 debian/grub-pc-bin.install.linux-i386.in0000664000000000000000000000004612524662415015126 0ustar usr/lib/grub/@CPU_PLATFORM@/efiemu*.o debian/grub-theme-starfield.install0000664000000000000000000000004012524662415014573 0ustar usr/share/grub/themes/starfield debian/grub-common.examples0000664000000000000000000000001612524662415013161 0ustar docs/grub.cfg debian/changelog0000664000000000000000000050742112634017624011060 0ustar grub2 (2.02~beta2-9ubuntu1.6) trusty-security; urgency=medium * SECURITY UPDATE: password bypass via backspace key buffer overflow - debian/patches/CVE-2015-8370.patch: check length before accepting a backspace character in grub-core/lib/crypto.c, grub-core/normal/auth.c. - CVE-2015-8370 -- Marc Deslauriers Tue, 15 Dec 2015 09:11:24 -0500 grub2 (2.02~beta2-9ubuntu1.5) trusty; urgency=medium * d/p/arm64-set-correct-length-of-device-path-end-entry.patch: Fixes booting arm64 kernels on certain UEFI implementations. (LP: #1476882) * progress: avoid NULL dereference for net files. (LP: #1459872) * arm64/setjmp: Add missing license macro. (LP: #1459871) * Cherry-pick patch to add SAS disks to the device list from the ofdisk module. (LP: #1517586) * Cherry-pick patch to open Simple Network Protocol exclusively. (LP: #1508893) -- dann frazier Wed, 25 Nov 2015 13:13:35 -0700 grub2 (2.02~beta2-9ubuntu1.4) trusty; urgency=medium * Fix overlap check in check_blocklists for load_env (backported patch from upstream commit 1f6af2a9). (LP: #1311247) -- Mathieu Trudel-Lapierre Wed, 23 Sep 2015 21:29:20 -0400 grub2 (2.02~beta2-9ubuntu1.3) trusty; urgency=medium * Do not hang headless servers indefinitely on boot after edge case power failure timing (LP: #1443735). Instead, time out after 30 seconds and boot anyway, including on non-headless systems. -- Robie Basak Tue, 19 May 2015 13:31:03 +0100 grub2 (2.02~beta2-9ubuntu1.2) trusty-proposed; urgency=medium * debian/patches/install_powerpc_machtypes.patch: updated: do a better job at detecting machine types; so as to use the right utility when updating nvram for the boot-device. This also fixes adding a CHRP note on the chrp_ibm machines, which broke PowerVM mode. (LP: #1334793) * debian/patches/ppc64el-disable-vsx.patch: disable the VSX instruction, which is enabled by default on POWER7/8 cpu models, to avoid crashes due to instruction exceptions. The kernel will re-enable it when necessary. (LP: #1454743) * debian/patches/ieee1275-clear-reset.patch: clear the text attribute in the clear command. (LP: #1454764) -- Mathieu Trudel-Lapierre Wed, 13 May 2015 12:30:05 -0400 grub2 (2.02~beta2-9ubuntu1.1) trusty-proposed; urgency=medium * Add dependency on efibootmgr to grub-efi-arm64-bin (LP: #1435663). -- dann frazier Mon, 06 Apr 2015 22:31:19 -0600 grub2 (2.02~beta2-9ubuntu1) trusty; urgency=medium * Backport patches from upstream to make the network stack more responsive on busy networks (LP: #1314134). * Add support for nvme device in grub-mkdevicemap (thanks, Dimitri John Ledkov; closes: #746396, LP: #1275162). -- Colin Watson Thu, 08 May 2014 13:09:46 +0100 grub2 (2.02~beta2-9) unstable; urgency=medium * Backport from upstream: - Tolerate devices with no filesystem UUID returned by os-prober (LP: #1287436). -- Colin Watson Thu, 10 Apr 2014 17:34:44 +0100 grub2 (2.02~beta2-8) unstable; urgency=medium [ Colin Watson ] * Backport from upstream: - ieee1275: check for IBM pseries emulated machine. - Fix partmap, cryptodisk, and abstraction handling in grub-mkconfig (closes: #735935). - btrfs: fix get_root key comparison failures due to endianness. * Build-depend on automake (>= 1.10.1) to ensure that it meets configure's requirements (LP: #1299041). * When installing an image for use with UEFI Secure Boot, generate a load.cfg even if there are no device abstractions in use (LP: #1298399). [ Jon Severinsson ] * Add Tanglu support, as in Debian except: - Enable splash screen by default (as Ubuntu) - Enable quiet and quick boot (as Ubuntu) - Enable the grub-common init script (as Ubuntu) - Enable dynamic gfxpayload (as Ubuntu) - Enable vt handover (as Ubuntu) - Use monochromatic theme by default (as Ubuntu) - Use Tanglu GRUB wallpaper by default. -- Colin Watson Mon, 31 Mar 2014 16:30:37 +0100 grub2 (2.02~beta2-7) experimental; urgency=medium * Fix shift-held-down test not to clear other modifier key states (LP: #843804). * Explicitly pass an appropriate --target to grub-install in the postinst (suggested by Jordan Uggla). * Backport from upstream: - Use bootaa64.efi instead of bootaarch64.efi on arm64 to comply with EFI specification. Also use grubaa64.efi for consistency. -- Colin Watson Mon, 10 Mar 2014 13:39:33 +0000 grub2 (2.02~beta2-6) experimental; urgency=medium * Install bootinfo.txt and grub.chrp into grub-ieee1275-bin on powerpc and ppc64el. * Port yaboot logic to improve installation for various powerpc machine types. * Improve parsing of /etc/default/grub.d/*.cfg in C utilities (LP: #1273694). * Run grub-install on install or upgrade on grub-ieee1275/ppc64el. -- Colin Watson Tue, 28 Jan 2014 23:50:55 +0000 grub2 (2.02~beta2-5) experimental; urgency=medium * Add a number of EFI debugging commands to the signed image (lsefi, lsefimmap, lsefisystab, lssal). * Add gfxterm_background to the signed image so that background_image works in UEFI Secure Boot mode. Thanks to syscon-hh for the report. -- Colin Watson Mon, 27 Jan 2014 10:03:00 +0000 grub2 (2.02~beta2-4) experimental; urgency=medium * Remove redundant build-dependencies on autoconf and automake, covered by dh-autoreconf. * In --enable-quick-boot mode, restore previous behaviour of using a hidden timeout if GRUB_HIDDEN_TIMEOUT=0 (thanks to Sebastien Bacher for the report). * Disable cpio test on kFreeBSD again for now; it fails within cpio itself with "field width not sufficient for storing rdev minor". * Copy shim.efi.signed to the correct path in UEFI Secure Boot mode. Thanks to syscon-hh for the report. -- Colin Watson Mon, 20 Jan 2014 15:53:36 +0000 grub2 (2.02~beta2-3) experimental; urgency=medium * Pass VERBOSE=1 when running tests so that Automake will print test logs on failure. * Adjust Vcs-* fields to indicate the experimental branch. * Build-depend on cpio on architectures where we run the test suite, for tests/cpio_test.in. * Ignore EPERM when modifying kern.geom.debugflags on FreeBSD, fixing tests. -- Colin Watson Fri, 17 Jan 2014 10:50:40 +0000 grub2 (2.02~beta2-2) experimental; urgency=medium * Convert patch handling to git-dpm. * Add bi-endian support to ELF parser (Tomohiro B Berry). * Adjust restore_mkdevicemap.patch to mark get_kfreebsd_version as static, to appease "gcc -Werror=missing-prototypes". * Cherry-pick from upstream: - Change grub-macbless' manual page section to 8. * Install grub-glue-efi, grub-macbless, grub-render-label, and grub-syslinux2cfg. * grub-shell: Pass -no-pad to xorriso when building floppy images. -- Colin Watson Thu, 16 Jan 2014 15:18:04 +0000 grub2 (2.02~beta2-1) experimental; urgency=low * New upstream beta release. * Drop qemu-utils build-dependency; the test suite no longer uses qemu-img. * Build grub-common, grub2-common, grub-themes-starfield, and grub-mount on ARM and ARM64 architectures. * Install grub-mkrescue in grub-common on all architectures. * Make grub-efi-ia32, grub-efi-amd64, and grub-efi-ia64 conflict with elilo. * Adjust the postinst of grub-efi-ia64, grub-efi-arm, and grub-efi-arm64 to keep the EFI System Partition up to date with grub-install after it has been run once, like grub-efi-ia32 and grub-efi-amd64 already do. * Regularise indentation of "recordfail" in /etc/grub.d/10_linux. * Add alpha.gnu.org to debian/watch, for pre-releases. * Add OpenPGP signature checking configuration to watch file. * Drop mkconfig_skip_dmcrypt.patch; it breaks GRUB_ENABLE_CRYPTODISK=y, which is a better fix for the original problem (closes: #732245). * Fix mismerge of mkconfig_loopback.patch. * Build for ppc64el, using a powerpc cross-compiler at least for now. * Don't run gettext_strings_test; this test is mainly useful as an upstream maintenance check. * Silence warning if /usr/share/locale-langpack does not exist (closes: #732595). * Remove debian/grub-common.preinst, superseded by .maintscript files. * Install grub-file in grub-common. * Fix crash due to pointer confusion in grub-mkdevicemap, introduced while converting away from nested functions in 2.00+20131208-1. -- Colin Watson Thu, 26 Dec 2013 00:52:47 +0000 grub2 (2.00+20131208-1) experimental; urgency=low * New upstream snapshot. - Skip issuing cursor on/off sequences on Macs (closes: #683068). - Move grub-mknetdir to /usr/bin (closes: #688799). - Apply program name transformations at build-time rather than at run-time (closes: #696465). - Add info documentation for grub-mount (closes: #666427). - Clean up dangling references to grub-setup (LP: #1082045). - Avoid installing to sectors matching the signature of an Acer registration utility with several sightings in the wild (LP: #987022). - Document the need for GRUB_DEFAULT=saved in grub-set-default(8) (LP: #1102925). - Fix missing PVs if they don't contain an "interesting" LV (probably closes: #650724, #707613). - Reimplement grub-reboot to not depend on saved_entry (closes: #707695, LP: #704406). - Fix Ctrl-u handling to copy the killed characters to the kill buffer as UCS4 stored as grub_uint32_t rather than as 8-bit characters stored as char (closes: #710076). - Fix inconsistent use of GRUB_CRYPTODISK_ENABLE and GRUB_ENABLE_CRYPTODISK (LP: #1232237). - Support GRUB_DISABLE_SUBMENU configuration, and document submenu usage in grub-reboot(8) (closes: #690538). - Don't decompress initrd when booting with Xen (closes: #700197). - Document how to delete the whole environment block (closes: #726265). - Revamp hidden timeout handling by adding a new timeout_style environment variable and a corresponding GRUB_TIMEOUT_STYLE configuration key for grub-mkconfig. This controls hidden-timeout handling more simply than the previous arrangements, and pressing any hotkeys associated with menu entries during the hidden timeout will now boot the corresponding menu entry immediately (LP: #1178618). As part of merging this, radically simplify the mess that quick_boot.patch had made of /etc/grub.d/30_os-prober; if it finds other OSes it can now just set timeout_style=menu and make sure the timeout is non-zero. - On Linux, read partition start offsets from sysfs if possible (LP: #1237519). - New ports to arm-uboot, arm-efi, arm64-efi, i386-xen, and x86_64-xen. * Add grub-uboot*, grub-efi-arm*, and grub-xen* binary packages. * Ignore functional test failures for now as they are broken. * Move working directories around (build/ -> obj/, build/stamps -> debian/stamps) so that "debian/rules build" still works after working directories have been created. * Drop "grub-mkrescue --diet" option; never merged upstream and only matters for floppies. Please let me know if you were using this. Explicitly use -no-pad to build grub-rescue-floppy.img, which has an equivalent effect on size. * Break lupin-support (<< 0.55) due to the rewrite of grub-install in C. * Remove build-dependency on autogen, no longer needed. * Compress GRUB files on grub-rescue-floppy.img using xz. * Build-depend on wamerican, newly required by the test suite. * Run tests with LC_CTYPE=C.UTF-8, so that grub-fs-tester can handle UTF-8 data correctly. * Update debian/legacy/update-grub to the version from grub 0.97-67. * Silence error message on initial installation when /etc/default/grub does not yet exist. * Add GRUB_RECOVERY_TITLE option, to allow the controversial "recovery mode" text to be customised (LP: #1240360). -- Colin Watson Mon, 09 Dec 2013 00:21:45 +0000 grub2 (2.00-20) unstable; urgency=low * Backport from upstream: - Sort gnumach kernels in version order (closes: #725451). * Move packaging to git, following upstream. Adjust Vcs-* fields. * Remove obsolete DM-Upload-Allowed field. * Merge (completely!) from Ubuntu: - Handle probing striped DM-RAID devices (thanks, Robert Collins; LP: #803658). - Unconditionally create grub.cfg on our EFI boot partition in Secure Boot mode; GRUB always needs some configuration in this case to find /boot/grub, since we can't modify the signed image at install time (Steve Langasek, LP: #1236625). - If MokManager is present on the host system, copy it onto the EFI boot partition for use (Steve Langasek). - Adjust UEFI installation to cope with Kubuntu setting GRUB_DISTRIBUTOR (LP: #1242417). - If building for Ubuntu: + Bypass menu unless other OSes are installed or Shift is pressed. + Show the boot menu if the previous boot failed. + Set GRUB_GFXPAYLOAD_LINUX=keep unless it's known to be unsupported on the current hardware. + Set vt.handoff=7 for smooth handoff to kernel graphical mode. + In recovery mode, add nomodeset to the Linux kernel arguments, and remove the 'set gfxpayload=keep' command. + Set default timeout to 10 seconds. + Enable hidden timeout support by default. - Migrate timeout settings from menu.lst. - Probe FusionIO devices (LP: #1237519). * Make grub.cfg world-unreadable if even hashed passwords are in use (closes: #632598). -- Colin Watson Thu, 14 Nov 2013 10:49:31 +0000 grub2 (2.00-19) unstable; urgency=low [ Colin Watson ] * Merge from Ubuntu: - debian/build-efi-images: Where possible, make use of the device path derived from the EFI Loaded Image Protocol to compute the prefix (LP: #1097570). - debian/build-efi-images: Add a netboot image target to our set of prebuilt EFI images (thanks, Steve Langasek). * Backport from upstream: - Handle partitions on non-512B EFI disks (LP: #1065281). [ Phillip Susi ] * restore_mkdevicemap.patch: Fix dmraid uuid check to look for "DMRAID-" anywhere instead of only at the start, since kpartx prefixes it with "partN-" (LP: #1183915). -- Colin Watson Wed, 18 Sep 2013 17:18:27 +0100 grub2 (2.00-18) unstable; urgency=low * Add gettext module to signed UEFI images (LP: #1104627). * Put the preprocessor definition for quiet-boot in the right place so that it actually takes effect. -- Colin Watson Mon, 26 Aug 2013 17:23:09 +0100 grub2 (2.00-17) unstable; urgency=low * Really include patches to reduce visual clutter in normal mode when building for Ubuntu. -- Colin Watson Thu, 15 Aug 2013 09:58:59 +0100 grub2 (2.00-16) unstable; urgency=low * Make reportbug script file robust against su authentication failures and missing LVM commands. * Backport from upstream: - Move @itemize after @subsection to satisfy texinfo-5.1. - grub-mkconfig: Fix detection of Emacs autosave files. - Fix spurious failure on Xen partition devices without disk devices (closes: #708614). * Merge from Ubuntu: - Treat Kubuntu as an alias for Ubuntu in GRUB_DISTRIBUTOR (Harald Sitter). - Make any EFI system boot into the shim (if installed) even if SecureBoot is disabled (Stéphane Graber). - Allow Shift to interrupt 'sleep --interruptible'. - If building for Ubuntu: + Reduce visual clutter in normal mode. + Remove verbose messages printed before reading configuration. + Suppress kernel/initrd progress messages, except in recovery mode. + Suppress "GRUB loading" message unless Shift is held down. - Skip Windows os-prober entries on Wubi systems. * Consolidate debian/rules logic for when to build signed images. -- Colin Watson Thu, 15 Aug 2013 08:35:53 +0100 grub2 (2.00-15) unstable; urgency=low [ Colin Watson ] * Install reportbug presubj and script files in all binary packages. * Make grub-yeeloong.postinst explicitly install with --target=mipsel-loongson (closes: #708204). * Make grub-script-check fail on scripts containing no commands (closes: #713886). * Make the description of grub-firmware-qemu a little more generic, rather than assuming that bochsbios provides qemu's default BIOS image (closes: #714277). * Don't assume that the presence of /etc/default/grub or /etc/default/grub.d/*.cfg means that any particular item is set in it (LP: #1199731). [ Debconf translations ] * Hungarian (Dr. Nagy Elemér Károly). -- Colin Watson Sat, 13 Jul 2013 11:04:15 +0100 grub2 (2.00-14) unstable; urgency=low * Merge from Ubuntu: - Don't call update-grub in the zz-update-grub kernel hook if /boot/grub/grub.cfg doesn't exist. - acpihalt: expand parser to handle SSDTs and some more opcodes. Fixes test suite hang with current seabios. * Remove kernel-specific grub.d conffiles that were dropped from packages built for all but their corresponding kernel type in 1.96+20090307-1 (closes: #703539). * Look for grub-bios-setup in /usr/lib/grub/i386-pc/ as well (closes: #705636). * Merge 1.99-27.1 (thanks, Steve McIntyre): - Add entries for Windows Boot Manager found via UEFI in os-prober (closes: #698914). -- Colin Watson Thu, 09 May 2013 00:14:55 +0100 grub2 (2.00-13) experimental; urgency=low * Backport from upstream: - Fix booting FreeBSD >= 9.1 amd64 kernels (closes: #699002). * Merge from Ubuntu: - Stop using the /usr/share/images/desktop-base/desktop-grub.png alternative as the fallback background if GRUB_DISTRIBUTOR is "Ubuntu". - source_grub2.py: Use attach_default_grub from apport's hookutils. - Output a menu entry for firmware setup on UEFI FastBoot systems. - Set a monochromatic theme and an appropriate background for Ubuntu. - Remove "GNU/Linux" from default distributor string for Ubuntu. - Apply Ubuntu GRUB Legacy changes to legacy update-grub script. - Apply patch from Fedora to add a "linuxefi" loader which boots kernels with EFI handover patches, avoiding ExitBootServices. - Temporarily make linuxefi refuse to validate kernels in the absence of a shim, until we get some other details worked out. - Automatically call linuxefi from linux if secure boot is enabled and the kernel is signed, to hand over to the kernel without calling ExitBootServices. Otherwise, linux will fall through to previous code, call ExitBootServices itself, and boot the kernel normally. - Generate configuration for signed UEFI kernels if available. - On Ubuntu amd64, add a raw-uefi custom upload tarball for signing. - Install signed images if available and UEFI Secure Boot is enabled. - Add "splash" to default boot options on Ubuntu. -- Colin Watson Fri, 01 Feb 2013 15:44:25 +0000 grub2 (2.00-12) experimental; urgency=low * Silence output from running-in-container. * Also skip update-grub when running in a container (LP: #1060404). -- Colin Watson Thu, 24 Jan 2013 23:21:48 +0000 grub2 (2.00-11) experimental; urgency=low [ Adam Conrad ] * debian/{postinst,config}.in: Don't fail if /etc/default/grub.d configuration snippets exist, but /etc/default/grub does not. [ Colin Watson ] * Merge wheezy branch up to 1.99-27, fixing overzealous removal of load_video call when GRUB_GFXPAYLOAD_LINUX is empty (closes: #661789). * Merge from Ubuntu: - If the postinst is running in a container, skip grub-install and all its associated questions (LP: #1060404). - Fix backslash-escaping in merge_debconf_into_conf (LP: #448413). Note that this differs slightly from the fix in Ubuntu, which corrected behaviour when amending an existing configuration item but accidentally over-escaped when adding a new one. - Replace "single" with "recovery" when friendly-recovery is installed (LP: #575469). - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate Ubuntu's backport of the grub-doc split (LP: #493968). -- Colin Watson Mon, 21 Jan 2013 10:49:00 +0000 grub2 (2.00-10) experimental; urgency=low * Support parallel builds. * Remove /boot/grub/unicode.pf2 on purge of grub-efi-{amd64,i386} (closes: #697183). * Build with GCC 4.7. * Merge from Ubuntu: - Don't permit loading modules on UEFI Secure Boot (since in such a setup the GRUB core image must be signed but it has no provision for verifying module signatures). - Read /etc/default/grub.d/*.cfg after /etc/default/grub (LP: #901600). - Blacklist 1440x900x32 from VBE preferred mode handling until a better solution is available (LP: #701111). -- Colin Watson Thu, 03 Jan 2013 09:38:25 +0000 grub2 (2.00-9) experimental; urgency=low * Ensure /boot/grub exists before copying files to it for EFI installs (closes: #696962). -- Colin Watson Sat, 29 Dec 2012 23:44:51 +0000 grub2 (2.00-8) experimental; urgency=low * debian/apport/source_grub2.py: - Use context managers to avoid (harmless) file descriptor leaks. - Set a file encoding, per PEP 0263. * Drop grub-ieee1275-bin's dependency on bc in favour of powerpc-ibm-utils (>= 1.2.12-1) (cf. #625728). * Move powerpc-ibm-utils and powerpc-utils dependencies from grub-ieee1275-bin to grub-ieee1275 (closes: #693400). * Merge from Ubuntu: - Ignore symlink traversal failures in grub-mount readdir (LP: #1051306). - Fix incorrect initrd minimum address calculation (LP: #1055686). - Avoid assuming that gets is declared. * Copy unicode.pf2 to /boot/grub/ for EFI installs so that it is more likely to be readable by GRUB (closes: #661789). -- Colin Watson Fri, 28 Dec 2012 17:34:32 +0000 grub2 (2.00-7) experimental; urgency=low * Backport from upstream: - Fix stderr leakage from grub-probe in is_path_readable_by_grub. - Fix tftp endianness problem. * Merge from Ubuntu: - Prefer translations from language packs (LP: #537998). (No-op for Debian, but harmless.) - Avoid getting confused by inaccessible loop device backing paths (LP: #938724). -- Colin Watson Wed, 26 Sep 2012 16:05:07 +0100 grub2 (2.00-6) experimental; urgency=low [ Colin Watson ] * Adjust package descriptions to talk about update-grub, not update-grub2. * Backport from upstream: - Fix grub-emu build on FreeBSD. * Revert gcc-4.6-multilib build-dependency change from 2.00-1, since kfreebsd-i386 and hurd-i386 don't have gcc-4.6-multilib. Instead, make sure to only install efiemu32.o and efiemu64.o on (linux-)i386, kopensolaris-i386, and any-amd64. * Manually expand @PACKAGE@ symbols in grub-efi.postinst (closes: #688725), grub-linuxbios.postinst (closes: #688726), and grub2.postinst (closes: #688724). [ Debconf translations ] * Lithuanian (Rimas Kudelis). Closes: #675628 * Galician (Jorge Barreiro). Closes: #677389 * Welsh (Daffyd Tomos). * Greek (galaxico). Closes: #685201 * Romanian (Andrei POPESCU). Closes: #685477 * Finnish (Timo Jyrinki). [ Cyril Brulebois ] * Use xz compression for all binaries to save up some space on CD images (closes: #688773). -- Colin Watson Tue, 25 Sep 2012 22:47:03 +0100 grub2 (2.00-5) experimental; urgency=low * Backport from upstream: - Remove extra layer of escaping from grub_probe. - Add efifwsetup module to reboot into firmware setup menu. - Revert incorrect off-by-one fix when embedding in MBR (LP: #1051154). * Switch watch file to point to ftp.gnu.org. * Build-depend on liblzma-dev, enabling 'grub-mkimage -C xz'. * Adjust /etc/grub.d/30_os-prober to detect Ubuntu's use of "recovery" rather than "single". -- Colin Watson Wed, 19 Sep 2012 08:52:27 +0100 grub2 (2.00-4) experimental; urgency=low * Fix platform postinsts to handle new core.img location. * Only fix up powerpc key repeat on IEEE1275 machines. Fixes powerpc-emu compilation. * Move grub-install to grub2-common, since it's now common across platforms but clashes with grub-legacy. * Move grub-mknetdir to grub-common, since it's now common across platforms. * Make grub-install fall back to i386-pc if booted using EFI but the relevant *-efi target is not available (because only grub-pc is installed). -- Colin Watson Fri, 14 Sep 2012 13:38:37 +0100 grub2 (2.00-3) experimental; urgency=low * Use dh-autoreconf. * Bail out if trying to run grub-mkconfig during upgrade to 2.00 (e.g. while configuring a kernel image), since the old /etc/grub.d/00_header conffile breaks until such time as grub-common is configured. -- Colin Watson Thu, 13 Sep 2012 17:07:18 +0100 grub2 (2.00-2) experimental; urgency=low * Add -Wno-error=unused-result to HOST_CFLAGS for the moment, since at least grub-core/lib/crypto.c fails to compile on Ubuntu otherwise. * Update default/grub.md5sum to include Ubuntu maverick's default md5sum. * Autogenerate packaging files for grub-emu, in order that its postinst does not contain unexpanded @PACKAGE@ symbols. * Only try to install efiemu*.o into grub-emu on *-i386. -- Colin Watson Sat, 08 Sep 2012 10:32:33 +0100 grub2 (2.00-1) experimental; urgency=low [ Jordi Mallach, Colin Watson ] * New upstream release. - Add LUKS and GELI encrypted disk support (closes: #463107). - Lazy scanning to avoid accessing devices which aren't really used. This avoids boot delay due to slow device scanning (closes: #549905, #550015, #550083, #564252, #595059, #632408). - Don't override more informative errors when loading kernel/initrd (closes: #551630). - Support 4K-sector NTFS (closes: #567728). - Unify grub-mkrescue interface on powerpc with that on other architectures (closes: #570119). - Fix infinite recursion in gettext when translation fails (closes: #611537, #612454, #616487, #619618, #626853, #643608). - Add more missing quotes to grub-mkconfig (closes: #612417). - Import gnulib change to fix argp_help segfault with help filter (closes: #612692). - Support %1$d syntax in grub_printf (closes: #630647). - Use write-combining MTRR to speed up video with buggy BIOSes (closes: #630926). - Remove multiboot header from PXE images to avoid confusing ipxe (closes: #635877). - Fix crash when attempting to install to a non-BIOS disk (closes: #637208). - Fix handling of grub-mkrescue --xorriso= option (closes: #646788). - Use umask rather than chmod to create grub.cfg.new to avoid insecure grub.cfg (closes: #654599). - Improve font installation logic (closes: #654645). - Add grub-probe info documentation (closes: #666031). - Don't crash on canonicalize_file_name failure in grub-probe (closes: #677211). [ Colin Watson ] * Adjust debian/watch to point to xz-compressed tarballs. * debian/grub.d/05_debian_theme: Source grub-mkconfig_lib from /usr/share/grub, not the /usr/lib/grub compatibility link. * Convert to source format 3.0 (quilt). Developers, note that patches are stored applied in bzr; you may want to 'quilt pop -a' / 'quilt push -a' around merges. * Remove pointless debian/grub-mount-udeb.install.hurd-i386; grub-mount-udeb is not built on the Hurd. * Refactor debian/grub-common.install.hurd-i386 into .in files so that it imposes less of a maintenance burden. * Restore grub-mkdevicemap for now. While it's kind of a mess, requiring lots of OS-specific code to iterate over all possible devices, we use it in a number of scripts to discover devices and reimplementing those in terms of something else would be very complicated. * Add grub-efi-ia64-bin and grub-efi-ia64 packages. These are currently experimental, and grub-efi-ia64 does not automatically run grub-install. * Build-depend on gcc-4.6-multilib on kfreebsd-i386 and hurd-i386 as well as the other i386 architectures, since we need it to build efiemu32.o and efiemu64.o. * Add per-platform *-dbg packages containing files needed to use GRUB's GDB stub. These are relatively large and thus worth splitting out. * Build-depend on ttf-dejavu-core for the starfield theme. * Add a grub-theme-starfield package containing the starfield theme. * Backport from upstream: - Don't decrease efi_mmap_size (LP: #1046429). * grub-common Suggests: console-setup for grub-kbdcomp (closes: #686815). * Silence error messages when translations are unavailable. * Don't pass *.module to dpkg-shlibdeps, avoiding lots of build-time warnings. * Move transitional package to Section: oldlibs. * Acknowledge NMU (closes: #676609). [ Debconf translations ] * Lithuanian (Rimas Kudelis). Closes: #675628 * Galician (Jorge Barreiro). Closes: #677389 * Welsh (Daffyd Tomos). * Greek (galaxico). Closes: #685201 * Romanian (Andrei POPESCU). Closes: #685477 * Finnish (Timo Jyrinki). -- Colin Watson Thu, 06 Sep 2012 19:04:21 +0100 grub2 (1.99-27.1) unstable; urgency=medium * NMU * Add entries for Windows Boot Manager found via UEFI in os-prober. Closes: #698914 before the Wheezy release. -- Steve McIntyre <93sam@debian.org> Fri, 26 Apr 2013 23:53:34 +0100 grub2 (1.99-27) unstable; urgency=low * Amend gfxpayload_keep_default.patch to no longer remove the call to load_video when GRUB_GFXPAYLOAD_LINUX is empty (closes: #661789). -- Colin Watson Sun, 20 Jan 2013 16:37:52 +0000 grub2 (1.99-26) unstable; urgency=low * Remove /boot/grub/unicode.pf2 on purge of grub-efi-{amd64,i386} (closes: #697183). -- Colin Watson Wed, 02 Jan 2013 11:54:50 +0000 grub2 (1.99-25) unstable; urgency=low * Ensure /boot/grub exists before copying files to it for EFI installs (closes: #696962). -- Colin Watson Sat, 29 Dec 2012 23:45:01 +0000 grub2 (1.99-24) unstable; urgency=low * Acknowledge NMU with thanks. * Fix namespace of EFI boot failure patch file added in NMU. * Copy unicode.pf2 to /boot/grub/ for EFI installs so that it is more likely to be readable by GRUB (closes: #661789). * Fix infinite recursion in gettext when translation fails (closes: #611537, #612454, #616487, #619618, #626853, #643608). * Fix grammar in Finnish translation (closes: #687681). -- Colin Watson Fri, 28 Dec 2012 13:01:38 +0000 grub2 (1.99-23.1) unstable; urgency=low * Non-maintainer upload. * Apply Ubuntu patch fixing some EFI boot failures (closes: #687320) - Thanks to Colin Watson. -- Michael Gilbert Sun, 14 Oct 2012 04:09:51 -0400 grub2 (1.99-23) unstable; urgency=low [ Debconf translations ] * Lithuanian (Rimas Kudelis). Closes: #675628 * Galician (Jorge Barreiro). Closes: #677389 * Welsh (Daffyd Tomos). * Greek (galaxico). Closes: #685201 * Romanian (Andrei POPESCU). Closes: #685477 * Finnish (Timo Jyrinki). [ Cyril Brulebois ] * Use xz compression for all binaries to save up some space on CD images (closes: #688773). [ Colin Watson ] * Autogenerate packaging files for grub-emu (closes: #688727), in order that its postinst does not contain unexpanded @PACKAGE@ symbols. * Manually expand @PACKAGE@ symbols in grub-efi.postinst (closes: #688725), grub-linuxbios.postinst (closes: #688726), and grub2.postinst (closes: #688724). -- Colin Watson Tue, 25 Sep 2012 18:59:18 +0100 grub2 (1.99-22.1) unstable; urgency=low * Non-maintainer upload. * Apply upstream patches for hurd-i386: - Test inode number (Closes: #634799). - Disable zfs code on GNU/Hurd (Closes: #670069). - Add userland partition support (Closes: #670186). * Fix packages build without libfuse (Closes: #670189). -- Samuel Thibault Fri, 08 Jun 2012 01:19:00 +0200 grub2 (1.99-22) unstable; urgency=low [ Debconf translations ] * Khmer added (Khoem Sokhem) * Slovenian (Vanja Cvelbar). Closes: #670616 * Traditional Chinese (Vincent Chen). * Vietnamese (Hai Lang). * Marathi (Sampada Nakhare) * Finnish (Timo Jyrinki). Closes: #673976 * Latvian (Rūdolfs Mazurs). Closes: #674697 [ Colin Watson ] * Make apport hook compatible with Python 3. * Add upstream r3476 (fix memory leak in grub_disk_read_small) to 4k_sectors.patch, otherwise the larger disk cache due to efi_disk_cache.patch can cause EFI systems to run out of memory. -- Colin Watson Wed, 30 May 2012 10:38:40 +0100 grub2 (1.99-21) unstable; urgency=low * Backport from upstream: - Fix hook calling for unaligned segments (closes: #666992, LP: #972250). -- Colin Watson Tue, 03 Apr 2012 14:19:18 +0100 grub2 (1.99-20) unstable; urgency=low * Backport kFreeBSD support from upstream to 4k_sectors.patch. -- Colin Watson Mon, 02 Apr 2012 21:53:02 +0100 grub2 (1.99-19) unstable; urgency=low [ Colin Watson ] * Add grub-probe to grub-mount-udeb (LP: #963471). * Backport from upstream: - Restore CFLAGS after efiemu check (closes: #665772). - Include __ctzdi2 and __ctzsi2 from libgcc if present (closes: #665993). - Support non-512B sectors and agglomerate reads. [ Debconf translations ] * Croatian (Tomislav Krznar). -- Colin Watson Mon, 02 Apr 2012 18:26:09 +0100 grub2 (1.99-18) unstable; urgency=low [ Colin Watson ] * Ensure that /sbin and /usr/sbin are in $PATH when running tests (closes: #662916). * mkconfig_loopback.patch: Use different GRUB loop devices for different OS loop devices (thanks, bcbc; LP: #888281). * Backport from upstream: - Add support for LZO compression in btrfs (LP: #727535). - Fix efiemu configure check. [ Ilya Yanok ] * Backport from upstream: - Make FAT UUID uppercase to match Linux (LP: #948716). [ Debconf translations ] * Norwegian Bokmål (Hans Fredrik Nordhaug). * Gujarati (Kartik Mistry). Closes: #663542 -- Colin Watson Mon, 19 Mar 2012 18:24:33 +0000 grub2 (1.99-17) unstable; urgency=low * efi_disk_cache.patch: Fix incorrect GRUB_DISK_CACHE_BITS (LP: #944347). -- Colin Watson Tue, 06 Mar 2012 17:43:42 +0000 grub2 (1.99-16) unstable; urgency=low * Backport from upstream: - Build with -fno-asynchronous-unwind-tables to save space (closes: #662787). -- Colin Watson Tue, 06 Mar 2012 12:45:42 +0000 grub2 (1.99-15) unstable; urgency=low [ Adam Conrad ] * grub.cfg_400.patch: Redirect grep stdout to /dev/null since grub-mkconfig is "exec > grub.cfg.new", which causes grep's input and output to be the same FD (LP: #934269) (closes: #652972) * efi_disk_cache.patch: Bump the disk cache on EFI systems to dramatically reduce load times for vmlinux/initrd (LP: #944347) [ Colin Watson ] * no_libzfs.patch: Use xasprintf rather than asprintf. * Backport from upstream: - Rewrite XFS btree parsing; fixes invalid BMAP (closes: #657776). - Handle newer autotools, and add some missing quotes in the process. (Note that this moves grub-mkconfig_lib and update-grub_lib to /usr/share/grub; I added links in /usr/lib/grub for compatibility.) - Fix incorrect identifiers in bash-completion (closes: #661415). - Add support for GRUB_CMDLINE_GNUMACH (closes: #660493). * Build with GCC 4.6 (closes: #654727). [ Debconf translations ] * Dutch (Jeroen Schot). Closes: #651275 * Bulgarian (Damyan Ivanov). Closes: #653356 * Icelandic (Sveinn í Felli). * Ukrainian (Yatsenko Alexandr). Closes: #654294 * Italian (Luca Monducci). Closes: #654304 * Thai (Theppitak Karoonboonyanan). Closes: #656551 * Uyghur (Abduqadir Abliz) * Indonesian (Mahyuddin Susanto). Closes: #656705 * Hebrew (Omer Zak). Closes: #656852 * Turkish (Atila KOÇ). Closes: #656907 * Polish (Michał Kułach). Closes: #657265 * Asturian (Mikel González). * Dzongkha (Dawa Pemo) * Tamil (Dr.T.Vasudevan). * Belarusian (Viktar Siarhiejczyk). Closes: #662615 -- Colin Watson Mon, 05 Mar 2012 16:58:01 +0000 grub2 (1.99-14) unstable; urgency=low * Rewrite no_libzfs.patch using a different approach. (Closes: #648539) -- Robert Millan Sun, 13 Nov 2011 00:14:38 +0100 grub2 (1.99-13) unstable; urgency=low [ Debconf translations ] * Portuguese (Miguel Figueiredo). Closes: #641226 * German (Martin Eberhard Schauer). Closes: #641630 * Sinhala (Danishka Navin). Closes: #644080 * Uyghur (Gheyret Tohti). Closes: #627011 [ Robert Millan ] * LVM support for GNU/kFreeBSD. - kfreebsd_lvm.patch * Cherry-pick several ZFS updates from upstream Bazaar. - zfs_update.patch * Build without libzfs. -- Robert Millan Fri, 11 Nov 2011 23:04:58 +0100 grub2 (1.99-12) unstable; urgency=low [ Robert Millan ] * Fix grub-probe detection for LSI MegaRAID SAS devices on kFreeBSD. - kfreebsd_mfi_devices.patch [ Colin Watson ] * Backport from upstream: - Canonicalise the path argument to grub-probe (closes: #637768). - Skip */README* as well as README* (LP: #537123). -- Colin Watson Mon, 05 Sep 2011 15:17:20 +0100 grub2 (1.99-11) unstable; urgency=low * Backport from upstream: - Honour GRUB_CMDLINE_LINUX_XEN_REPLACE and GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT, which replace GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT (complementing the existing options which append; closes: #617538). -- Colin Watson Mon, 08 Aug 2011 17:55:21 +0100 grub2 (1.99-10) unstable; urgency=high * Mark la_array as packed. - zfs_packed_la_array.patch -- Robert Millan Sun, 07 Aug 2011 20:16:31 +0000 grub2 (1.99-9) unstable; urgency=low [ Colin Watson ] * Adjust apport hook to attach /boot/grub/device.map if it exists. * Fix regression in gfxterm background_color handling. * Improve detection of invalid shell syntax in apport hook. [ Debconf translations ] * Esperanto (Felipe E. F. de Castro). Closes: #632157 * Slovak (Slavko). [ Robert Millan ] * Enable grub-mount on kfreebsd-any. * Build grub-mount-udeb on kfreebsd-i386 and kfreebsd-amd64. -- Robert Millan Mon, 25 Jul 2011 15:36:31 +0200 grub2 (1.99-8) unstable; urgency=low [ Robert Millan ] * Avoid buggy versions of libgeom-dev (see #630107). Closes: #630197 * Fix grub-probe detection for ATA devices using `ata' driver on kFreeBSD 9. - kfreebsd-9_ada_devices.patch [ Colin Watson ] * Update ntldr-img from grub-extras: - Handle ext3 inode sizes other than 128. [ Debconf translations ] * Kazakh (Baurzhan Muftakhidinov). Closes: #630915 -- Colin Watson Tue, 21 Jun 2011 02:10:10 +0100 grub2 (1.99-7) unstable; urgency=low [ Debconf translations ] * Basque (Iñaki Larrañaga Murgoitio). Closes: #628716 * Swedish (Martin Bagge / brother). Closes: #628866 * Czech (Miroslav Kure). Closes: #628978 * Brazilian Portuguese (Flamarion Jorge). Closes: #629135 * Spanish (Francisco Javier Cuadrado). Closes: #629633 [ Colin Watson ] * Cope with btrfs / inside an encrypted block device (thanks, alexeagar; LP: #757631). * Merge from Ubuntu: - Give up scanning partitions after ten consecutive open failures (LP: #787461). -- Colin Watson Thu, 16 Jun 2011 00:13:14 +0100 grub2 (1.99-6) unstable; urgency=low [ Colin Watson ] * Update Vcs-* fields for Alioth changes. * Backport from upstream, removing the need for Breaks: udev (<< 168-1): - Don't stat devices unless we have to. [ Debconf translations ] * Catalan (Jordi Mallach). * Farsi (Behrad Eslamifar). Closes: #628648 -- Colin Watson Tue, 31 May 2011 09:20:54 +0100 grub2 (1.99-5) unstable; urgency=low [ Colin Watson ] * Change grub2/linux_cmdline and grub2/kfreebsd_cmdline descriptions to indicate that the command line is allowed to be empty, since this is a common source of confusion (thanks, Jordan Uggla). * On non-Ubuntu-derived systems, add Breaks: udev (<< 168-1) to grub-common, for the sake of (some?) users without initrds (closes: #627587). [ Debconf translations ] * French (Christian Perrier) * Russian (Yuri Kozlov). Closes: #628196 * Simplified Chinese (YunQiang Su). Closes: #628210 * Japanese (Hideki Yamane). Closes: #628382 * Danish (Joe Hansen). Closes: #628427 -- Colin Watson Sun, 29 May 2011 21:58:55 +0100 grub2 (1.99-4) unstable; urgency=low * Make grub--bin packages depend on grub-common rather than grub2-common, and add grub2-common dependencies to grub-. This ensures that grub--bin packages are coinstallable with grub-legacy, making it easier to use them as build-dependencies. * Stop trying to install the non-existent grub-ofpathname(8) on sparc for now. It will exist in the next upstream snapshot. -- Colin Watson Thu, 19 May 2011 12:38:45 +0100 grub2 (1.99-3) unstable; urgency=low * Ship grub-mkrescue on non-Linux amd64/i386 architectures. * Don't try to ship grub-mkrescue on sparc. * Drop boot_blocklist_hack.patch, fixed differently upstream some time ago by being smarter about filesystem-root-relative path conversion. -- Colin Watson Wed, 18 May 2011 14:06:51 +0100 grub2 (1.99-2) unstable; urgency=low * Include both old and new Lintian override styles for statically-linked-binary tag, since ftp-master has not yet been updated to 2.5.0~rc1. -- Colin Watson Tue, 17 May 2011 01:36:10 +0100 grub2 (1.99-1) unstable; urgency=low * New upstream release. - Ensure uniqueness of RAID array numbers even if some elements have a name (closes: #609804). - Remove unnecessary brackets from tr arguments (closes: #612564). - Add grub-mkrescue info documentation (closes: #612585). - Avoid generating invalid configuration when something that looks like a Xen hypervisor is present without any Xen kernels (closes: #612898). - Fix memory alignment when calling 'linux' multiple times on EFI (closes: #616638). - Fix grub-install on amd64 EFI systems (closes: #617388). - Automatically export pager variable (closes: #612995). - Fix parser error with "time" (closes: #612991). - Ignore case of bitmap extensions (closes: #611123). - Skip vmlinux-* on x86 platforms (closes: #536846, #546008). - Accept old-style Xen kernels (closes: #610428). - Skip damaged LVM volumes (closes: #544731). - Handle LVM mirroring (closes: #598441). - Detect spares and report them as not RAID members (closes: #611561). - Don't enable localisation unless gfxterm is available (closes: #604609). - Fix partitioned RAID support (closes: #595071, #613444). - Dynamically count the number of lines for the lower banner (closes: #606494). - Improve quoting in grub-mkconfig, to support background image file names containing spaces (closes: #612417). - Flush BIOS disk devices more accurately (closes: #623124). - Identify RAID devices by their UUID rather than by their guessed name (closes: #624232). - Add "SEE ALSO" sections to most man pages (closes: #551428). [ Christian Perrier ] * Drop extra word in French debconf translation. Thanks to David Prévôt. * Fix spelling error in French debconf translation. Thanks to David Prévôt. [ Colin Watson ] * Set PACKAGE_VERSION and PACKAGE_STRING using configure arguments rather than sedding configure.ac in debian/rules (which sometimes has annoying interactions with quilt, etc.). * Update branch_embed-sectors.patch: - Detect sector used by HighPoint RAID controller (closes: #394868). * Add debian/README.source (from quilt). * Make debian/rules more explicit about when autogen.sh is run. We need to be careful that all full builds run it, since we use GRUB extras. * Merge from Ubuntu: - Handle filesystems loop-mounted on file images. - On Wubi, don't ask for an install device, but just update wubildr using the diverted grub-install. - Add grub-mount-udeb, containing just grub-mount. This can be used by os-prober and other parts of d-i. - Artificially bump Replaces: grub-common versioning to account for grub-reboot/grub-set-default movement in Ubuntu. * Don't do a separate build pass for grub-common. It will be identical to the build for the default platform for the CPU architecture anyway, so reuse that. * Build with GCC 4.5 on all architectures. * Update Lintian overrides for changes in Lintian 2.5.0~rc1. * Invert how files are split among binary packages: rather than code in debian/rules to remove files we don't want, add dh_install configuration to declare the files we do want. This means a little more repetition for platform-specific programs, but it seems less confusing and easier to extend. * Drop versioned dependencies on base-files. GPL-3 has been there for two Debian releases now, and the dependency was never upgrade-critical anyway. * Create grub2-common package containing files that are common among GRUB platform packages but that would break GRUB Legacy, or that are too confusing when coinstalled with GRUB Legacy (closes: #564167). * Drop conflict on an ancient (pre-lenny/hardy) version of desktop-base. * Move /etc/grub.d/05_debian_theme to grub-common, to go with the other /etc/grub.d/* files. * Drop redundant Suggests: os-prober from several platform packages, as grub-common already Recommends: os-prober. * Create grub--bin packages corresponding to all grub- packages (except for grub-emu). These do not automatically install the boot loader or update grub.cfg, and they install their binaries to /usr/lib/grub/-/; this means that they can be installed in parallel, making it easier to use them to build GRUB-based disk images (e.g. d-i). The grub- packages now depend on these and include symlinks, so their behaviour will remain as before. * Make grub-emu depend on grub-common. * Make the documentation directory in most binary packages be a symlink to that in grub-common. * Drop lenny compatibility from grub2-common's dpkg/install-info dependency, since it produces a Lintian warning and using the current packaging on lenny is probably rather a stretch anyway. [ Updated translations ] * Belarusian (Viktar Siarheichyk). Closes: #606864 * Danish (Joe Hansen). Closes: #606879 * Romanian (Andrei POPESCU). Closes: #606888 * Italian (Luca Monducci). Closes: #606891 * Brazilian Portuguese (Flamarion Jorge). Closes: #610613 * Greek (Emmanuel Galatoulas). Closes: #604847 -- Colin Watson Mon, 16 May 2011 17:42:07 +0100 grub2 (1.99~rc1-13) unstable; urgency=low * Cherry-pick from upstream: - Use correct limits for mips initrd. * Run grub-install on install or upgrade of grub-yeeloong. * Update branch_fuse.patch: - Tell FUSE to run single-threaded, since GRUB code is not thread-safe (LP: #756297). -- Colin Watson Fri, 15 Apr 2011 12:11:21 +0100 grub2 (1.99~rc1-12) unstable; urgency=low * Update branch_butter.patch: - Fix filename comparison. - Take extent offset in account on uncompressed extents. - Use filled extent size if available. * Allow use of first sector on btrfs (LP: #757446). * Merge from Ubuntu: - Build part_msdos and vfat into EFI boot images (LP: #677758). -- Colin Watson Mon, 11 Apr 2011 16:22:08 +0100 grub2 (1.99~rc1-11) unstable; urgency=low * Update branch_fuse.patch: - Make grub-mount exit non-zero if opening the device or filesystem fails. - Translate GRUB error codes into OS error codes for FUSE (LP: #756456). * Merge from Ubuntu: - Fix use of freed memory when replacing existing loopback device (LP: #742967). -- Colin Watson Sun, 10 Apr 2011 21:52:26 +0100 grub2 (1.99~rc1-10) unstable; urgency=low * Update branch_butter.patch, fixing RAID1/duplicated chunk size calculation (thanks, Vladimir Serbinenko; LP: #732149). -- Colin Watson Sat, 09 Apr 2011 21:22:15 +0100 grub2 (1.99~rc1-9) unstable; urgency=low * Update branch_parse-color.patch, to blend text when any background is set as opposed to only when a stretched background is set (closes: #613120). * Make update-grub2 a symlink to update-grub, rather than bothering with a wrapper script. * Cherry-pick from upstream: - Check RAID superblock offset (closes: #610184). - Flush buffer cache on close and not on open (closes: #620663). - Handle special naming of yeeloong directory (closes: #620420). * Add grub-mount utility, from the upstream 'fuse' branch. * efibootmgr is only available on Linux architectures, so only make grub-efi-ia32 and grub-efi-amd64 depend on it on Linux. -- Colin Watson Sat, 09 Apr 2011 03:39:56 +0100 grub2 (1.99~rc1-8) unstable; urgency=low * Cherry-pick from upstream: - Fix FreeBSD compilation problem. -- Colin Watson Tue, 29 Mar 2011 15:13:51 +0100 grub2 (1.99~rc1-7) unstable; urgency=low * Add /proc/mdstat, LVM information, and listings of /dev/disk/by-id/ and /dev/disk/by-uuid/ to bug reports, by request of upstream. * Cherry-pick from upstream: - Use libgeom on FreeBSD to detect partitions (closes: #612128). - Copy the partition table zone if floppy support is disabled, even if no partition table is found (LP: #741867). - Fix an ext2 overflow affecting inodes past 2TiB. - Fix RAID-0 disk size calculation for metadata 1.x (LP: #743136). * Merge from Ubuntu: - Build with gcc-4.5 on ppc64. - Add apport hook for ProblemType = 'Package', thanks to Jean-Baptiste Lallement (LP: #591753). -- Colin Watson Tue, 29 Mar 2011 12:30:36 +0100 grub2 (1.99~rc1-6) unstable; urgency=low * Cherry-pick from upstream: - Fix crash when extending menu entry line beyond 79 characters (closes: #615893). - Account for FreeBSD module headers when calculating allocation size. - Switch back to framebuffer page zero before loading the kernel (thanks, Felix Kuehling). * Merge from Ubuntu: - If we're upgrading and /boot/grub/core.img doesn't exist, then don't ask where to install GRUB, since it probably means we're in some kind of specialised environment such as a live USB stick (LP: #591202). - Drop the default priority of grub2/linux_cmdline to medium. We only need to ask it if we're upgrading from GRUB Legacy and found an empty kopt in menu.lst (LP: #591202). * Update branch_embed-sectors.patch, avoiding consuming lots of space and time if the first partition is not near the start of the disk (closes: #619458, LP: #691569). -- Colin Watson Fri, 25 Mar 2011 19:23:04 +0000 grub2 (1.99~rc1-5) unstable; urgency=low * Update debian/legacy/update-grub to the version from grub 0.97-65. * Mark binary packages as Multi-Arch: foreign (for example, an amd64 kernel installed on an i386 system could use the native architecture's GRUB). * Rewrite find_root_device_from_mountinfo to cope with move-mounts (LP: #738345). [ Updated translations ] * Esperanto (Felipe Castro). Closes: #606524 * Thai (Theppitak Karoonboonyanan). Closes: #607706 -- Colin Watson Wed, 23 Mar 2011 15:51:47 +0000 grub2 (1.99~rc1-4) unstable; urgency=low * Don't touch /boot/grub/grub2-installed if using the --root-directory option to grub-install (thanks, Nicolas George; closes: #614927). * Update branch_devmapper.patch, adding partitioned MD RAID support (untested) and support for probing multipath disks. * Update ntldr-img from grub-extras: - Only call ntfs_fix_mmft if the attribute to find is AT_DATA. This matches GRUB's NTFS module. - Install grubinst as grub-ntldr-img. * Fix loading GRUB from lnxboot (LP: #693671). * Update branch_embed-sectors.patch to avoid straying into first partition when embedding-area sectors are in use (closes: #613409, LP: #730225). -- Colin Watson Tue, 15 Mar 2011 11:01:48 +0000 grub2 (1.99~rc1-3) unstable; urgency=low * Build for ppc64 (except for grub-emu, which doesn't build cleanly yet). * Suppress output from debconf-communicate in upgrade-from-grub-legacy. * Refer to the info documentation at the top of /etc/default/grub (closes: #612538). * We need at least freebsd-utils (>= 8.0-4) on kFreeBSD architectures for camcontrol, so depend on it. * Tolerate camcontrol failing to read capacity of IDE devices, until such time as we know how to do this properly (see #612128). * Adjust /etc/default/grub for rename of GRUB_DISABLE_LINUX_RECOVERY to GRUB_DISABLE_RECOVERY (closes: #612777). * Update ntldr-img from grub-extras: - Install g2hdr.bin and g2ldr.mbr (closes: #613245). -- Colin Watson Wed, 16 Feb 2011 13:11:11 +0000 grub2 (1.99~rc1-2) unstable; urgency=low * Merge 1.98+20100804-13 and 1.98+20100804-14, updating translations: - Kazakh (Baurzhan Muftakhidinov / Timur Birsh). * mkconfig_skip_dmcrypt.patch: Refer to GRUB_PRELOAD_MODULES rather than suggesting people write a /etc/grub.d/01_modules script (thanks, Jordan Uggla). * Handle empty dir passed to grub_find_root_device_from_mountinfo; fixes grub-mkrelpath on btrfs subvolumes (LP: #712029). * Add rootflags=subvol= if / is on a btrfs subvolume (LP: #712029). * Upload to unstable. -- Colin Watson Tue, 08 Feb 2011 11:39:26 +0000 grub2 (1.99~rc1-1) experimental; urgency=low [ Colin Watson ] * New upstream release candidate. [ Alexander Kurtz ] * 05_debian_theme: - If we find a background image and no colours were specified, use upstream defaults for color_normal and color_highlight rather than setting color_normal to black/black. - Make the code more readable by replacing code for handling alternatives. - Make the code for searching for pictures in /boot/grub more readable and robust (for example against newlines in the filename). - Don't try the other alternatives when $GRUB_BACKGROUND is set; you can now add GRUB_BACKGROUND= to /etc/default/grub to force no background image (closes: #608263). -- Colin Watson Mon, 17 Jan 2011 13:43:06 +0000 grub2 (1.99~20110112-1) experimental; urgency=low * New Bazaar snapshot. - Disable ieee1275_fb on sparc (closes: #560823). - Fix pf2 font generation on big-endian platforms (closes: #609818). * branch_butter.patch: Resolve the device returned by grub_find_root_device_from_mountinfo or find_root_device_from_libzfs using grub_find_device (closes: #609590, #609814, LP: #700147). -- Colin Watson Thu, 13 Jan 2011 00:12:41 +0000 grub2 (1.99~20110111-1) experimental; urgency=low * New Bazaar snapshot. - Don't check amount of low memory, as reportedly INT 12h can be broken and if low memory is too low we wouldn't have gotten into grub_machine_init anyway (closes: #588293, LP: #513528). - Submenu default support (LP: #691878). - Fix optimisation-dependent grub-mklayout crash (closes: #609584). * branch_butter.patch: Don't free an uninitialised pointer if /proc is unmounted (LP: #697493). * Add a po/LINGUAS file listing the translations we've synced from the TP (closes: #609671). -- Colin Watson Tue, 11 Jan 2011 17:11:44 +0000 grub2 (1.99~20110106-1) experimental; urgency=low * New Bazaar snapshot. - Check that named RAID array devices exist before using them (closes: #606035). - Clear terminfo output on initialisation (closes: #569678). - Fix grub-probe when btrfs is on / without a separate /boot. -- Colin Watson Thu, 06 Jan 2011 13:38:57 +0000 grub2 (1.99~20110104-2) experimental; urgency=low * Support long command lines as per the 2.06 Linux boot protocol, from the upstream 'longlinuxcmd' branch. * Add a background_color command, from the upstream 'parse-color' branch. * Update branch_devmapper.patch, adding a #include to fix a build failure on Ubuntu amd64. * When embedding the core image in a post-MBR gap, check for and avoid sectors matching any of a number of known signatures, from the upstream 'embed-sectors' branch. -- Colin Watson Wed, 05 Jan 2011 13:31:05 +0000 grub2 (1.99~20110104-1) experimental; urgency=low * New Bazaar snapshot. - Don't emit drivemap directive for Windows Server 2008 (closes: #607687). - Don't add spurious RAID array members (closes: #605357). - Improve presentation of Xen menu entries (closes: #607867). - Fix PCI probing hangs by skipping remaining functions on devices that do not implement function 0 (closes: #594967). - Fix typo in descriptions of extract_legacy_entries_source and extract_legacy_entries_configfile (LP: #696721). * Merge 1.98+20100804-12: - Use semicolons rather than commas to separate size from model in debconf disk and partition descriptions. * Add full btrfs support, from the upstream 'butter' branch. * Support partitioned loop devices and improve devmapper support, from the upstream 'devmapper' branch. * Add squashfs 4 support, from the upstream 'squash' branch. -- Colin Watson Tue, 04 Jan 2011 16:12:45 +0000 grub2 (1.99~20101221-1) experimental; urgency=low * New Bazaar snapshot. - Initialise next pointer when creating multiboot module (closes: #605567). - Fix gettext quoting to work with bash as /bin/sh, and make echo UTF-8-clean so that (at least) Catalan boot messages are displayed properly (closes: #605615). - Fix use of uninitialised memory in Reed-Solomon recovery code (LP: #686705). -- Colin Watson Tue, 21 Dec 2010 17:43:52 +0000 grub2 (1.99~20101210-2) experimental; urgency=low * Automatically remove MD devices from device.map on upgrade, since the BIOS cannot read from these and including them in device.map will break GRUB's ability to read from such devices (LP: #690030). * Merge 1.98+20100804-9, 1.98+20100804-10, and 1.98+20100804-11: - Apply debconf template review by debian-l10n-english and mark several more strings for translation, thanks to David Prévot and Justin B Rye. - Incorporate rewritten 05_debian_theme by Alexander Kurtz, which works when /usr is inaccessible by GRUB. -- Colin Watson Sun, 19 Dec 2010 13:25:14 +0000 grub2 (1.99~20101210-1) experimental; urgency=low * New Bazaar snapshot. - ZFS moved into grub-core. - Extend gettext to fall back from ll_CC to ll, and set lang to include country part by default so that Chinese works (LP: #686788). * Remove grub-mknetdir from grub-emu. * Exit silently from zz-update-grub kernel hook if update-grub does not exist (e.g. if grub-pc has been removed but not purged; closes: #606184). -- Colin Watson Sat, 11 Dec 2010 01:22:26 +0000 grub2 (1.99~20101126-1) experimental; urgency=low * New Bazaar snapshot (mipsel build fix, LVM-on-RAID probing fix). * Fix comma-separation in handling of grub-pc/install_devices. -- Colin Watson Fri, 26 Nov 2010 13:08:52 +0000 grub2 (1.99~20101124-1) experimental; urgency=low * New Bazaar snapshot (command priorities, build fixes, grub-mkdevicemap segfault). * Don't try to build grub-efi-amd64 on kfreebsd-i386 or hurd-i386 (requires gcc-4.4-multilib). -- Colin Watson Wed, 24 Nov 2010 12:12:33 +0000 grub2 (1.99~20101123-1) experimental; urgency=low * New Bazaar snapshot (build fixes). * Build-depend on qemu-utils and parted on non-Hurd architectures. * qemu_img_exists.patch: Skip partmap test if qemu-img doesn't exist (as is the case on the Hurd). * Make grub-efi-ia32 and grub-efi-amd64 depend on efibootmgr so that grub-install works properly. * Upgrade the installed core image when upgrading grub-efi-ia32 or grub-efi-amd64, although only if /boot/efi/EFI/ (where is an identifier based on GRUB_DISTRIBUTOR, e.g. 'debian') already exists. * Re-expand a couple of dpkg architecture wildcards to exclude certain special cases: gcc-4.4-multilib is not available on kfreebsd-i386 or hurd-i386, and qemu-system is not available on hurd-i386. -- Colin Watson Tue, 23 Nov 2010 10:51:23 +0000 grub2 (1.99~20101122-1) experimental; urgency=low [ Colin Watson ] * New Bazaar snapshot. Too many changes to list in full, but some of the more user-visible ones are as follows: - GRUB script: + Function parameters, "break", "continue", "shift", "setparams", "return", and "!". + "export" command supports multiple variable names. + Multi-line quoted strings support. + Wildcard expansion. - sendkey support. - USB hotunplugging and USB serial support. - Rename CD-ROM to cd on BIOS. - Add new --boot-directory option to grub-install, grub-reboot, and grub-set-default; the old --root-directory option is still accepted but was often confusing. - Basic btrfs detection/UUID support (but no file reading yet). - bash-completion for utilities. - If a device is listed in device.map, always assume that it is BIOS-visible rather than using extra layers such as LVM or RAID. - Add grub-mknetdir script (closes: #550658). - Remove deprecated "root" command. - Handle RAID devices containing virtio components. - GRUB Legacy configuration file support (via grub-menulst2cfg). - Keyboard layout support (via grub-mklayout and grub-kbdcomp). - Check generated grub.cfg for syntax errors before saving. - Pause execution for at most ten seconds if any errors are displayed, so that the user has a chance to see them. - Support submenus. - Write embedding zone using Reed-Solomon, so that it's robust against being partially overwritten (closes: #550702, #591416, #593347). - GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY merged into a single GRUB_DISABLE_RECOVERY variable. - Fix loader memory allocation failure (closes: #551627). - Don't call savedefault on recovery entries (closes: #589325). - Support triple-indirect blocks on ext2 (closes: #543924). - Recognise DDF1 fake RAID (closes: #603354). [ Robert Millan ] * Use dpkg architecture wildcards. [ Updated translations ] * Slovenian (Vanja Cvelbar). Closes: #604003 * Dzongkha (dawa pemo via Tenzin Dendup). Closes: #604102 -- Colin Watson Mon, 22 Nov 2010 12:24:56 +0000 grub2 (1.98+20100804-14) unstable; urgency=low [ Updated translations ] * Kazakh (Baurzhan Muftakhidinov / Timur Birsh). Closes: #609187 [ Alexander Kurtz ] * 05_debian_theme: - If we find a background image and no colours were specified, use upstream defaults for color_normal and color_highlight rather than setting color_normal to black/black. - Don't try the other alternatives when $GRUB_BACKGROUND is set; you can now add GRUB_BACKGROUND= to /etc/default/grub to force no background image (closes: #608263). -- Colin Watson Mon, 17 Jan 2011 23:19:38 +0000 grub2 (1.98+20100804-13) unstable; urgency=low * Backport from upstream: - Don't add spurious RAID array members (closes: #605357). -- Colin Watson Tue, 04 Jan 2011 14:07:14 +0000 grub2 (1.98+20100804-12) unstable; urgency=low * Backport from upstream: - Support big ext2 files (closes: #543924). - Fix gettext quoting to work with bash as /bin/sh, and make echo UTF-8-clean so that (at least) Catalan boot messages are displayed properly (closes: #605615). - Initialise next pointer when creating multiboot module (closes: #605567). - Fix PCI probing hangs by skipping remaining functions on devices that do not implement function 0 (closes: #594967). * Use semicolons rather than commas to separate size from model in debconf disk and partition descriptions; commas are too easily confused with the multiselect choice separator, and in particular make it impossible to answer questions properly in the editor frontend (closes: #608449). Unfuzzy all translations where possible. -- Colin Watson Tue, 04 Jan 2011 00:42:29 +0000 grub2 (1.98+20100804-11) unstable; urgency=low * Exit silently from zz-update-grub kernel hook if update-grub does not exist (e.g. if grub-pc has been removed but not purged; closes: #606184). * Apply debconf template review by debian-l10n-english and mark several more strings for translation, thanks to David Prévot and Justin B Rye (closes: #605748). * Unfuzzy some translations that were not updated in this round (thanks, David Prévot; closes: #606921). * Incorporate rewritten 05_debian_theme by Alexander Kurtz, which works when /usr is inaccessible by GRUB (closes: #605705). * Backport from upstream: - Recognise DDF1 DM-RAID (closes: #603354). [ Updated translations ] * Chinese (YunQiang Su). Closes: #606426 * Indonesian (Arief S Fitrianto). Closes: #606431 * Slovenian (Vanja Cvelbar). Closes: #606445 * Swedish (Martin Bagge / brother). Closes: #606455 * Ukrainian (Yatsenko Alexandr). Closes: #606538 * Basque (Iñaki Larrañaga Murgoitio). Closes: #606644 * Slovak (Slavko). Closes: #606663 * Catalan (Jordi Mallach). * Bulgarian (Damyan Ivanov). Closes: #606452 * Persian (Morteza Fakhraee). Closes: #606672 * Russian (Yuri Kozlov). Closes: #606753 * Dutch (Paul Gevers). Closes: #606807 * Japanese (Hideki Yamane). Closes: #606836 * French (Christian Perrier). Closes: #606842 * Czech (Miroslav Kure). Closes: #606854 * Spanish (Francisco Javier Cuadrado). Closes: #606903 * Portuguese (Tiago Fernandes / Miguel Figueiredo). Closes: #606908 * German (Martin Eberhard Schauer). Closes: #606896 -- Colin Watson Sat, 18 Dec 2010 17:20:09 +0000 grub2 (1.98+20100804-10) unstable; urgency=low * fix_crash_condition_in_kfreebsd_loader.patch: Import from upstream. Fixes crash condition in case kfreebsd_* commands are used after kfreebsd has (gracefully) failed. -- Robert Millan Tue, 30 Nov 2010 19:40:11 +0100 grub2 (1.98+20100804-9) unstable; urgency=low [ Robert Millan ] * Import from upstream: - refuse_embedingless_cross_disk.patch: Refuse to do a cross-disk embeddingless install rather than creating a broken install. - fix_grub_install_error_msg.patch: Replace useless recomendation to pass --modules with a recomendation to report a bug. - message_refresh.patch: Make error messages visible again. (Closes: #605485) [ Jordi Mallach ] * Update Catalan translation with latest file from the Translation Project. [ Updated translations ] * Slovenian (Vanja Cvelbar). Closes: #604003 * Dzongkha (dawa pemo via Tenzin Dendup). Closes: #604102 -- Robert Millan Tue, 30 Nov 2010 15:44:02 +0100 grub2 (1.98+20100804-8) unstable; urgency=low [ Robert Millan ] * increase_disk_limit.patch: Increase SCSI/IDE disk limits to cope with Sun Fire X4500. * linux_mdraid_1x.patch: Support for Linux MD RAID v1.x. (Closes: #593652) * yeeloong_boot_info.patch: On Yeeloong, pass machine type information to Linux. [ Updated translations ] * Portuguese fixed by Christian Perrier (variable names were translated) -- Robert Millan Fri, 05 Nov 2010 23:43:15 +0100 grub2 (1.98+20100804-7) unstable; urgency=low [ Robert Millan ] * zfs_fix_mkrelpath.patch: Replace with proper fix from upstream Bazaar. (Closes: #601087) [ Updated translations ] * Vietnamese (Clytie Siddall). Closes: #598327 * Icelandic (Sveinn í Felli). Closes: #600126 -- Robert Millan Sun, 24 Oct 2010 16:35:37 +0200 grub2 (1.98+20100804-6) unstable; urgency=low [ Robert Millan ] * zfs_v23.patch: Accept ZFS up to v23 (no changes required). * fix_usb_boot.patch: Fix boot on USB devices, for BIOSes that expose them as floppies. (Closes: #600580) * zfs_fix_mkrelpath.patch: Fix grub-mkrelpath for non-root ZFS. (Closes: #600578) [ Updated translations ] * Kazakh (kk.po) by Baurzhan Muftakhidinov via Timur Birsh (closes: #598188). * Portuguese (pt.po) by Tiago Fernandes via Rui Branco (closes: #599767). * Catalan (ca.po) by Jordi Mallach. -- Robert Millan Thu, 21 Oct 2010 23:45:23 +0200 grub2 (1.98+20100804-5) unstable; urgency=low [ Updated translations ] * Hebrew (he.po) by Omer Zak and Lior Kaplan (closes: #593855). * Romanian (ro.po) by ioan-eugen STAN (closes: #595727). * Esperanto (eo.po) by Felipe Castro (closes: #596171). [ Colin Watson ] * Make grub-efi-amd64 conflict with grub-pc as well as the other way round. * Backport upstream patches to fix DM-RAID support (closes: #594221, LP: #634840). [ Robert Millan ] * enable_zfs.patch: Fix grub-fstest build problem. * zfs_fix_label_arg.patch: Fix kfreebsd_device initialization on ZFS for non-main filesystems. -- Colin Watson Fri, 17 Sep 2010 23:45:10 +0100 grub2 (1.98+20100804-4) unstable; urgency=low [ Updated translations ] * Italian (it.po) by Luca Monducci (closes: #593685). * Finnish (fi.po) by Esko Arajärvi (closes: #593921). [ Colin Watson ] * Run update-grub from kernel hooks if DEB_MAINT_PARAMS is unset, for compatibility with old kernel packages. This may produce duplicate runs of update-grub, but that's better than not running it at all (closes: #594037). -- Colin Watson Mon, 23 Aug 2010 12:11:55 +0100 grub2 (1.98+20100804-3) unstable; urgency=low [ Updated translations ] * Brazilian Portuguese (pt_BR.po) by Flamarion Jorge (closes: #592156). * Asturian (ast.po) by Maacub (closes: #592313). * Galician (gl.po) by Jorge Barreiro (closes: #592816). [ Robert Millan ] * Backport ZFS bugfixes from upstream Bazaar: - zfs_fix_chroot.patch: Fix breakage when running grub-probe inside chroot. - zfs_fix_label_arg.patch: Fix grub-probe fs_label argument. - zfs_fix_pathname.patch: Fix pathname for non-root ZFS filesystems. - zfs_fix_segfault.patch: Fix segfault when /dev is not mounted. [ Colin Watson ] * Escape single quotes when removing them from $mode in zz-update-grub, so that this works when /bin/sh is bash (thanks, Will Dyson; closes: #593242). * Add support for ext2 root on GNU/kFreeBSD (thanks, Aurelien Jarno; closes: #593467). -- Colin Watson Thu, 19 Aug 2010 18:21:45 +0100 grub2 (1.98+20100804-2) unstable; urgency=low [ Colin Watson ] * Make /etc/kernel/postrm.d/zz-update-grub a real file rather than a symlink (closes: #592076). [ Updated translations ] * Norwegian Bokmål (nb.po) by Hans Nordhaug (closes: #591569). -- Colin Watson Sat, 07 Aug 2010 17:53:34 +0100 grub2 (1.98+20100804-1) unstable; urgency=low * New Bazaar snapshot. - Fix grub-emu build on GNU/kFreeBSD (closes: #591490). [ Colin Watson ] * Add kernel hook scripts and remove any uses of update-grub as a postinst_hook or postrm_hook in /etc/kernel-img.conf (closes: #554175). Thanks to Ben Hutchings for advice and to Harald Braumann for an early implementation. * Extend the existing GRUB_LEGACY_0_BASED_PARTITIONS handling to avoid new-style partition naming when generating output for GRUB Legacy (closes: #590554). [ Updated translations ] * Slovak (sk.po) by Slavko (closes: #591458). -- Colin Watson Wed, 04 Aug 2010 04:48:11 +0100 grub2 (1.98+20100802-1) unstable; urgency=low * New Bazaar snapshot. - Remove compatibility with terminal.mod prior to terminal_input/terminal_output separation (LP: #519358). - Enable `grub-probe -t device' resolution on ZFS. - Don't use UUID for LVM root when generating Xen entries (closes: #591093). - Restore missing whitespace to commands' --help output (closes: #590874). - Select unique numbers for named RAID arrays, for use as keys in the disk cache. [ Updated translations ] * German (Martin Eberhard Schauer). Closes: #590108 * Spanish (Francisco Javier Cuadrado). Closes: #590448 * Traditional Chinese (Tetralet). Closes: #591191 * Danish (Joe Hansen). Closes: #591223 * Dutch (Paul Gevers). Closes: #590864 * Japanese (Hideki Yamane). Closes: #591058 [ Robert Millan ] * postinst.in: Fill in device size and model information on GNU/kFreeBSD, using camcontrol. * patches/enable_zfs.patch: New patch. Link ZFS from grub-extras into grub-probe and grub-setup. * control: Build-Depend on libzfs-dev and libnvpair-dev on kfreebsd-*. [ Colin Watson ] * Offer RAID devices as GRUB installation targets if they contain /, /boot, or /boot/grub. -- Colin Watson Tue, 03 Aug 2010 02:13:07 +0100 grub2 (1.98+20100722-1) unstable; urgency=low * New Bazaar snapshot. - Don't count named RAID arrays when looking for unused array numbers. [ Colin Watson ] * Merge from Ubuntu: - grub-common Breaks: lupin-support (<< 0.30) due to a grub-mkimage syntax change (lupin-support isn't in Debian, but this is harmless anyway). -- Colin Watson Thu, 22 Jul 2010 14:33:34 +0100 grub2 (1.98+20100720-1) unstable; urgency=low * New Bazaar snapshot. - Link to Info documentation on changes from GRUB Legacy in README (closes: #502623). - Add support for mdadm metadata formats 1.x (closes: #492897). [ Aaron M. Ucko ] * Compare -trunk kernels earlier than numeric ABIs (closes: #568160). [ Colin Watson ] * Remove /boot/grub/device.map, /boot/grub/grubenv, /boot/grub/installed-version, and /boot/grub/locale/ on purge, if permitted (closes: #547679). * Convert from CDBS to dh. * Use exact-version dependencies in grub2 and grub-efi, to reduce potential confusion. * Raise priority of grub-common and grub-pc to optional (also done in archive overrides). * Copy-edit debian/presubj. * Use 'mktemp -t' rather than hardcoding /tmp (closes: #589537). [ Mario 'BitKoenig' Holbe ] * Update /etc/grub.d/05_debian_theme to handle multiple entries in GRUB_TERMINAL_OUTPUT (closes: #589322). [ Updated translations ] * Simplified Chinese (zh_CN.po) by YunQiang Su (closes: #589013). * Russian (ru.po) by Yuri Kozlov (closes: #589244). * Swedish (sv.po) by Martin Bagge / brother (closes: #589259). * Bulgarian (bg.po) by Damyan Ivanov (closes: #589272). * Indonesian (id.po) by Arief S Fitrianto (closes: #589318). * Arabic (ar.po) by Ossama M. Khayat. * Basque (eu.po) by Iñaki Larrañaga Murgoitio (closes: #589489). * Persian (fa.po) by Bersam Karbasion (closes: #589544). * Czech (cs.po) by Miroslav Kure (closes: #589568). * Belarusian (be.po) by Viktar Siarheichyk (closes: #589634). -- Colin Watson Wed, 21 Jul 2010 09:11:14 +0100 grub2 (1.98+20100710-1) unstable; urgency=low * New Bazaar snapshot. - Handle degraded RAID arrays in grub-probe and grub-setup. - Fix gfxterm pager handling. [ Fabian Greffrath ] * Get value of correct debconf question when deciding whether to purge /boot/grub (closes: #588331). [ Colin Watson ] * Generate device.map in something closer to the old ordering (thanks, Vadim Solomin). [ Updated translations ] * Croatian (hr.po) by Josip Rodin, closes: #588350. * French (fr.po) by Christian Perrier (closes: #588695). -- Colin Watson Mon, 12 Jul 2010 11:46:53 +0100 grub2 (1.98+20100706-1) unstable; urgency=low * New Bazaar snapshot. - USB hub support. - Fix GRUB_BACKGROUND configuration ordering. - Fix corruption of first entry name in a reiserfs directory. - Don't include MD devices when generating device.map (if you're using RAID and upgraded through 1.98+20100702-1 or 1.98+20100705-1, you may need to fix this up manually). -- Colin Watson Tue, 06 Jul 2010 18:06:40 +0100 grub2 (1.98+20100705-1) unstable; urgency=medium * New Bazaar snapshot. - Bidi and diacritics support. + Use terminfo for ieee1275 terminals (closes: #586953). - Don't use empty grub_device in EFI grub-install (closes: #587838). - Fix grub-setup core.img comparison when not embedding (thanks, Matt Kraai and M. Vefa Bicakci; closes: #586621). * Update Source: in debian/copyright (thanks, Jörg Sommer). * Convert by-id disk device names from device.map to traditional device names for display (closes: #587951). * Set urgency=medium. We've cleared out most of the apparent regressions at this point, and #550704 is getting more and more urgent to fix in testing. -- Colin Watson Mon, 05 Jul 2010 02:09:58 +0100 grub2 (1.98+20100702-1) unstable; urgency=low * New Bazaar snapshot. - Use video functions in Linux loader rather than hardcoding UGA; load all available video backends (closes: #565576, probably). - Add support for initrd images on Fedora 13. - Output grub.cfg stanzas for Xen (closes: #505517). - Add 'cat --dos' option to treat DOS-style "\r\n" line endings as simple newlines (closes: #586358). - Change grub-mkdevicemap to emit /dev/disk/by-id/ names where possible on Linux. - Return CF correctly in mmap e820/e801 int15 hook (closes: #584846). - The info documentation now has no broken references, although of course it could still use more work (closes: #553460). - Support GRUB_BADRAM in grub-mkconfig. - Skip LVM snapshots (closes: #574863). [ Colin Watson ] * Mention grub-rescue-usb.img in grub-rescue-pc description (closes: #586462). * Add instructions for using grub-rescue-usb.img (closes: #586463). * Remove /usr/lib/grub/mips-* from grub-common rather than the incorrect /usr/lib/grub/mipsel-*, so that it stops clashing with grub-yeeloong; add a versioned Replaces to grub-yeeloong just in case (closes: #586526). * Remove qemu-system build-dependency on hurd-i386, where it doesn't seem to exist. Disable tests if qemu-system-i386 isn't available. * Mark "upgrade-from-grub-legacy" paragraph in grub-pc/chainload_from_menu.lst as untranslatable. * Update Homepage field (thanks, Sedat Dilek). * On Linux, if /boot/grub/device.map exists on upgrade to this version, regenerate it to use stable device names in /dev/disk/by-id/. If it had more than one entry, then display a critical-priority debconf note (sorry, but it's better than silently breaking boot menu entries) advising people to check custom boot menu entries and update them if necessary (closes: #583271). * Use 'set -e' rather than '#! /bin/sh -e' or '#! /bin/bash -e', to avoid accidents when debugging with 'sh -x'. * Store grub-pc/install_devices as persistent device names under /dev/disk/by-id/ (closes: #554790). Migrate previous device names to that, with explicit confirmation in non-trivial cases to make sure we got the right ones. If the devices we were told to install to ever go away, ask again. (This is based on the implementation in Ubuntu.) * If grub-install fails during upgrade-from-grub-legacy, allow the user to try again with a different device, but failing that cancel the upgrade (closes: #587790). * Remove numbering from patch files. The order is now explicit in a quilt series file, and renumbering from time to time is tedious. [ Updated translations ] * Ukrainian (uk.po) by Yatsenko Alexandr / Borys Yanovych (closes: #586611). * Indonesian (id.po) by Arief S Fitrianto (closes: #586799). * Swedish (sv.po) by Martin Bagge (closes: #586827). * Persian (fa.po) by Behrad Eslamifar (closes: #587085). * French (fr.po) by Christian Perrier (closes: #587383). * Galician (gl.po) by Jorge Barreiro (closes: #587796). [ Robert Millan ] * Add commented GRUB_BADRAM example in debian/default/grub. -- Colin Watson Fri, 02 Jul 2010 17:42:56 +0100 grub2 (1.98+20100617-1) unstable; urgency=low * New Bazaar snapshot. - Fix i386-pc prefix handling with nested partitions (closes: #585068). * When running grub-pc.postinst from upgrade-from-grub-legacy, tell it to disregard the fact that /boot/grub/stage2 and /boot/grub/menu.lst still exist (closes: #550477). * Touch a marker file when grub-install is run but GRUB Legacy files are still around. If that marker file is present, pretend that GRUB Legacy files are missing when upgrading. * If GRUB Legacy files are present when upgrading, scan boot sectors of all disks for GRUB 2. If we find GRUB 2 installed anywhere, then ask the user if they want to finish conversion to GRUB 2, and warn them that not doing so may render the system unbootable (closes: #586143). Thanks to Sedat Dilek for helping to narrow down this bug. * Leaving grub-pc/install_devices empty makes sense in some situations, but more often than not is a mistake. On the other hand, automatically selecting all disk devices would upset some people too. Compromise by simply asking for explicit confirmation if grub-pc/install_devices is left empty, defaulting to false so that simply selecting all the defaults in debconf can't leave you with an unbootable system (closes: #547944, #557425). -- Colin Watson Sat, 19 Jun 2010 01:31:40 +0100 grub2 (1.98+20100614-2) unstable; urgency=low * Build-depend on gcc-4.4-multilib on i386 and kopensolaris-i386 too, in order to build grub-efi-amd64. * Ignore non-option arguments in grub-mkconfig (closes: #586056). -- Colin Watson Wed, 16 Jun 2010 17:58:48 +0100 grub2 (1.98+20100614-1) unstable; urgency=low * New Bazaar snapshot. - Make target-related error messages from grub-mkimage slightly more helpful (closes: #584415). - Fix underquoting that broke savedefault (thanks, Mario 'BitKoenig' Holbe; closes: #584812). - Expand 'info grub' substantially, including a new section on configuring authentication (closes: #584822). - Give all manual pages proper NAME sections (closes: #496706). * Update 915resolution from grub-extras: - Fix a hang with 945GME (thanks, Sergio Perticone; closes: #582142). [ Colin Watson ] * Disable grub-emu on sparc for the time being. We're currently trying to use TARGET_* flags to build it, which won't work. * Don't build-depend on libsdl1.2-dev on hurd-i386. Although libsdl1.2-dev exists there, it's currently uninstallable due to missing libpulse-dev, and we can happily live without it for now. * kfreebsd-amd64 needs gcc-4.4-multilib too (closes: #585668). * Warn and return without error from prepare_grub_to_access_device if /boot is a dm-crypt device (thanks, Marc Haber; closes: #542165). * Make /etc/grub.d/05_debian_theme usable by shells other than bash (thanks, Alex Chiang; closes: #585561). * Remove grub-mkisofs leftovers from debian/copyright. * Fix reversed sense of DEB_BUILD_OPTIONS=nocheck handling. * Build-depend on qemu-system for grub-pc tests. -- Colin Watson Tue, 15 Jun 2010 12:45:35 +0100 grub2 (1.98+20100602-2) unstable; urgency=low * Only build-depend on libdevmapper-dev on Linux architectures. * Don't build-depend on libusb-dev on hurd-i386, where it doesn't seem to be available. * Fix printf format mismatch in disk/usbms.c (closes: #584474). * Fix verbose error output when device-mapper isn't supported by the running kernel (closes: #584196). * Prepend "part_" to partmap module names in grub-mkconfig, in line with grub-install (closes: #584426). -- Colin Watson Fri, 04 Jun 2010 14:01:58 +0100 grub2 (1.98+20100602-1) unstable; urgency=low * New Bazaar snapshot. - Add btrfs probing support, currently only in the single-device case (closes: #540786). - Fix grub-emu build on mips/powerpc/sparc. - Add safety check to make sure that /boot/grub/locale exists before trying to probe it (closes: #567211). - Several 'info grub' improvements, including a new section on configuration file generation using grub-mkconfig which documents the available keys in /etc/default/grub (closes: #497085). - Many USB fixes. [ Colin Watson ] * Reorganise configure and build targets in debian/rules to use stamp files. configure/* never existed and build/* was always a directory, so make never considered either of them up to date (closes: #450505). * Remove config.h.in from AUTOGEN_FILES, since autoheader doesn't necessarily update it. * Remove conf/gcry.mk from AUTOGEN_FILES, and conf/gcry.rmk from their dependencies. autogen.sh runs util/import_gcry.py after autoconf et al, so conf/gcry.rmk's timestamp will be later than some of the autogenerated outputs. * Go back to shipping rescue images in the grub-rescue-pc .deb itself rather than generating them in the postinst. This means that (a) they get removed when the package is removed (closes: #584176); (b) they are listed in package metadata, as is proper for files in /usr (closes: #584218); (c) grub-rescue-pc can potentially be used as a build-dependency for other packages that need to build GRUB images into installation media etc., without having to build-depend on grub-pc which isn't coinstallable with other platform variants and does invasive things in its postinst. * Add grub-mkrescue patch from Thomas Schmitt to allow reducing the size of xorriso-created images. Use this to ensure that grub-rescue-floppy.img fits well within size limits (closes: #548320). -- Colin Watson Thu, 03 Jun 2010 11:24:41 +0100 grub2 (1.98+20100527-2) unstable; urgency=low * Always override statically-linked-binary Lintian tag for kernel.img; dynamic linking makes no sense here. * kernel.img is stripped upstream where it can be, but override Lintian's error for the cases where it can't. * Override binary-from-other-architecture for kernel.img as well as *.mod when building grub-efi-amd64 on i386. -- Colin Watson Tue, 01 Jun 2010 13:48:14 +0100 grub2 (1.98+20100527-1) unstable; urgency=low * New Bazaar snapshot. - Support multiple terminals in grub-mkconfig, e.g. GRUB_TERMINAL='serial console' (closes: #506707). - Speed up consecutive hostdisk operations on the same device (closes: #508834, #574088). - Fix grammar error in grub-setup warning (closes: #559005). - Use xorriso for image creation rather than embedding a modified copy of mkisofs (closes: #570156). - Issue an error rather than segfaulting if only some LVM component devices are in device.map (closes: #577808). - Fix typo in make_device_name which caused grub-probe problems on systems with BSD disk labels (closes: #578201). - Add DM-RAID probe support (closes: #579919). - Include all gnumach kernels on Hurd, not just gnumach and gnumach.gz (closes: #581584). [ Colin Watson ] * Restore TEXTDOMAINDIR correction in grub.d files, lost by mistake in a merge. Noticed by Anthony Fok. * Don't fail on purge if the ucf association has already been taken over by a different grub package (closes: #574176). * Add debian/grub-extras/*/conf/*.mk to AUTOGEN_FILES. * Remove support for the lpia architecture, now removed from Ubuntu. * Conflict with grub (<< 0.97-54) as well as grub-legacy. * Build-depend on libdevmapper-dev for DM-RAID probe support. * Switch to quilt. * Suggest xorriso (>= 0.5.6.pl00) in grub-common, since grub-mkrescue now needs it. Depend on it in grub-rescue-pc. * Move grub-mkimage to grub-common, now that it only has one implementation. * Clean up temporary files used while building grub-firmware-qemu. * Make grub-probe work with symlinks under /dev/mapper (closes: #550704). * When upgrading a system where GRUB 2 is chainloaded from GRUB Legacy and upgrade-from-grub-legacy has not been run, upgrade the chainloaded image rather than confusing the user by prompting them where they want to install GRUB (closes: #546822). * Build-depend on libsdl1.2-dev for SDL support in grub-emu. * Don't leak debconf's file descriptor to update-grub, so that the LVM tools called from os-prober don't complain about it (closes: #549976). Other leaks are not this package's fault, may not be bugs at all, and in any case os-prober 1.36 suppresses the warnings. * Build-depend on flex (>= 2.5.35). * Build-depend on gcc-4.4-multilib on amd64. [ Updated translations ] * Slovenian (sl.po) by Vanja Cvelbar (closes: #570110). * Vietnamese (vi.po) by Clytie Siddall (closes: #574578). * Tamil (ta.po) by Tirumurti Vasudevan (closes: #578282). * Portuguese (pt.po) by Tiago Fernandes (closes: #580140). * Romanian (ro.po) by Eddy Petrișor / Andrei Popescu (closes: #583185). -- Colin Watson Tue, 01 Jun 2010 11:24:38 +0100 grub2 (1.98-1) unstable; urgency=low * New upstream release (closes: #572898). - Fix grub-script-check to handle empty lines (closes: #572302). - Fix offset computation when reading last sectors. Partition reads and writes within and outside a partition (closes: #567469, #567884). - Fix script execution error handling bug that meant that an error in a menuentry's last statement caused the whole menuentry to fail (closes: #566538, LP: #464743). - Support GRUB_GFXPAYLOAD_LINUX (closes: #536453, LP: #416772). [ Samuel Thibault ] * Add GRUB_INIT_TUNE example to /etc/default/grub (closes: #570340). [ Colin Watson ] * Build-depend on libusb-dev so that grub-emu is reliably built with USB support (closes: #572854). * Update directions in debian/rules on exporting grub-extras to account for it being maintained in Bazaar nowadays. * Add myself to Uploaders. * Acknowledge NMUs, thanks to Torsten Landschoff and Julien Cristau. -- Colin Watson Tue, 09 Mar 2010 13:25:35 +0000 grub2 (1.98~20100128-1.2) unstable; urgency=low * Non-maintainer upload. * Stop setting gfxpayload=keep (closes: #567245). -- Julien Cristau Sun, 14 Feb 2010 20:37:51 +0100 grub2 (1.98~20100128-1.1) unstable; urgency=low * Non-maintainer upload. * Apply trivial patch (already merged upstream) fixing the offset computation for non-cached reads (closes: #567637). -- Torsten Landschoff Mon, 08 Feb 2010 22:15:01 +0100 grub2 (1.98~20100128-1) unstable; urgency=low * New Bazaar snapshot. - Fix corruption problem when reading files from CDROM. (Closes: #567219) [ Felix Zielcke ] * Never strip kernel.img in rules. Upstream already does it when it can be done. (Closes: #561933) * Bump Standards-Version to 3.8.4. [ Robert Millan ] * rules: Run the testsuite (make check) when building grub-pc. -- Robert Millan Thu, 28 Jan 2010 16:28:45 +0100 grub2 (1.98~20100126-1) unstable; urgency=low * New Bazaar snapshot. - Includes mipsel-yeeloong port. [ Robert Millan ] * config.in: Lower priority of grub2/linux_cmdline_default. [ Felix Zielcke ] * Drop `CFLAGS=-O0' workaround on powerpc. Should be fixed correctly now. * Ship grub-bin2h and grub-script-check in grub-common. * Terminate NEWS.Debian with a blank line like lintian would suggest if that check would be working correctly. -- Felix Zielcke Tue, 26 Jan 2010 19:26:25 +0100 grub2 (1.98~20100115-1) unstable; urgency=low * New Bazaar snapshot. - Includes savedefault / grub-reboot branch. - Includes Multiboot video support (from latest 1.x draft). -- Robert Millan Fri, 15 Jan 2010 18:15:26 +0100 grub2 (1.98~20100110-1) unstable; urgency=low * New Bazaar snapshot. [ Robert Millan ] * grub-rescue-pc.postinst: Fix image generation during upgrades. (Closes: #564261) -- Robert Millan Sun, 10 Jan 2010 02:45:52 +0100 grub2 (1.98~20100107-1) unstable; urgency=low * New Bazaar snapshot. [ Robert Millan ] * grub-rescue-pc.postinst: Use grub-mkrescue for floppy as well. [ Updated translations ] * Chinese (zh_TW.po) by Tetralet. (Closes: #564044) -- Robert Millan Thu, 07 Jan 2010 17:56:10 +0100 grub2 (1.98~20100101-1) unstable; urgency=high * New Bazaar snapshot. - Fix FTBS on sparc. [ Robert Millan ] * rules: Auto-update version from debian/changelog. [ Felix Zielcke ] * Add -O0 to CFLAGS on powerpc to avoid the `_restgpr_31_x in boot is not defined' FTBFS. -- Felix Zielcke Fri, 01 Jan 2010 00:31:37 +0100 grub2 (1.98~20091229-1) unstable; urgency=high * New Bazaar snapshot. - Fix slowness when $prefix uses an UUID. (Closes: #541145, LP: #420933) - Correctly set TARGET_CFLAGS. (Closes: #562953) [ Robert Millan ] * grub-rescue-pc.postinst: Build USB rescue image. * rules: Invoke configure with relative path. This makes binaries smaller, since dprintf strings are constructed using this path. [ Felix Zielcke ] * Urgency=high due to RC bug fix. * Fix version comparison in grub-common.preinst for handling obsolete /etc/grub.d/10_freebsd. (Closes: #562921) -- Felix Zielcke Tue, 29 Dec 2009 16:05:00 +0100 grub2 (1.98~20091222-1) unstable; urgency=low * New Baazar snapshot. - Make 30_os-prober again dash compatible. (Closes: #562034) -- Felix Zielcke Tue, 22 Dec 2009 12:50:57 +0100 grub2 (1.98~20091221-1) unstable; urgency=low * New Bazaar snapshot. - Fix search command failing on some broken BIOSes. (Closes: #530357) [ Felix Zielcke ] * Add Replaces:/Conflicts: grub-linuxbios to grub-coreboot. (Closes: #561811) * Delete obsolete /etc/grub.d/10_freebsd if it has not been modified, else disable it. (Closes: #560346) -- Robert Millan Mon, 21 Dec 2009 22:04:17 +0100 grub2 (1.98~20091210-1) unstable; urgency=low * Version bump. -- Robert Millan Mon, 14 Dec 2009 14:52:59 +0100 grub2 (1.97+20091210-1) unstable; urgency=low * New Bazaar snapshot. - patches/02_fix_mountpoints_in_mkrelpath.diff: Remove (merged). - Fixes FTBFS on powerpc (again) and sparc. - patches/903_grub_legacy_0_based_partitions.diff: Resync (merged into debian branch). * Fix dpkg dependency for lenny compatibility. -- Robert Millan Thu, 10 Dec 2009 00:35:20 +0100 grub2 (1.97+20091130-1) unstable; urgency=low * New Bazaar snapshot. * Enable ntldr-img from grub-extras. -- Robert Millan Mon, 30 Nov 2009 02:33:03 +0100 grub2 (1.97+20091125-2) unstable; urgency=low [ Updated translations ] * Bulgarian (bg.po) by Damyan Ivanovi (Closes: #558039) [ Robert Millan ] * control: Remove genisoimage from Build-Depends/Suggests (no longer used). * grub.d/05_debian_theme: Make output string distro-agnostic. [ Felix Zielcke ] * patches/02_fix_mountpoints_in_mkrelpath.diff: New patch to handle mount points like the old shell function did. (Closes: #558042) -- Felix Zielcke Sun, 29 Nov 2009 21:38:00 +0100 grub2 (1.97+20091125-1) unstable; urgency=low [ Robert Millan ] * New upstream snapshot. - Fixes script parser load error. * Add gettext to Build-Depends and gettext-base to grub-common's Depends. -- Felix Zielcke Wed, 25 Nov 2009 19:22:51 +0100 grub2 (1.97+20091124-1) unstable; urgency=low * New upstream snapshot. - Fix grub-mkisofs related FTBFS on powerpc. (Closes: #557704) - Create fake GRUB devices for devices not listed in device.map. This also makes dmraid and multipath work as long as search --fs-uuid works. (Closes: #442382, #540549, LP: #392136) - rules: grub-emu is now built as a port. [ Felix Zielcke ] * Change the bt-utf-source build dependency to xfonts-unifont. It's more complete, better maintained and grub-mkfont supports actually more then BDF fonts as input, thanks to libfreetype. * Use grub-probe to get the GRUB device of /boot/grub instead of passing (hd0) to grub-install when creating the core.img with chainloading. This avoids the (UUID=) hack slowness in case /boot/grub is on a different disk then (hd0) in device.map. * patches/903_grub_legacy_0_based_partitions.diff: Update. * Add a build dependency on automake and python. * Set TARGET_CC=$(CC) to really use gcc-4.4 everywhere. Also pass it and CC as arguments to ./configure instead of env vars so they get preserved. * Ship grub-mkrelpath in grub-common. * Ship the locale files in grub-common. * Add a dependency on 'dpkg (>= 1.15.4) | install-info' for grub-common as recommended by Policy and lintian. -- Felix Zielcke Tue, 24 Nov 2009 21:20:00 +0100 grub2 (1.97+20091115-1) unstable; urgency=low * New upstream snapshot. - Fix security problem with password checking. (Closes: #555195) - Fix the generated GNU/Hurd menu entries and also add support for it in 30_os-prober. (Closes: #555188) - Same grub-mkrescue for grub-pc and grub-coreboot, used by grub-rescue-pc during postinst now. (Closes: #501867) [ Felix Zielcke ] * Ship grub-mkisofs in grub-common. * patches/002_grub.d_freebsd.in.diff: Remove (merged upstream). * patches/906_grub_extras.diff: Remove. Superseded by GRUB_CONTRIB variable in recent upstream trunk. * rules: Export GRUB_CONTRIB to enable grub-extras add-ons. * Pass --force to grub-install in the postinst. (Closes: #553415) * Don't strip debug symbols from grub-emu. It's meant for debugging and with them it's much more useful. * Ship grub-mkfloppy in grub-pc. * Revert the Replaces: grub-common to (<= 1.96+20080413-1) on the grub-pc package. It was wrongly modified long ago. [ Robert Millan ] * copyright: Document mkisofs. * control: Update Vcs- fields (moved to Bazaar). * rules: Update debian/legacy/update-grub rule to Bazaar. -- Felix Zielcke Sun, 15 Nov 2009 19:13:31 +0100 grub2 (1.97-1) unstable; urgency=low [ Robert Millan ] * patches/905_setup_force.diff: Remove, no longer needed as of grub-installer >= 1.47. * grub.d/05_debian_theme: Attempt to source grub_background.sh from desktop-base (Needed for #495282, #495616, #500134, see also #550984). [ Felix Zielcke ] * Add a build dependency on texinfo. * Fix little typo in /etc/default/grub. (LP: #457703) [ Updated translations ] * Finnish (fi.po) by Esko Arajärvi. (Closes: #551912) -- Felix Zielcke Sun, 25 Oct 2009 19:50:21 +0100 grub2 (1.97~beta4-1) unstable; urgency=low * New upstream beta release. [ Felix Zielcke ] * Change the Recommends: os-prober to (>= 1.33). * patches/907_grub.cfg_400.diff: Really add it. Somehow it was a 0 byte file. (Closes: #547409) * Convert newlines back to spaces when parsing kopt from GRUB Legacy's menu.lst, before giving the value to Debconf. Thanks to Colin Watson. (Closes: #547649) * Ship the info docs in grub-common. (Closes: #484074) * Remove generated /usr/share/info/dir* files. * Update the presubj bug file and also install it for grub-common. [ Robert Millan ] * Enable ZFS and 915resolution in grub-extras (now requires explicit switch). * grub-common conflicts with grub-doc (<< 0.97-32) and grub-legacy-doc (<< 0.97-59). * Move grub-emu to a separate package. [ Updated translations ] * Japanese (ja.po) by Hideki Yamane. (Closes: #549599) -- Robert Millan Mon, 05 Oct 2009 20:03:04 +0200 grub2 (1.97~beta3-1) unstable; urgency=high * New upstream beta release. - Make it more clear how to use /etc/grub.d/40_custom. (Closes: #545153) - fix a serious memory corruption in the graphical subsystem. (Closes: #545364, #544155, #544639, #544822, LP: #424503) - patches/003_grub_probe_segfault.diff: Remove (merged). * Change the watch file so upstream beta releases are recognized. * Include /etc/default/grub in bug reports. * Recommend os-prober (>= 1.32). (Closes: #491872) * Change the gcc-multilib [sparc] build dependency to gcc-4.4-multilib [sparc]. * patches/907_grub.cfg_400.diff: New patch to make grub.cfg again mode 444 if it does not contain a password line. * Use `su' in the bug reporting script to read grub.cfg in case the user is not allowed to read it. * Readd grub-pc/kopt-extracted template. [ Updated translations ] * Brazilian Portuguese (pt_BR.po) by Flamarion Jorge. * Japanese (ja.po) by Hideki Yamane. (Closes: #545331) * Spanish (es.po) by Francisco Javier Cuadrado. (Closes: #545566) * Italian (it.po) by Luca Monducci. (Closes: #546035) -- Felix Zielcke Sat, 12 Sep 2009 15:28:20 +0200 grub2 (1.97~beta2-2) unstable; urgency=low [ Updated translations ] * Dutch (nl.po) by Paul Gevers. (Closes: #545050) [ Felix Zielcke ] * Move GRUB Legacy's grub-set-default to /usr/lib/grub-legacy in preparation for GRUB 2's grub-set-default. * Remove password lines in bug script. [ Robert Millan ] * Do not conflict with `grub' dummy package (this prevented upgrades). * patches/003_grub_probe_segfault.diff: Disable file test codepath, which wasn't normally used before. -- Felix Zielcke Sat, 05 Sep 2009 00:27:22 +0200 grub2 (1.97~beta2-1) unstable; urgency=low * New upstream beta release. - Fix loading of FreeBSD modules. (Closes: #544305) [ Updated translations ] * French (fr.po) by Christian Perrier. (Closes: #544320) * Czech (cs.po) by Miroslav Kure. (Closes: #544327) * Belarusian (be.po) by Hleb Rubanau. * Arabic (ar.po) by Ossama M. Khayat. * Catalan (ca.po) by Juan Andrés Gimeno Crespo. * Russian (ru.po) by Yuri Kozlov. (Closes: #544730) * Swedish (sv.po) by Martin Ågren. (Closes: #544759) * Brazilian Portuguese (pt_BR.po) by Flamarion Jorge. (Closes: #544810) * German (de.po) by Helge Kreutzmann. (Closes: #544912) [ Robert Millan ] * Build with GCC 4.4. -- Robert Millan Fri, 04 Sep 2009 14:40:20 +0200 grub2 (1.97~beta1-1) unstable; urgency=low * New upstream beta release. [ Updated translations ] * German (de.po) by Helge Kreutzmann. (Closes: #544261) * Asturian (ast.po) by Marcos. * Georgian (ka.po) by Aiet Kolkhi. [ Robert Millan ] * Merge config, templates, postinst, postrm, dirs and install files into a single source. * Disable Linux-specific strings on GNU/kFreeBSD. Enable translations in grub2/linux_cmdline_default. Add grub2/kfreebsd_* strings (still unused). -- Felix Zielcke Sun, 30 Aug 2009 18:01:40 +0200 grub2 (1.96+20090829-1) unstable; urgency=low * New SVN snapshot. - Fix filesystem mapping on GNU/kFreeBSD. (Closes: #543950) * New grub-extras SVN snapshot. - Add 915resolution support to the GMA500 (poulsbo) graphics chipset. Thanks to Pedro Bulach Gapski. (Closes: #543917) * Use `cp -p' to copy /usr/share/grub/default/grub to the temporary file to preverse permissions. * Remove also efiemu files from /boot/grub on purge if requested. * Check that GRUB_CMDLINE_LINUX and GRUB_CMDLINUX_LINUX_DEFAULT is at the start of line in *.postinst. * Don't check that $GRUB_CMDLINE_LINUX{,DEFAULT} are non empty strings in *.config. * Add empty GRUB_CMDLINE_LINUX to /usr/share/grub/default/grub. * Factorise the editing of the temporary file. Thanks to Martin F Krafft. * Read in /etc/default/grub in *.config files. [ Updated translations ] * French (fr.po) by Christian Perrier. (Closes: #544023) * Russian (ru.po) by Yuri Kozlov. (Closes: #544077) * Italian (it.po) by Luca Monducci. (Closes: #544200) -- Felix Zielcke Sat, 29 Aug 2009 17:01:17 +0200 grub2 (1.96+20090826-3) unstable; urgency=low * Add missing quotes in grub-pc.config and *.postinst. -- Felix Zielcke Wed, 26 Aug 2009 19:14:23 +0200 grub2 (1.96+20090826-2) unstable; urgency=low * Really use the correct templates in grub-pc.config. ARGS. -- Felix Zielcke Wed, 26 Aug 2009 14:10:41 +0200 grub2 (1.96+20090826-1) unstable; urgency=low * New SVN snapshot. * Use the right templates in grub-pc.config. (Closes: #543615) -- Felix Zielcke Wed, 26 Aug 2009 11:00:36 +0200 grub2 (1.96+20090825-1) unstable; urgency=low * New SVN snapshot. - Enable gfxterm only if there's a suitable video backend and don't print an error if not. (Closes: #520846) [ Felix Zielcke ] * Copy unicode.pf2 instead of ascii.pf2 to /boot/grub in grub-pc postinst (Closes: #542314). * Update Standards version to 3.8.3. * Use DEB_HOST_ARCH_CPU for the generation of the lintian overrides. * Fix calling the grub-pc/postrm_purge_boot_grub template in grub-pc.postinst. * Handle GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT via debconf. Thanks to Martin F. Krafft and Colin Watson for idea and hints. * Use ucfr --force when /etc/default/grub is registered to a grub-* package. * Use #!/bin/sh in *.config and fix a small bashism in grub-pc.config. [ Robert Millan ] * patches/907_terminal_output_workaround.diff: Remove. It seems that it wasn't really necessary. * grub-pc.postinst: Avoid printing an error if /etc/kernel-img.conf doesn't exist, because it is misleading. We simply refrain from fixing it and move along. * grub-pc.postinst: Don't schedule generation of grub.cfg via "grub-install" code path unless we actually run grub-install. * grub-pc.postinst: Only copy unicode.pf2 and moreblue-orbit-grub.png when /boot/grub/grub.cfg is scheduled to be generated. * legacy/upgrade-from-grub-legacy: Reset grub-pc/install_devices. Thanks Colin Watson. (Closes: #541230) -- Felix Zielcke Tue, 25 Aug 2009 21:45:24 +0200 grub2 (1.96+20090808-1) unstable; urgency=low * New SVN snapshot. - Fix XFS with inode size different then 256. (Closes: #528761) - Add support for multiple LVM metadata areas. (LP: #408580) - patches/008_dac_palette_width.diff: Remove. (merged) - Prefer unicode over ascii font. (LP: #352034) [ Felix Zielcke ] * Fix the generation of the lintian override for efiemu64.o. * Remove the Conflicts dmsetup. * Use ?= for setting DEB_HOST_ARCH. * Document GRUB_DISABLE_LINUX_RECOVERY in /etc/default/grub. (Closes: #476536 LP: #190207) * Add docs/grub.cfg to examples. * patches/01_uuids_and_lvm_dont_play_along_nicely.diff: Updated to also disable UUIDs on LVM over RAID. * Add a debconf prompt to remove all grub2 files from /boot/grub on purge. (Closes: #527068, #470400) * Move the Suggests: os-prober from grub-pc to grub-common. * patches/901_dpkg_version_comparison.diff: Updated. * Update the Replaces on grub-common for the other packages to (<< 1.96+20080831-1). (Closes: #540492) [ Robert Millan ] * Reorganize grub-pc.{config,postinst} logic. The idea being that if there's no trace of GRUB Legacy, the grub-pc/install_devices template will be shown even if this is the first install. * When setting grub-pc/install_devices, obtain input dynamically from grub-mkdevicemap (rather than devices.map). (Closes: #535525) * Add a note to grub-pc/install_devices template that it's also possible to install GRUB to a partition boot record. * patches/002_grub.d_freebsd.in.diff: New patch. Reimplement 10_freebsd.in to handle multiple kernel versions & acpi.ko. -- Robert Millan Mon, 10 Aug 2009 18:49:52 +0200 grub2 (1.96+20090725-1) unstable; urgency=high * New SVN snapshot. - Don't add drivemap call with Windows Vista/7. It breaks Win 7. (LP: #402154) [ Felix Zielcke ] * Don't build grub-efi-amd64 on hurd-i386. * Change DEB_BUILD_ARCH to DEB_HOST_ARCH in the check for sparc. * Don't add the lintian override for kernel.img for sparc and grub-pc. * Add a lintian override for binary-from-other-architecture for grub-efi-amd64 and grub-pc on i386. * Use wildcards in the lintian overrides. * Add a Conflicts/Replaces for all packages except grub-common. (Closes: #538177) [ Robert Millan ] * 008_dac_palette_width.diff: New patch. Fix blank screen when booting Linux with vga= parameter set to a packed color mode (<= 8-bit). (Closes: #535026) * Set urgency=high because #535026 affects 1.96+20090709-1 which is in testing now. * patches/907_terminal_output_workaround.diff: Work around recent regression with terminal_output command (not critical, just breaks gfxterm). -- Robert Millan Sat, 25 Jul 2009 19:00:53 +0200 grub2 (1.96+20090721-4) unstable; urgency=low * Place grub-ofpathname only in grub-common. (Closes: #537999) -- Felix Zielcke Wed, 22 Jul 2009 13:38:24 +0200 grub2 (1.96+20090721-3) unstable; urgency=low * Don't strip kernel.img on sparc. * Suggest efibootmgr on grub-efi-{amd64,ia32}. * Pass --disable-grub-fstest to configure. (Closes: #537897) -- Felix Zielcke Tue, 21 Jul 2009 21:46:01 +0200 grub2 (1.96+20090721-2) unstable; urgency=low * Add back Conflicts/Replaces grub. -- Felix Zielcke Tue, 21 Jul 2009 11:24:45 +0200 grub2 (1.96+20090721-1) unstable; urgency=low * New SVN snapshot. * Change License of my update-grub(8) and update-grub2(8) manpages to GPL3+ to match new copyright file. * Merge from Ubuntu: Don't build grub-efi-amd64 on lpia. * Don't pass `--enable-efiemu' to configure. On kfreebsd-i386 it won't compile and it should be now auto detected if it's compilable. (Closes: #536783) * Don't build grub-efi-amd64 on kfreebsd-i386. It lacks 64bit compiler support. * Rename the lintian override for kernel.elf to kernel.img. * Strip kernel.img not kernel.elf, but not in the case of grub-pc. * Rename the Conflicts/Replaces grub to grub-legacy. (Closes: #537824) -- Felix Zielcke Tue, 21 Jul 2009 10:50:20 +0200 grub2 (1.96+20090709-1) unstable; urgency=low * New SVN snapshot. * control (Build-Depends): Add gcc-multilib [sparc]. * copyright: Rewrite using DEP-5 format. * Merge grub-extras into the package, and integrate it with GRUB's build system. - patches/906_grub_extras.diff - rules - copyright -- Robert Millan Thu, 09 Jul 2009 00:26:49 +0200 grub2 (1.96+20090702-1) unstable; urgency=low * New SVN snapshot. * rules: Remove duplicated files in sparc64-ieee1275 port. * rules: Comment out -DGRUB_ASSUME_LINUX_HAS_FB_SUPPORT=1 setting. We'll re-evaluate using it when it's more mature. (Closes: #535026). -- Robert Millan Thu, 02 Jul 2009 13:23:51 +0200 grub2 (1.96+20090629-1) unstable; urgency=low * New SVN snapshot. - Misc fixes in Linux loader. * control (grub-firmware-qemu): Make it buildable only on i386/amd64. * control: Add sparc (grub-ieee1275), remove remnants of ppc64. * rules: Include all modules in grub-firmware-qemu build. -- Robert Millan Mon, 29 Jun 2009 19:22:37 +0200 grub2 (1.96+20090628-1) unstable; urgency=low * New SVN snapshot. * Re-enable QEMU port. -- Robert Millan Sun, 28 Jun 2009 01:11:10 +0200 grub2 (1.96+20090627-2) unstable; urgency=low * Disable QEMU port untill it goes through NEW. * Upload to unstable. -- Robert Millan Sat, 27 Jun 2009 18:40:17 +0200 grub2 (1.96+20090627-1) experimental; urgency=low * New SVN snapshot. - Fix parsing of --output in grub-mkconfig. (Closes: #532956) [ Felix Zielcke ] * Use ucfr --force in grub-ieee1275.postinst in case we're upgrading from previous version. It registered /etc/default/grub wrongly with package iee1275. * Drop the build dependency on libc6-dev-i386. * Remove ppc64 from the Architectures. It's totally dead. * Add a note to /etc/default/grub that update-grub needs to be run to update grub.cfg. (Closes: #533026) * Fix the svn-snapshot rule. * Update Standards version to 3.8.2. No changes needed. [ Robert Millan ] * legacy/upgrade-from-grub-legacy: Invoke grub-pc.postinst directly rather than dpkg-reconfigure. Since we pretend we're upgrading, it will DTRT. * Add grub-firmware-qemu package. - patches/008_qemu.diff: QEMU port (patch from upstream). - control (grub-firmware-qemu): New package. - rules: Add grub-firmware-qemu targets. - debian/grub-firmware-qemu.dirs - debian/grub-firmware-qemu.install * patches/906_revert_to_linux16.diff: Remove, now that gfxpayload is supported. -- Robert Millan Sat, 27 Jun 2009 00:46:23 +0200 grub2 (1.96+20090611-1) experimental; urgency=low * New SVN snapshot. * Append .diff to patches/01_uuids_and_lvm_dont_play_along_nicely so it gets really applied. * Drop completely the build dependency on gcc-multilib. * Instead of arborting in the preinst if /etc/kernel-img.conf still contains /sbin/update-grub, change the file with sed. Policy allows thisi, because it's not a conffile, according to Colin Watson. * Change /etc/default/grub to an ucf managed file instead of dpkg conffile. -- Felix Zielcke Fri, 12 Jun 2009 11:46:24 +0200 grub2 (1.96+20090609-1) experimental; urgency=low * New SVN snapshot. - Fix variable parsing inside strings. (Closes: #486180) - Add `true' command. (Closes: #530736) [ Robert Millan ] * Split grub-efi in grub-efi-ia32 and grub-efi-amd64, both available on i386 and amd64. (Closes: #524756) * Add kopensolaris-i386 to arch list. [ Felix Zielcke ] * Add a NEWS entry about the grub-efi split. * Drop the build dependency on gcc-multilib for all *i386. * Change upgrade-from-grub-legacy to use `dpkg-reconfigure grub-pc' to install grub2 into MBR. [ New translations ] * Catalan (ca.po) by Jordi Mallach. [ Updated translations ] * Spanish (es.po) by Francisco Javier Cuadrado. (Closes: #532407) -- Jordi Mallach Tue, 09 Jun 2009 19:21:15 +0200 grub2 (1.96+20090603-1) unstable; urgency=low * New SVN snapshot. * Abort the install of grub-pc if /etc/kernel-img.conf still contains /sbin/update-grub (Closes: #500631). -- Felix Zielcke Wed, 03 Jun 2009 20:01:11 +0200 grub2 (1.96+20090602-1) unstable; urgency=low * New SVN snapshot. [ Felix Zielcke ] * Skip floopies in the grub-install debconf prompt in grub-pc postinst. Patch by Fabian Greffrath. (Closes: #530848) [ Robert Millan ] * Change Vcs-Browser field to viewsvn. [ Felix Zielcke ] * Change Vcs-Svn field to point to the trunk. (Closes: #531391) * patches/01_uuids_and_lvm_dont_play_along_nicely: New patch. On Debian root=UUID= with lvm still doestn't work so disable it. (Closes: #530357) * Remove Otavio Salvador from Uploaders with his permission. * add grub-pc.preinst -- Felix Zielcke Wed, 03 Jun 2009 14:42:11 +0200 grub2 (1.96+20090523-1) unstable; urgency=low * New SVN snapshot. - Add drivemap command, similar to grub-legacy's map command. (Closes: 503630) - Export GRUB_TERMINAL_INPUT in grub-mkconfig. (Closes: #526741) [ Robert Millan ] * rules: Set GRUB_ASSUME_LINUX_HAS_FB_SUPPORT=1 in CFLAGS. * patches/905_setup_force.diff: Relax blocklist warnings. * patches/906_revert_to_linux16.diff: Keep using linux16 for now. [ Felix Zielcke ] * patches/07_core_in_fs.diff: Updated. * Remove /etc/grub.d/10_hurd on non-Hurd systems in the grub-common preinst. Likewise for 10_freebsd for non kFreebsd and 10_linux on kFreebsd and Hurd. (Closes: #523777) -- Felix Zielcke Sat, 23 May 2009 20:05:10 +0200 grub2 (1.96+20090504-1) experimental; urgency=low * New SVN snapshot. - Add support for parttool command, which can be used to hide partitions. (Closes: #505905) - Fix a segfault with LVM on RAID. (Closes: #520637) - Add support for char devices on (k)FreeBSD. (Closes: #521292) - patches/08_powerpc-ieee1275_build_fix.patch: Remove (merged). [ Updated translations ] * Basque (eu.po) by Piarres Beobide. (Closes: #522457) * German (de.po) by Helge Kreutzmann. (Closes: #522815) [ Robert Millan ] * Update my email address. * Remove 04_uuids_and_abstraction_dont_play_along_nicely.diff now that bugs #435983 and #455746 in mdadm and dmsetup have been fixed. [ Felix Zielcke ] * Place new grub-dumpbios in grub-common. * Add lpia to the archictectures to reduce the ubuntu delta. * Add a manpage for the update-grub and update-grub2 stubs, written by me. (Closes: #523876) * Suggest genisoimage on grub-pc and grub-ieee1275, because grub-mkrescue needs it to create a cd image. (Closes: #525845) * Add a dependency on $(AUTOGEN_FILES) for the configure/grub-common target, this is needed now that upstream removed the autogenerated files from SVN. * Add `--enable-efiemu to' `./configure' flags. * Add a build dependency on gcc-multilib for i386. * Drop alternate build dependency on gcc-4.1 (<< 4.1.2). -- Felix Zielcke Mon, 04 May 2009 21:01:22 +0200 grub2 (1.96+20090402-1) experimental; urgency=low * New SVN snapshot. - Fix regression in disk/raid.c. (Closes: #521897, #514338) - Fix handling of filename string lengths in HFS. (Really closes: #516458). * Add myself to Uploaders. * Add patch 08_powerpc-ieee1275_build_fix.patch to fix powerpc-ieee1275 builds which were lacking header files for kernel_elf_HEADERS. Thanks Vladimir Serbinenko. -- Jordi Mallach Fri, 03 Apr 2009 20:58:37 +0200 grub2 (1.96+20090401-1) experimental; urgency=low [ Felix Zielcke ] * New SVN snapshot. - Pass grub's gfxterm mode to Linux kernel. (Closes: #519506) - Fix ext4 extents on powerpc. (Closes: #520286) [ Robert Millan ] * Remove grub-of transitional package (Lenny had grub-ieee1275 already). * Fix kopt parsing in grub-pc.config. Thanks Marcus Obst. (Closes: #514837) * Add debconf template to automatically run grub-install during upgrades (prior user confirmation). (Closes: #514705) -- Robert Millan Wed, 01 Apr 2009 01:19:45 +0200 grub2 (1.96+20090317-1) unstable; urgency=low * New SVN snapshot. - Fix loading of files with underscore in HFS. (Closes: #516458) * Update Standards version to 3.8.1. No changes needed. [ Updated translations ] * Brazilian Portuguese (pt_BR.po) by Flamarion Jorge. (Closes: #519417) -- Felix Zielcke Tue, 17 Mar 2009 14:42:10 +0100 grub2 (1.96+20090309-1) unstable; urgency=low * New SVN snapshot. -- Felix Zielcke Mon, 09 Mar 2009 10:03:13 +0100 grub2 (1.96+20090307-1) unstable; urgency=low * New SVN snapshot. - Add support for /dev/md/dNNpNN mdraid devices. (Closes: #509960) - Add new PF2 fontengine. (Closes: #510344) - Avoid mounting ext2 partitions with backward-incompatible features. (Closes: #502333) - Try to avoid false positives with FAT. (Closes: #514263) [ Felix Zielcke ] * Remove build-dependency on unifont package and add one for bf-utf-source package and libfreetype6-dev * grub-pc.postinst: Copy new ascii.pf2 instead of old ascii.pff to /boot/grub. * Add `--enable-grub-mkfont' to configure flags. * Put new grub-mkfont in grub-common package. * Add a dependency for ${misc:Depends} to all packages to make lintian a bit more happy. * Detect when grub-setup leaves core.img in filesystem, and include that info in bug report templates. - debian/patches/07_core_in_fs.diff - debian/script * Add myself to Uploads and add `DM-Upload-Allowed: yes' tag. [ Updated translations ] * Asturian (ast.po) by Marcos Alvarez Costales. (Closes: #511144) * Traditional Chinese (zh_TW.po) by Tetralet. (Closes: #513918) * Belarusian (be.po) by Pavel Piatruk. (Closes: #516243) -- Felix Zielcke Sat, 07 Mar 2009 11:54:43 +0100 grub2 (1.96+20081201-1) experimental; urgency=low * New SVN snapshot. -- Robert Millan Mon, 1 Dec 2008 00:07:31 +0100 grub2 (1.96+20081120-1) experimental; urgency=low * New SVN snapshot. * Update to new debian theme. - grub-pc.postinst: Switch to moreblue-orbit-grub.png. - grub.d/05_debian_theme: Likewise. * grub.d/05_debian_theme: - Update to use new grub-mkconfig_lib instead of the deprecated update-grub_lib. - Update to check if `GRUB_TERMINAL_OUTPUT' is `gfxterm' instead of `GRUB_TERMINAL'. [ Updated translations ] * Romanien (ro.po) by Eddy Petrișor. (Closes: #506039) -- Felix Zielcke Thu, 20 Nov 2008 20:25:56 +0100 grub2 (1.96+20081108-1) experimental; urgency=low * New SVN snapshot. - Add support for /dev/md/N style mdraid devices. (Closes: #475585) - Handle LVM dash escaping. (Closes: #464215) - Use case insensitive match in NTFS. (Closes: #497889) - Use hd%d drive names in grub-mkdevicemap for all architectures. (Closes: #465365) - Handle LVM circular metadata. (Closes: #462835, #502953) - Fix NULL dereference and failure paths in LVM. Thanks Guillem Jover. (Closes: #500482) - Provides GRUB header files (only in grub-common). [ Updated translations ] * Dutch (nl.po) by Paul Gevers. (Closes: #500514) * French (fr.po) by Christian Perrier. (Closes: #503708) * Georgian (ka.po) by Aiet Kolkhi. (Closes: #503715) * Czech (cs.po) by Miroslav Kure. (Closes: #503809) * German (de.po) by Helge Kreutzmann. (Closes: #503841) * Japanese (ja.po) by Hideki Yamane. (Closes: #503869) * Italian (it.po) by Luca Monducci. (Closes: #504076) * Swedish (sv.po) by Martin Ågren. (Closes: #504207) * Arabic (ar.po) by Ossama Khayat. (Closes: #504254) * Portuguese (pt.po) by Miguel Figueiredo. (Closes: #504280) * Russian (ru.po) by Yuri Kozlov. (Closes: #504324) * Finnish (fi.po) by Esko Arajärvi. (Closes: #504310) * Basque (eu.po) by Piarres Beobide. (Closes: #504466) * Dutch (nl.po) by Paul Gevers. (Closes: #504683) [ Felix Zielcke ] * patches/01_grub_legacy_0_based_partitions.diff: Rename to * patches/903_grub_legacy_0_based_partitions.diff: this and adapt for s/biosdisk.c/hostdisk.c/ rename upstream. * patches/03_disable_floppies.diff patches/904_disable_floppies.diff: Likewise. * update-grub has been renamed to grub-mkconfig, so provide a stub for compatibility. * Make grub-pc/linux_cmdline debconf template translatable. (Closes: #503478) * Remove ro.po and ta.po. They don't contain a single translated message. [ Robert Millan ] * control: Make grub-common dependency = ${binary:Version}. * default/grub: Set GRUB_CMDLINE_LINUX=quiet to syncronize with default D-I settings. -- Robert Millan Sat, 8 Nov 2008 13:54:10 +0100 grub2 (1.96+20080831-1) experimental; urgency=low * New SVN snapshot. - patches/00_fix_double_prefix.diff: Remove (merged). (Closes: #487565) - patches/00_getline.diff: Remove (merged). (Closes: #493289) - Handle errors in RAID/LVM scan routine (rather than letting the upper layer cope with them). (Closes: #494501, #495049) - patches/901_linux_coreboot.diff: Remove (replaced). - Add support for GFXMODE variable (Closes: #493106) - Skips /dev/.* in grub-probe. (Closes: #486624) - RAID code has various fixes. (Closes: #496573) - Buffered file read is now used to read the background image faster. (Closes: #490584) * We are already using LZMA, because upstream includes it's own lzma encoder, so drop completely the liblzo handling in control and rules files. [ Felix Zielcke ] * Remove the 1.95 partition numbering transition debconf warning from grub2 package and removed it from all languages (*.po). (Closes: #493744) * Add a comment for the new GFXMODE in default/grub. * debian/rules: - Remove 2 ./configure options which it didn't understand. - New grub-mkelfimage belongs to grub-common. * debian/control: - Change debhelper compat level to 7 and build depend on it >= 7. - Remove ${misc:Depend} dependency on all packages except grub-pc which is the only one using debconf. - Replace deprecated ${Source-Version} with ${source:Version} for << dependency and with ${build:Version} for = ones. - Remove versioned dependency of Build-Depends patchutils and cdbs, because etch has newer versions then the one used. - Remove dpkg-dev completely from Build-Depends because it's build-essentail and a non versioned dependency results in a lintian error. - Remove Conflict/Replaces pupa, it has been removed from Debian 2004. - Change build-dependency of unifont-bin to unifont (>= 1:5.1.20080820), it's the new package containing unifont.hex and that version to avoid licensing problems (Closes: #496061) - Remove Jason Thomas from Uploaders with his permission. * Preserve arguments in update-grub2 stub. (Closes: #496610) [ Updated translations ] * Japanese (ja.po) by Hideki Yamane (Closes: #493347) [ Robert Millan ] * Move a few files to grub-common and remove them from the arch- specific packages. * patches/02_old_linux_version_comparison.diff: Replace with ... * patches/901_dpkg_version_comparison.diff: ... this. Use dpkg --compare-versions in update-grub. (Closes: #494158) * patches/03_disable_floppies.diff: Free .drive struct member when skipping floppy drives. (Closes: #496040) * patches/902_boot_blocklist_hack.diff: Support separate /boot when using blocklists. (Closes: #496820, #489287, #494589) -- Robert Millan Sun, 31 Aug 2008 18:40:09 +0200 grub2 (1.96+20080730-1) experimental; urgency=low * New SVN snapshot. - patches/00_fix_overflow.diff: Remove (merged). - patches/00_uuid_boot.diff: Remove (merged). - patches/00_raid_duped_disks.diff: Remove (merged). - patches/00_xfs.diff: Remove (merged). - patches/00_strengthen_apple_partmap_check.diff: Remove (merged). - patches/00_skip_dev_dm.diff: Remove (merged). * patches/901_linux_coreboot.diff: Implements Linux load on Coreboot (patch from Coresystems). * grub-linuxbios -> grub-coreboot rename again. -- Robert Millan Wed, 30 Jul 2008 22:12:07 +0200 grub2 (1.96+20080724-4) unstable; urgency=high * patches/00_fix_overflow.diff: fix overflow with a big grub.cfg. (Closes: #473543) -- Felix Zielcke Tue, 29 Jul 2008 17:10:59 +0200 grub2 (1.96+20080724-3) unstable; urgency=low [ Felix Zielcke ] * changed dependency for debconf to also support debconf-2.0. (Closes: #492543) * patches/00_xfs.diff: Fix "out of partition" error with XFS. (Closes: #436943) [ Robert Millan ] * patches/00_raid_duped_disks.diff: Do not abort when two RAID disks with the same number are found. (Closes: #492656) * patches/00_strengthen_apple_partmap_check.diff: Be more strict when probing for Apple partition maps (this prevents false positives on i386-pc installs). (Closes: #475718) -- Robert Millan Tue, 29 Jul 2008 00:48:01 +0200 grub2 (1.96+20080724-2) unstable; urgency=high [ Felix Zielcke ] * fixed lintian override for kernel.elf * debian/rules: changed cvs targets to use svn [ Robert Millan ] * patches/00_skip_dev_dm.diff: Skip /dev/dm-[0-9] devices also (implicitly) for RAID. (Closes: #491977) * patches/00_uuid_boot.diff: Fix cross-disk installs by using UUIDs. (Closes: #492204) -- Robert Millan Sat, 26 Jul 2008 01:06:07 +0200 grub2 (1.96+20080724-1) unstable; urgency=high * New SVN snapshot. - Support for ext4dev extents. - patches/00_speed_up_font_load.diff: Remove (merged). [ Felix Zielcke ] * upgrade-from-grub-legacy now calls update-grub if grub.cfg doestn't exist and prints a big warning if it failed. * Update Standards version to 3.8.0. No changes need. * Added Build-Dep for po-debconf and a lintian override, to make it happy. [ Updated translations ] * Swedish (sv.po) by Martin Ågren (Closes: #492056) [ Robert Millan ] * Revert r844. grub-coreboot is stuck on NEW, and it was too early for branching. -- Robert Millan Thu, 24 Jul 2008 13:27:53 +0200 grub2 (1.96+20080717-1) experimental; urgency=low * New SVN snapshot. - Provides LZMA support (not yet used in the package). - Fix grub-mkrescue manpage generation. (Closes: #489440) * Rename grub-linuxbios to grub-coreboot (and leave a dummy grub-linuxbios package to handle upgrades). [ Updated translations ] * Spanish (es.po) by Maria Germana Oliveira Blazetic (Closes: #489877) * Portuguese (pt.po) by Ricardo Silva (Closes: #489807) -- Robert Millan Sat, 12 Jul 2008 17:47:09 +0200 grub2 (1.96+20080704-2) unstable; urgency=high * patches/02_old_linux_version_comparison.diff: Set interpreter to /bin/bash. (Closes: #489426, #489446) -- Robert Millan Mon, 7 Jul 2008 15:17:58 +0200 grub2 (1.96+20080704-1) unstable; urgency=high * New SVN snapshot. * default/grub: Add commented example to disable graphical terminal. * Use substvars to support linking with liblzo1. * Bring 03_disable_floppies.diff to pre-r805 state. (Closes: #488375) * patches/02_old_linux_version_comparison.diff: New patch. Steal version comparison code from GRUB Legacy's update-grub. (Closes: #464086, #489133) * patches/00_speed_up_font_load.diff: New patch. Generate font files with only the needed characters. (Closes: #476479, #477083) -- Robert Millan Fri, 4 Jul 2008 21:39:07 +0200 grub2 (1.96+20080626-1) unstable; urgency=high * New CVS snapshot. - Avoids passing UUID to Linux when not using initrd. (Closes: #484228) - patches/04_uuids_and_abstraction_dont_play_along_nicely.diff: Resync. -- Robert Millan Thu, 26 Jun 2008 16:43:48 +0200 grub2 (1.96+20080621-1) unstable; urgency=high * Urgency set to "high" because of #482688. * New CVS snapshot. - Fix module load hook in prepare_grub_to_access_device(). (Closes: #486804) - Call prepare_grub_to_access_device() before accessing devices, never afterwards. (Closes: #487198) * grub.d/05_debian_theme: Prefer /boot/grub over /usr for image loading, since chances are it's less LVMed. -- Robert Millan Sat, 21 Jun 2008 15:52:48 +0200 grub2 (1.96+20080617-1) unstable; urgency=low * New CVS snapshot. - Supports IDA block devices. (Closes: #483858) - Fixes some problems in ext2/ext3. (Closes: #485068, #485065) - Uses EUID instead of UID in update-grub. (Closes: #486043, #486039, #486040, #486041). - Fixes incomplete I2O device support. Thanks Sven Mueller. (Closes: #486505) - Fixes recent regressions in fs/ext2.c. (Closes: #485279) - Only use UUIDs when requested device is not the same as the one providing /boot. (Closes: #486119) - patches/02_libgcc_powerpc_hack.diff: Remove. Probably not needed anymore. - patches/04_uuids_and_abstraction_dont_play_along_nicely.diff: Update. * patches/06_olpc_prefix_hack.diff: Hardcode prefix to (sd,1) on OLPC. * Refurbish 03_disable_floppy_support_in_util_biosdisk.diff into 03_disable_floppies.diff. -- Robert Millan Tue, 17 Jun 2008 01:07:52 +0200 grub2 (1.96+20080601-2) unstable; urgency=low * 04_run_grub_mkdevicemap_when_grub_probe_fails.diff: Remove. Argueably makes grub-probe unreliable and is quite annoying. * 04_uuids_and_abstraction_dont_play_along_nicely.diff: New patch. Disable UUID parameter to Linux when LVM or dmRAID is in use. (Closes: #484228) This is a workaround for bug #484297 in udev. -- Robert Millan Tue, 3 Jun 2008 16:29:53 +0200 grub2 (1.96+20080601-1) unstable; urgency=low * New CVS snapshot. - patches/06_backward_compat_in_uuid_support.diff: Merged. - Fixes NULL pointer dereference in biosdisk.c. (Closes: #483895, #483900) - Extends UUID support for XFS and ReiserFS. -- Robert Millan Sun, 1 Jun 2008 15:44:08 +0200 grub2 (1.96+20080531-1) unstable; urgency=low * New CVS snapshot. - Work around BIOS bug affecting keyboard on macbooks. (Closes: #482860) - Adjust grub.d/05_debian_theme to use the new UUID-compatible API. - default/grub: Add commented GRUB_DISABLE_LINUX_UUID variable. - patches/06_backward_compat_in_uuid_support.diff: New. Make update-grub generate code that is compatible with older GRUB installs. - util/biosdisk.c no longer complains about duplicated device.map entries. (Closes: #481236) [ Updated translations ] * Galician (gl.po) by Jacobo Tarrio (Closes: #480977) -- Robert Millan Sat, 31 May 2008 00:02:54 +0200 grub2 (1.96+20080512-1) unstable; urgency=low * New CVS snapshot. - Adds support for default-only Linux cmdline options. (Closes: #460843) - Supports Xen virtual block devices. (Closes: #456777) - Supports Virtio block devices. (Closes: #479056) - Supports CCISS block devices. (Closes: #479735) - Fixes handling of more LVM abnormal conditions. (Closes: #474343, #474931, #477175) * Switch to liblzo2 now that it's GPLv3-compatible. (Closes: #466375) * grub-pc.postinst: Escape \ and / in cmdline sed invokation. (Closes: #479279) [ Updated translations ] * Italian (it.po) by Luca Monducci (Closes: #480740) -- Robert Millan Mon, 12 May 2008 17:46:38 +0200 grub2 (1.96+20080429-1) unstable; urgency=high * New CVS snapshot. - Includes sample grub.cfg file; we use it for grub-rescue-pc. (Closes: #478324) * grub-common: Upgrade Replaces to << 1.96+20080426-3. (Closes: #478224, #478353, #478144) [ Updated translations ] * French (fr.po) by Christian Perrier (Closes: #471291) -- Robert Millan Tue, 29 Apr 2008 13:27:52 +0200 grub2 (1.96+20080426-1) unstable; urgency=high * New CVS snapshot. - Fixes syntax error when setting GRUB_PRELOAD_MODULES. (Closes: #476517) * Move os-prober to Suggests, to avoid trouble with #476184. (Closes: #476684) * patches/04_run_grub_mkdevicemap_when_grub_probe_fails.diff: New patch, does what its name says. (Closes: #467127) - Also move grub-mkdevicemap from grub-pc to grub-common, so that GRUB Legacy can use it. [ Updated translations ] * Basque (eu.po) by Piarres Beobide (Closes: #476708) -- Robert Millan Sat, 26 Apr 2008 20:06:55 +0200 grub2 (1.96+20080413-1) unstable; urgency=high * New CVS snapshot. - Provides 30_os-prober update-grub add-on. Thanks Fabian Greffrath. (Closes: #461442) - Improves robustness when handling LVM. (Closes: #474931, #474343) * patches/03_disable_floppy_support_in_util_biosdisk.diff: New. Does what its name says. (Closes: #475177) -- Robert Millan Sun, 13 Apr 2008 13:53:28 +0200 grub2 (1.96+20080408-1) unstable; urgency=low * New CVS snapshot. - grub-probe skips non-existant devices when processing device.map. (Closes: #473209) * control: Fix syntax error. [ Updated translations ] * Finnish (fi.po) by Esko Arajärvi (Closes: #468641) -- Robert Millan Tue, 8 Apr 2008 15:45:25 +0200 grub2 (1.96+20080228-1) unstable; urgency=low * New CVS snapshot. * Split grub-probe into grub-common package. Make all flavours depend on it. (Closes: #241972) * Suggest multiboot-doc. * patches/01_grub_legacy_0_based_partitions.diff: New patch. Add a hack that tells grub-probe you want 0-based partition count (GRUB_LEGACY_0_BASED_PARTITIONS variable) * Stop depending on lsb-release (too heavy! we don't need python in base). Instead of assuming it's there, try calling it and otherwise just echo Debian. -- Robert Millan Thu, 28 Feb 2008 16:43:40 +0100 grub2 (1.96+20080219-3) unstable; urgency=low * default/grub: Use lsb_release to support Debian derivatives. (Closes: #466561) * grub.d/05_debian_theme: Only setup background image when a reader for it is present in /boot/grub. (Closes: #467111) [ Updated translations ] * Russian (ru.po) by Yuri Kozlov (Closes: #467181) -- Robert Millan Sun, 24 Feb 2008 15:39:50 +0100 grub2 (1.96+20080219-2) unstable; urgency=high * grub-pc.postinst: Create /boot/grub if it doesn't exist. -- Robert Millan Wed, 20 Feb 2008 07:15:14 +0100 grub2 (1.96+20080219-1) unstable; urgency=high * New CVS snapshot. - Improves GPT support, allowing it to work without blocklists. -- Robert Millan Tue, 19 Feb 2008 15:05:10 +0100 grub2 (1.96+20080216-1) unstable; urgency=high * New CVS snapshot. - Fixes offset calculation issue when installing on GPT (urgency set to high because of this). * Fix Vcs-Browser tag. Thanks James. (Closes: #465697) * Only process grub-pc/linux_cmdline if /boot/grub/menu.lst exists. (Closes: #465708) [ Updated translations ] * French (fr.po) by Christian Perrier (Closes: #465706) -- Robert Millan Sat, 16 Feb 2008 23:30:55 +0100 grub2 (1.96+20080213-1) unstable; urgency=low * New CVS snapshot. - Failure to read one device in a RAID-1 array no longer causes boot to fail (so long as there's a member that works). (Closes: #426341) * script: For /proc/mounts, only report lines that start with /dev/. * Add new upgrade-from-grub-legacy script for the user to complete the upgrade process from GRUB Legacy, and advertise it prominently in menu.lst. (Closes: #464912) * Add a hack to support gfxterm / background_image on systems where /usr isn't accessible. (Closes: #464911, #463144) - grub-pc.postinst - grub.d/05_debian_theme * Fix a pair of spelling mistakes in debconf. (Closes: #465296) * Migrate kopt from menu.lst. (Closes: #461164, #464918) [ Updated translations ] * Portuguese (pt.po) by Ricardo Silva (Closes: #465137) * German (de.po) by Helge Kreutzmann (Closes: #465295) -- Robert Millan Wed, 13 Feb 2008 16:37:13 +0100 grub2 (1.96+20080210-1) unstable; urgency=high * New CVS snapshot. - Errors that cause GRUB to enter rescue mode are displayed now. (Closes: #425149) - Build LVM/RAID modules into a few commands that were missing them (notably, grub-setup). (Closes: #465033) * Fix license violation (incompatibility between GRUB and LZO2). (Closes: #465056) - Urgency set to high. - control: Move liblzo2-dev from Build-Depends to Build-Conflicts (leaving liblzo-dev as the only option). -- Robert Millan Sun, 10 Feb 2008 17:09:15 +0100 grub2 (1.96+20080209-1) unstable; urgency=low * New CVS snapshot. - Fix a root device setting issue in grub-setup. (Closes: #463391) - Fix partmap detection under LVM/RAID. - Add scripting commands that would allow user to implement hiddenmenu-like functionality (http://grub.enbug.org/Hiddenmenu). - Provide manpages for grub-setup, grub-emu, grub-mkimage and others. (Closes: #333516, #372890) * Fix a pair of spelling errors in debconf templates. Thanks Christian Perrier. (Closes: #464133) * Run debconf-updatepo. (Closes: #463918) * Lower base-files versioned dependency to >= 4.0.1~bpo40+1. -- Robert Millan Sat, 9 Feb 2008 13:43:49 +0100 grub2 (1.96+20080203-1) unstable; urgency=low * New CVS snapshot (and release, but we skipped that ;-)) - patches/01_regparm.diff: Delete. - Improved XFS support. - util/grub.d/00_header.in: Add runtime error detection (for gfxterm). - Fixes problem when chainloading to Vista. * Fix po-debconf errors. Thanks Thomas Huriaux. (Closes: #402972) * grub.d/05_debian_theme: - Add runtime error detection. - Detect/Enable PNG background when it is present. * control (grub-ieee1275): Remove versioned dependency on powerpc-ibm-utils. -- Robert Millan Sun, 3 Feb 2008 19:31:23 +0100 grub2 (1.95+20080201-1) unstable; urgency=low * New CVS snapshot. * presubj: Improve notice. * patches/01_regparm.diff: Fix CPU context corruption affecting fs/xfs.c. (Closes: #463081, #419766, #462159) * patches/02_libgcc_powerpc_hack.diff: Fix FTBFS on powerpc. (Closes: #457491) * patches/disable_xfs.diff: Actually remove this time... -- Robert Millan Fri, 1 Feb 2008 17:06:00 +0100 grub2 (1.95+20080128-1) unstable; urgency=low * New CVS snapshot. - Fixes bogus CLAIM problems on Apple firmware. (Closes: #449135, #422729) - grub-probe performs sanity checks to make sure our filesystem drivers are usable. (Closes: #462449) - patches/disable_ata.diff: Remove. ATA module isn't auto-loaded in rescue floppies now. - patches/disable_xfs.diff: Remove. See above (about grub-probe). * Bring back grub-emu; it can help a lot with debugging feedback. - control - rules -- Robert Millan Mon, 28 Jan 2008 00:01:11 +0100 grub2 (1.95+20080116-2) unstable; urgency=low * grub.d/05_debian_theme: Enable swirlish beauty. * rules: Obtain debian/legacy/update-grub dynamicaly from GRUB Legacy svn. -- Robert Millan Sat, 19 Jan 2008 13:16:18 +0100 grub2 (1.95+20080116-1) unstable; urgency=low * New CVS snapshot. - update-grub ignores stale *.dpkg-* files. (Closes: #422708, #424223) - LVM/RAID now working properly (except when it affects /boot). (Closes: #425666) - Fixes flickery in timeout message. (Closes: #437275) * grub-pc.postinst: Use `--no-floppy' whenever possible. Die, floppies, die! * Resync with latest version of GRUB Legacy's update-grub. This time, using the $LET_US_TRY_GRUB_2 hack to reuse the same script both for addition of core.img and its removal. * grub-*.install: Add update-grub2 stub. Packages providing /etc/grub.d/ scripts should invoke update-grub2 in both postinst and postrm (whenever it is found, of course). * control: Reorganize a bit, including a complete rewrite of the package descriptions. * control (grub-ieee1275): Enable for i386/amd64. -- Robert Millan Wed, 16 Jan 2008 15:00:54 +0100 grub2 (1.95+20080107-1) unstable; urgency=low * New CVS snapshot. - Supports ReiserFS. (Closes: #430742) - patches/disable_ata.diff: Resync. -- Robert Millan Mon, 7 Jan 2008 12:46:39 +0100 grub2 (1.95+20080105-2) unstable; urgency=low * grub-pc.postinst: Fix covered assumption that menu.lst exists. (Closes: #459247) * copyright: Fix copyright/license reference. -- Robert Millan Sun, 6 Jan 2008 18:02:28 +0100 grub2 (1.95+20080105-1) unstable; urgency=low * New CVS snapshot. - Fixes install on non-devfs systems with devfs-style paths (ouch). (Closes: #450709). - Fixes boot of "Linux" zImages (including memtest86+). (Closes: #436113). - Corrects usage message in grub-setup. (Closes: #458600). - patches/menu_color.diff: Remove. Made obsolete by `menu_color_normal' and `menu_color_highlight' variables. Add/install grub.d/05_debian_theme to make use of them. * Reestructure grub-pc.postinst. Notably: - Do not touch menu.lst unless user has confirmed it (via debconf). (Closes: #459247) - When we do, keep a backup in /boot/grub/menu.lst_backup_by_grub2_postinst. -- Robert Millan Sat, 5 Jan 2008 17:55:37 +0100 grub2 (1.95+20080101-1) unstable; urgency=low * New CVS snapshot. - patches/disable_xfs.diff: Rewrite in a way that won't collide with upstream changes so often. - unifont.hex now processed by upstream. - rules: Disable build of unifont.pff. - *.install: Remove build/unifont.pff line. - patches/menu_color.diff: Change menu color to our traditional blue theme. * Support new dpkg fields (Homepage, Vcs-Svn, Vcs-Browser). * patches/disable_ata.diff: Prevent ATA module from being built on i386-pc. -- Robert Millan Tue, 1 Jan 2008 19:45:30 +0100 grub2 (1.95+20071101-1) unstable; urgency=low * New CVS snapshot. - patches/linuxbios.diff: Remove (supported in upstream now). -- Robert Millan Thu, 1 Nov 2007 13:18:51 +0100 grub2 (1.95+20071004-2) unstable; urgency=low * Rename debian/grub-of.* to debian/grub-ieee1275.*. * Add debian/grub-linuxbios.{postinst,dirs,install}. * rules: Fix/Overrride lintian warnings (unstripped-binary-or-object). * Remove grub-linuxbios.postinst. -- Robert Millan Wed, 10 Oct 2007 23:56:35 +0200 grub2 (1.95+20071004-1) unstable; urgency=low * New CVS snapshot. * Add grub-linuxbios package. - patches/linuxbios.diff - control - rules * Rename grub-of to grub-ieee1275 to match with upstream conventions. - control - rules -- Robert Millan Thu, 4 Oct 2007 14:42:30 +0200 grub2 (1.95+20070829-1) unstable; urgency=low * New CVS snapshot. - Includes fix for parallel builds. * rules: Append -j flag to $(MAKE) to take advantage of >1 processors. * Add reference to /usr/share/common-licenses. - debian/copyright - debian/control (all packages): Add base-files (>= 4.0.1) dependency. -- Robert Millan Sat, 1 Sep 2007 19:00:22 +0200 grub2 (1.95+20070828-2) unstable; urgency=low * control (grub-of): Make depends on powerpc-ibm-utils versioned as >= 1.0.6 (older versions don't have -a flag). -- Robert Millan Tue, 28 Aug 2007 23:32:32 +0200 grub2 (1.95+20070828-1) unstable; urgency=low * New CVS snapshot. - Adds ntfs support. - Fixes a pair of issues indirectly breaking grub-probe on powerpc. (Closes: #431488) - patches/disable_xfs.diff: Resync. - copyright: License upgraded to GPLv3. * control (grub-of Depends): Add powerpc-utils (for nvsetenv) and bc. -- Robert Millan Tue, 28 Aug 2007 21:24:14 +0200 grub2 (1.95+20070626-1) unstable; urgency=low * New CVS snapshot. - More fixes to cope with unreadable /. (Closes: #427289) - update-grub supports multiple terminals. * control (Build-Depends): Add genisoimage. * patches/partmap_fallback.diff: Remove. It didn't archieve anything as it also needs support for proper identification of raid / lvm (this is being worked on). * patches/disable_xfs.diff: Disable xfs in grub-probe. * grub-rescue-pc.README.Debian: New. Explain how to use the rescue images. -- Robert Millan Tue, 26 Jun 2007 08:39:14 +0200 grub2 (1.95+20070614-1) unstable; urgency=low * New CVS snapshot. - update-grub is tollerant to unreadable / (as long as /boot is accessible). (Closes: #427289) * grub-pc.postinst: Generate new grub.cfg when menu.lst exists. * New package grub-rescue-pc. - control: Add it. - README.Debian.in: Remove obsolete documentation. - rules: Build rescue images using grub-mkrescue. - grub-rescue-pc.dirs: Prepare their directory. - grub-rescue-pc.install: Install them. * legacy/update-grub: Fix core.img detection on separate /boot. -- Robert Millan Thu, 14 Jun 2007 08:17:21 +0200 grub2 (1.95+20070604-1) unstable; urgency=low * New CVS snapshot. - patches/grub_probe_for_everyone.diff: Remove (merged). - update-grub exports user-defined GRUB_CMDLINE_LINUX. (Closes: #425453) - Fix those nasty powerpc bugs. (Closes: #422729) -- Robert Millan Mon, 4 Jun 2007 21:30:55 +0200 grub2 (1.95+20070520-1) unstable; urgency=low * New CVS snapshot. - LVM / RAID fixes. (Closes: #423648, #381150) - Fix memory management bug. (Closes: #423409) - patches/efi.diff: Remove (merged). - patches/grub_probe_for_everyone.diff: Use the new paths for util/grub-probe.c, util/biosdisk.c, util/getroot.c. Enable grub-mkdevicemap. (Closes: #424985) * legacy/update-grub: Get rid of all grub-set-default calls. (Closes: #425054) * grub-{pc,efi,of}.postinst: Only run update-grub if grub.cfg already exists. * grub-pc.postinst: Only run GRUB Legacy compat stuff if menu.lst is found. * patches/partmap_fallback.diff: New. Implement fallback "pc gpt" for partmap detection failures. (Closes: #423022) * control: Update XS-Vcs-* fields. Thanks Sam Morris . (Closes: #425146) * grub-{pc,efi,of}.{dirs,postinst}: Move unifont.pff to /usr/share/grub. -- Robert Millan Sun, 20 May 2007 11:13:03 +0200 grub2 (1.95+20070515-1) unstable; urgency=low * New CVS snapshot. - Fix assumptions about /, /boot and /boot/grub being the same device. (Closes: #423268, #422459) - Proper sorting of Linux images. (Closes: #422580) - update-grub lets /etc/default/grub override its variables now. (Closes: #423649) - update-grub mentions /etc/default/grub in the grub.cfg header. (Closes: #423651) - update-grub sets 800x600x16 as the default gfxmode. (Closes: #422794) - update-grub runs grub-mkdevicemap before attempting to use grub-probe (part of #423217) [ Otavio Salvador ] * Add support to DEB_BUILD_OPTIONS=noopt. Thanks to Sam Morris for the patch. (Closes: #423005) * Add Robert Millan as uploader. * Change build-dependency from liblzo-dev to liblzo2-dev. (Closes: #423358) [ Robert Millan ] * grub-pc.postinst: - Remove /boot/grub/device.map before running grub-install. (Closes: #422851) - Always run update-grub after grub-install. (part of #423217) - Use grub-mkdevicemap instead of removing device.map, since update-grub needs it but grub-install is not run unconditionaly. - Redirect grub-install invocation to /dev/null, since it can mislead users into thinking that MBR was overwritten. (part of #423217) * default/grub: Stop exporting the variables (update-grub does that now). * Misc EFI fixes, including new grub-install. - patches/efi.diff: New. - patches/grub_probe_for_everyone.diff: Move some bits to efi.diff. - grub-efi.install: Stop installing dummy grub-install. - grub-install: Remove. * grub-pc.postinst: Avoid generating core.img when menu.lst is not present, to avoid duplicated work (this is specialy important for d-i). (part of #423217). * See multiple references above. (Closes: #423217) * grub-{pc,efi,of}.{dirs,install}: Install presubj in the right directory to make it work again (oops). * Add reportbug script to gather debugging information. (Closes: #423218) - script: New. - grub-{pc,efi,of}.install: Install it. * Install the reportbug scripts for grub2 too, since users might still use it for bugfiling. - grub2.dirs - grub2.install * Fix some lintian warnings. - control (grub2): Depend on debconf. - README.Debian.in: Fix mispell. - grub2.templates: Remove extra dot. -- Robert Millan Tue, 15 May 2007 22:08:53 +0200 grub2 (1.95+20070507-1) unstable; urgency=low [ Robert Millan ] * New CVS snapshot. - patches/build_neq_src.diff: Remove (merged). * Fix debhelper files to ensure each package gets the right thing. * Enable gfxterm/unifont support. * On grub-pc, if there's no core.img setup, create one (but do not risk writing to MBR). * On grub-pc, if menu.lst is found, regenerate it to include our core.img. [ Otavio Salvador ] * Move debian/update-grub to debian/legacy/update-grub otherwise the source gets messy. -- Otavio Salvador Mon, 07 May 2007 18:48:14 -0300 grub2 (1.95+20070505.1-3) unstable; urgency=low * Split postinst into grub2.postinst (with the transition warning) and postinst.in, with update-grub invocation for grub-{pc,efi,of}. - postinst.in - grub2.postinst - rules -- Robert Millan Sun, 6 May 2007 01:20:04 +0200 grub2 (1.95+20070505.1-2) unstable; urgency=low * Add EFI build of GRUB. - control: Restructure to provide 3 packages: grub-pc (x86), grub-efi (x86) and grub-of (powerpc). - rules: Handle a separate build for each package. - patches/build_neq_src.diff: Fix builddir == srcdir assumptions. - patches/grub_probe_for_everyone.diff: New (superceds powerpc_probe.diff). Enable grub-probe on powerpc and i386-efi. - grub-install: Dummy informational grub-install for EFI. - grub-efi.install: Installs it. -- Robert Millan Sun, 6 May 2007 00:23:56 +0200 grub2 (1.95+20070505.1-1) unstable; urgency=low * New CVS snapshot. * patches/powerpc_probe.diff: Add partmap/gpt.c to grub-probe. * control (Architecture): Temporarily disable powerpc. Sorry, but runtime is currently broken and we don't have the hardware to debug it. Will be re-enabled in next upload. -- Robert Millan Sat, 5 May 2007 21:52:49 +0200 grub2 (1.95+20070505-1) unstable; urgency=low * New CVS snapshot. - Improved grub.cfg parser. (Closes: #381215) - patches/fix-grub-install.diff: Remove (merged). - control (Build-Depends): Remove libncurses5-dev (no longer needed). - provides update-grub2. (Closes: #419151) - Supports GPT in PC/BIOS systems. (Closes: #409073) * control (Build-Depends): Add gcc-multilib to fix FTBFS. * control (Description): Make it less scary, and more informative. * postinst: Run update-grub to ensure the latest improvements always are applied. * patches/powerpc_probe.diff: Attempt at making grub-probe build/install on powerpc (and hopefuly update-grub). -- Robert Millan Sat, 5 May 2007 01:49:07 +0200 grub2 (1.95-5) unstable; urgency=low * Fix FTBFS on kFreeBSD. Thanks to Aurelien Jarno by providing the patch. Closes: #416408 -- Otavio Salvador Fri, 30 Mar 2007 19:20:48 -0300 grub2 (1.95-4) unstable; urgency=low * Fix powerpc grub-install binary path. Closes: #402838 -- Otavio Salvador Thu, 22 Mar 2007 23:45:56 -0300 grub2 (1.95-3) unstable; urgency=low [ Christian Perrier ] * Switch to po-debconf for debconf templates. Closes: #402972 * Depend on ${misc:Depends} and not "debconf" to allow cdebconf to be used * Debconf translations: - French - Czech. Closes: #413327 - Galician. Closes: #413323 - Swedish. Closes: #413325 - Portuguese. Closes: #413332 - German. Closes: #413365 - Tamil. Closes: #413478 - Russian. Closes: #413542 - Italian. Closes: #413904 - Romanian. Closes: #414443 -- Otavio Salvador Tue, 20 Mar 2007 23:46:38 -0300 grub2 (1.95-2) unstable; urgency=low [ Robert Millan ] * update-grub: Fix for Xen hypervisor entries, thanks Aaron Schrab. (Closes: #394706) * Transition to new numbering scheme for partitions. (Closes: #395019) - update-grub: Don't substract 1 when converting partition device names to grub drives. - Add debconf warning explaining the situation. * Rewrite Architecture line back to hardcoded list :(. (Closes: #398060) -- Otavio Salvador Mon, 11 Dec 2006 05:08:41 -0200 grub2 (1.95-1) unstable; urgency=low * New upstream release. - patches/03_revert_partition_numbering.diff: Delete (obsoleted). -- Robert Millan Sat, 14 Oct 2006 21:19:21 +0200 grub2 (1.94+20061003-1) unstable; urgency=high * New CVS snapshot. [ Otavio Salvador ] * Change debhelper compatibility mode to 5: - debian/compat: setted to 5; * control (Build-Depends): Add lib32ncurses5-dev for ppc64. Closes: #389873 * Set urgency=high since it's experimental stuff and tagged likewise. It also solved a serious bug on PowerPC that leave users with a black screen. [ Robert Millan ] * control (Depends): Add powerpc-ibm-utils for powerpc/ppc64. (Closes: #372186) -- Otavio Salvador Tue, 3 Oct 2006 16:49:32 -0300 grub2 (1.94+20060926-1) unstable; urgency=high * New CVS snapshot. - Command-line editting fix (Closes: #381214). - Fixes runtime breakage on amd64 (not in BTS). - Delete a few patches (merged). [ Robert Millan ] * Set urgency=high. Might seem like a rush, but it can't possibly be worse than 1.94-5 (broken on systems that use udev, broken on amd64...). * Pure ppc64 support. - control (Architecture): Add any-ppc64. - control (Build-Depends): Add libc6-dev-powerpc [ppc64]. * rules: Remove moddep.lst install command (no longer needed). * patches/03_revert_partition_numbering.diff: New. Revert a commit that broke grub-probefs. * Add bug template to encourage sending upstream stuff directly to upstream. - presubj: New. [ Otavio Salvador ] * Add XS-X-Vcs-Svn on control file and point it to our current svn repository. * Add cvs-snapshot to rules. -- Otavio Salvador Tue, 26 Sep 2006 16:14:36 -0300 grub2 (1.94-6) unstable; urgency=low [ Robert Millan ] * update-grub: Set interpreter to /bin/bash to cope with non-POSIX extensions. (mentioned in #361929) * patches/03_avoid_recursing_into_dot_static.diff: New. Avoid recursing into dotdirs (e.g. ".static"). * patches/04_mkdevicemap_dont_assume_floppies.diff: New. Don't assume /dev/fd0 exists when generating device.map. -- Otavio Salvador Thu, 14 Sep 2006 16:07:30 -0300 grub2 (1.94-5) unstable; urgency=low [ Robert Millan ] * control (Build-Depends): s/any-amd64/amd64 kfreebsd-amd64/g (this seems to confuse buildds). * 02_not_remove_menu_lst.patch: New patch. Skip menu.lst removal in grub-install. (Closes: #372934) -- Otavio Salvador Sun, 20 Aug 2006 12:02:13 -0300 grub2 (1.94-4) unstable; urgency=low [ Otavio Salvador ] * 01_fix_amd64_building.patch: dropped since it now supports amd64 native building. * Remove convert_kernel26 usage since it's not necessary anymore and due initramfs-tools changes it's bug too. [ Robert Millan ] * Fork update-grub from grub legacy, and tweak a few commands in output to make it work for grub2. * Update README.Debian.in with more recent (and easier) install instructions. * Add grub to Conflicts/Replaces. Too many commands with the same name, even if they don't use the same path yet (but will likely do in the future, see #361929). * Get rid of control.in, which I introduced in 0.6+20040805-1 and turned out to be an endless source of problems (and forbidden by policy as well). * Fix FTBFS on amd64. Really closes: #372548. -- Otavio Salvador Fri, 18 Aug 2006 15:38:25 -0300 grub2 (1.94-3) unstable; urgency=low * Fix FTBFS in amd64. Closes: 372548 -- Otavio Salvador Sat, 10 Jun 2006 19:57:01 -0300 grub2 (1.94-2) unstable; urgency=low * Update grub images paths in README.Debian * 01_fix_grub-install.patch: add to fix a problem with PowerPC installation. Refs: #371069 * Fix FTBFS in amd64. Closes: #370803 -- Otavio Salvador Fri, 9 Jun 2006 09:29:40 -0300 grub2 (1.94-1) unstable; urgency=low * New upstream release. - Fix powerpc building. Closes: #370259 - 01_fix_grub-install.patch: merged upstream. - Moved modules to /usr/lib/grub since they are architecture dependent. * Leave CDBS set debhelper compatibility level. * Allow amd64 build to happen. Closes: #364956 * Enforce building in 32bits while running in x86_64 machines. * Update Standards version to 3.7.2. No changes need. -- Otavio Salvador Mon, 5 Jun 2006 12:49:09 -0300 grub2 (1.93-1) unstable; urgency=low * New upstream release. - Added support to PowerPC. Closes: #357853 - 01_fix_grub-install.patch: rediff. * Update Standards version to 3.6.2. No changes need. * Start to use new dpkg architecture definition. Closes: #360134 -- Otavio Salvador Sat, 1 Apr 2006 10:07:17 -0300 grub2 (1.92-2) unstable; urgency=low * Add bison on build-depends field. Closes: #346178 * Add more fixes in 01_fix_grub-install.patch. Closes: #346177 -- Otavio Salvador Fri, 6 Jan 2006 09:48:08 -0200 grub2 (1.92-1) unstable; urgency=low * New upstream release. - Add support for GPT partition table format. - Add a new command "play" to play an audio file on PC. - Add support for Linux/ADFS partition table format. - Add support for BASH-like scripting. - Add support for Apple HFS+ filesystems. * 01_fix_grub-install.patch: Added. Fix grub-install to use /bin/grub-mkimage instead of /sbin/grub-mkimage. Closes: #338824 * Do not use CDBS tarball mode anymore. Closes: #344272 -- Otavio Salvador Thu, 5 Jan 2006 15:20:40 -0200 grub2 (1.91-0) unstable; urgency=low * New upstream release. Closes: #331211 * debian/watch: added. * debian/control.in, debian/control: Add libncurses5-dev in Build-Depends. Closes: #304638 * Remove Robert Millan as uploader; * Add myself as uploader; -- Otavio Salvador Sat, 12 Nov 2005 16:35:18 -0200 grub2 (0.6+20050203-2) unstable; urgency=low * Disable for powerpc. Reportedly it fails to boot. -- Robert Millan Fri, 4 Feb 2005 01:52:09 +0100 grub2 (0.6+20050203-1) unstable; urgency=low * New upstream snapshot. * Install moddep.lst properly in a cpu-independant way. (Closes: #264115) * Use cdbs debian/control autogeneration. - Set DEB_AUTO_UPDATE_DEBIAN_CONTROL = yes. - Move control to control.in. - Add a @cdbs@ tag and replace Architecture with Cpu/System. * control.in (Build-Depends): Add ruby. -- Robert Millan Thu, 3 Feb 2005 22:33:39 +0100 grub2 (0.6+20040805-1) unstable; urgency=low * New upstream snapshot. * Uploading to unstable so that powerpc users can be blessed by GRUB too. * Use type-handling to generate dpkg arch list. - control.in - rules -- Robert Millan Thu, 5 Aug 2004 20:50:16 +0200 grub2 (0.6+20040502-1) experimental; urgency=low * New upstream snapshot. - Fix FTBFS on powerpc. -- Robert Millan Sun, 2 May 2004 18:16:29 +0200 grub2 (0.6+20040429-1) experimental; urgency=low * New upstream snapshot. - control (Architecture): Add powerpc. -- Robert Millan Thu, 29 Apr 2004 20:41:31 +0200 grub2 (0.6+20031125-1) experimental; urgency=low * New upstream snapshot. - patches/multiboot.diff: Nuked. - install,docs: Update directory name. * control (Maintainer): Set to pkg-grub-devel mailing list. * control (Uploaders): Add myself. * control (Architecture): Add freebsd-i386 and netbsd-i386. -- Robert Millan Tue, 25 Nov 2003 23:48:18 +0100 grub2 (0.6+20031114-1) experimental; urgency=low * New upstream snapshot. - README.Debian: s/fat/ext2/g (We now have ext2fs support). * Add multiboot support, thanks to Jeroen Dekkers for his patch. - patches/multiboot.diff: New. - control (Architecture): Add hurd-i386 (which needed multiboot). * Rename package to grub2 (to follow upstream tendency). - control: Ditto. - README.Debian: Likewise. * Switch to tarball mode. - rules: Ditto. - docs: Prefix paths in order to workaround dh_installdocs bug. - install: Likewise, but not because of bug (should be in rules, actualy). * Fix FTBFS. (Closes: #213868) - control (Build-Depends): Add autoconf. - control (Build-Conflicts): Add autoconf2.13. -- Robert Millan Fri, 14 Nov 2003 13:16:12 +0100 pupa (0.6+20031008-1) experimental; urgency=low * New upstream snapshot. * Uploading to experimental. * debian/control: Add Jason Thomas to Uploaders. -- Robert Millan Wed, 8 Oct 2003 13:22:50 +0000 pupa (0.6+20030915-1) unstable; urgency=low * Initial Release. (Closes: #211030) -- Robert Millan Mon, 15 Sep 2003 14:58:42 +0000 debian/grub-pc-dbg.install.in0000664000000000000000000000004412524662415013263 0ustar usr/lib/grub/@CPU_PLATFORM@/*.image debian/grub-coreboot-bin.install.amd64.in0000664000000000000000000000004612524662415015425 0ustar usr/lib/grub/@CPU_PLATFORM@/efiemu*.o debian/grub.d/0000775000000000000000000000000012524676037010365 5ustar debian/grub.d/05_debian_theme0000775000000000000000000001365212524662415013225 0ustar #!/bin/sh set -e # grub-mkconfig helper script. # Copyright (C) 2010 Alexander Kurtz # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # GRUB is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GRUB. If not, see . # Include the GRUB helper library for grub-mkconfig. . /usr/share/grub/grub-mkconfig_lib # We want to work in /boot/grub/ only. test -d /boot/grub; cd /boot/grub # Set the location of a possibly necessary cache file for the background image. # NOTE: This MUST BE A DOTFILE to avoid confusing it with user-defined images. BACKGROUND_CACHE=".background_cache" set_default_theme(){ case $GRUB_DISTRIBUTOR in Tanglu|Ubuntu|Kubuntu) # Set a monochromatic theme for Tanglu/Ubuntu. echo "${1}set menu_color_normal=white/black" echo "${1}set menu_color_highlight=black/light-gray" if [ -e /lib/plymouth/themes/default.grub ]; then sed "s/^/${1}/" /lib/plymouth/themes/default.grub fi ;; *) # Set the traditional Debian blue theme. echo "${1}set menu_color_normal=cyan/blue" echo "${1}set menu_color_highlight=white/blue" ;; esac } module_available(){ local module for module in "${1}.mod" */"${1}.mod"; do if [ -f "${module}" ]; then return 0 fi done return 1 } set_background_image(){ # Step #1: Search all available output modes ... local output for output in ${GRUB_TERMINAL_OUTPUT}; do if [ "x$output" = "xgfxterm" ]; then break fi done # ... and check if we are able to display a background image at all. if ! [ "x${output}" = "xgfxterm" ]; then return 1 fi # Step #2: Check if the specified background image exists. if ! [ -f "${1}" ]; then return 2 fi # Step #3: Search the correct GRUB module for our background image. local reader case "${1}" in *.jpg|*.JPG|*.jpeg|*.JPEG) reader="jpeg";; *.png|*.PNG) reader="png";; *.tga|*.TGA) reader="tga";; *) return 3;; # Unknown image type. esac # Step #4: Check if the necessary GRUB module is available. if ! module_available "${reader}"; then return 4 fi # Step #5: Check if GRUB can read the background image directly. # If so, we can remove the cache file (if any). Otherwise the backgound # image needs to be cached under /boot/grub/. if is_path_readable_by_grub "${1}"; then rm --force "${BACKGROUND_CACHE}.jpeg" \ "${BACKGROUND_CACHE}.png" "${BACKGROUND_CACHE}.tga" elif cp "${1}" "${BACKGROUND_CACHE}.${reader}"; then set -- "${BACKGROUND_CACHE}.${reader}" "${2}" "${3}" else return 5 fi # Step #6: Prepare GRUB to read the background image. if ! prepare_grub_to_access_device "`${grub_probe} --target=device "${1}"`"; then return 6 fi # Step #7: Everything went fine, print out a message to stderr ... echo "Found background image: ${1}" >&2 # ... and write our configuration snippet to stdout. Use the colors # desktop-base specified. If we're using a user-defined background, use # the default colors since we've got no idea how the image looks like. # If loading the background image fails, use the default theme. echo "insmod ${reader}" echo "if background_image `make_system_path_relative_to_its_root "${1}"`; then" if [ -n "${2}" ]; then echo " set color_normal=${2}" fi if [ -n "${3}" ]; then echo " set color_highlight=${3}" fi if [ -z "${2}" ] && [ -z "${3}" ]; then echo " true" fi echo "else" set_default_theme " " echo "fi" } # Earlier versions of grub-pc copied the default background image to /boot/grub # during postinst. Remove those obsolete images if they haven't been touched by # the user. They are still available under /usr/share/images/desktop-base/ if # desktop-base is installed. while read checksum background; do if [ -f "${background}" ] && [ "x`sha1sum "${background}"`" = "x${checksum} ${background}" ]; then echo "Removing old background image: ${background}" >&2 rm "${background}" fi done <&2 cp /boot/grub/menu.lst{,_backup_by_grub2_prerm} echo "Running update-grub Legacy to remove our core.img in it" >&2 /usr/lib/grub-legacy/update-grub 2>&1 | sed -e "s/^/ /g" >&2 fi ;; failed-upgrade|upgrade) ;; *) echo "prerm called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 debian/default/0000775000000000000000000000000012524676037010630 5ustar debian/default/grub0000664000000000000000000000226412524662415011511 0ustar # If you change this file, run 'update-grub' afterwards to update # /boot/grub/grub.cfg. # For full documentation of the options in this file, see: # info -f grub -n 'Simple configuration' GRUB_DEFAULT=0 GRUB_TIMEOUT=@DEFAULT_TIMEOUT@ GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` GRUB_CMDLINE_LINUX_DEFAULT="@DEFAULT_CMDLINE@" GRUB_CMDLINE_LINUX="" # Uncomment to enable BadRAM filtering, modify to suit your needs # This works with Linux (no patch required) and with any kernel that obtains # the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...) #GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef" # Uncomment to disable graphical terminal (grub-pc only) #GRUB_TERMINAL=console # The resolution used on graphical terminal # note that you can use only modes which your graphic card supports via VBE # you can see them in real GRUB with the command `vbeinfo' #GRUB_GFXMODE=640x480 # Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux #GRUB_DISABLE_LINUX_UUID=true # Uncomment to disable generation of recovery mode menu entries #GRUB_DISABLE_RECOVERY="true" # Uncomment to get a beep at grub start #GRUB_INIT_TUNE="480 440 1" debian/default/grub.md5sum0000664000000000000000000000027212524662415012717 0ustar dfad90339e4227d432636ed7d4483744 experimental_1.96+20081129-1 e916b60d7de71969dd7bad5a809fb9dc lenny_1.96+20080724-16 965e5137eff659cded3adb640357c33d maverick_1.98+20100705-1ubuntu1 debian/bug-script0000775000000000000000000000335012524662415011205 0ustar #!/bin/bash set -e if test -e /boot/grub/setup_left_core_image_in_filesystem ; then echo >&3 echo "*********************** WARNING grub-setup left core.img in filesystem" >&3 fi for i in /proc/mounts ; do if test -e $i ; then echo >&3 echo "*********************** BEGIN $i" >&3 grep ^/dev/ $i >&3 echo "*********************** END $i" >&3 fi done for i in /boot/grub/{device.map,grub.cfg} ; do if ! test -e $i ; then continue fi echo >&3 echo "*********************** BEGIN $i" >&3 if test -r $i ; then sed $i -e "s/.*password.*/### PASSWORD LINE REMOVED ###/g" >&3 else echo "$i is not readable by you. Please enter your root password." echo "Any password line in it gets removed." su root -c "sed $i -e 's/.*password.*/### PASSWORD LINE REMOVED ###/g'" >&3 fi echo "*********************** END $i" >&3 done echo >&3 echo "*********************** BEGIN /proc/mdstat" >&3 cat /proc/mdstat >&3 2>&1 || true echo "*********************** END /proc/mdstat" >&3 cat <&3 echo "*********************** BEGIN LVM" >&3 su root -c "vgdisplay; pvdisplay; lvdisplay" >&3 || true echo "*********************** END LVM" >&3 fi echo >&3 echo "*********************** BEGIN /dev/disk/by-id" >&3 ls -l /dev/disk/by-id >&3 2>&1 || true echo "*********************** END /dev/disk/by-id" >&3 echo >&3 echo "*********************** BEGIN /dev/disk/by-uuid" >&3 ls -l /dev/disk/by-uuid >&3 2>&1 || true echo "*********************** END /dev/disk/by-uuid" >&3 exit 0 debian/grub-pc-bin.install.kopensolaris-i386.in0000664000000000000000000000004612524662415016500 0ustar usr/lib/grub/@CPU_PLATFORM@/efiemu*.o debian/grub-pc.dirs.in0000664000000000000000000000002412524662415012022 0ustar usr/lib/grub-legacy debian/apport/0000775000000000000000000000000012524676037010511 5ustar debian/apport/source_grub2.py0000664000000000000000000000730612524662415013465 0ustar # vim: set fileencoding=UTF-8 : '''apport package hook for grub2 Author: Jean-Baptiste Lallement This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. See http://www.gnu.org/copyleft/gpl.html for the full text of the license. ''' from __future__ import print_function from apport.hookutils import * import os import subprocess import re def check_shell_syntax(path): ''' Check the syntax of a shell script ''' try: with open(os.devnull, 'w') as devnull: subprocess.check_call(['/bin/sh', '-n', path], stderr=devnull) except subprocess.CalledProcessError: return False return True def check_shell_syntax_harder(path): ''' Check the syntax of a shell script ''' try: # sh -n is tempting, but not good enough. Consider this case: # # GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash nomodeset” # # The quotes are Unicode quotes, not valid in the shell and probably # caused by copying a line out of a web page. This is parsed as an # instruction to run the 'splash' command with argument 'nomodeset”' # and with the GRUB_CMDLINE_LINUX_DEFAULT environment variable set # to '”quiet'. 'sh -n' allows this because this is a valid parse # and it's possible that the command 'splash' might exist, but what # we need to know is whether sourcing the file will fail. # # Unfortunately this test may involve executing code. However, this # file is already sourced as root when running update-grub, so it # seems unlikely that this could do any further harm. with open(os.devnull, 'w') as devnull: subprocess.check_call( ['/bin/sh', '-ec', '. %s' % re.escape(path)], stderr=devnull) except subprocess.CalledProcessError: return False return True def add_info(report): if report['ProblemType'] == 'Package': # To detect if root fs is a loop device attach_file(report, '/proc/cmdline','ProcCmdLine') attach_default_grub(report, 'EtcDefaultGrub') attach_file_if_exists(report, '/boot/grub/device.map', 'DeviceMap') try: grub_d = '/etc/default/grub.d' for name in sorted(os.listdir(grub_d)): if name.endswith('.cfg'): key = 'EtcDefaultGrubD.' + path_to_key(name) attach_file_if_exists( report, os.path.join(grub_d, name), key) except OSError: pass invalid_grub_script = [] if not check_shell_syntax_harder('/etc/default/grub'): invalid_grub_script.append('/etc/default/grub') # Check scripts in /etc/grub.d since some users directly change # configuration there grubdir='/etc/grub.d' for f in os.listdir(grubdir): fullpath=os.path.join(grubdir, f) if f != 'README' and os.access(fullpath, os.X_OK) \ and not check_shell_syntax(fullpath): invalid_grub_script.append(fullpath) attach_file(report, fullpath) # TODO: Add some UI to ask if the user modified the invalid script # and if he still wants to report it if invalid_grub_script: report['InvalidGrubScript'] = ' '.join(invalid_grub_script) if __name__ == '__main__': r = {} r['ProblemType'] = 'Package' add_info(r) for k, v in r.items(): print('%s: "%s"' % (k, v)) print("========================================") debian/grub-firmware-qemu.dirs0000664000000000000000000000001712524662415013576 0ustar usr/share/qemu debian/grub-coreboot-bin.install.linux-i386.in0000664000000000000000000000004612524662415016340 0ustar usr/lib/grub/@CPU_PLATFORM@/efiemu*.o debian/bug-presubj0000664000000000000000000000213012524662415011343 0ustar MAKE SURE YOU ARE RUNNING THE LATEST VERSION The grub packages never update the installed version of GRUB automatically, except if you choose a device in the debconf prompt `GRUB install devices', which is currently only implemented for grub-pc. Because of this, you need to make sure you're running the LATEST VERSION of GRUB before you report a bug. Use grub-install to update it, and then check if the bug still applies. Debugging problems we already fixed makes us waste valuable time, so please try to avoid it. IMPORTANT NOTE WHEN SUBMITTING PATCHES Like many other FSF projects, GRUB upstream has specific requirements for accepting patches with regard to copyright assignment. If you're going to submit a patch, it is likely that it will only be accepted in upstream if you're willing to submit your paperwork as well. Because of this, we want to avoid diverging from upstream by adding patches to the Debian package unless we know the copyright issues can be sorted out. We encourage you to submit your work to upstream directly by sending a mail to the GRUB maintainers . debian/patches/0000775000000000000000000000000012634017610010617 5ustar debian/patches/core_in_fs.patch0000664000000000000000000000231312524662415013754 0ustar From 9f599c89688957e58a6f6841e1dc4ea126a27a54 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:12:51 +0000 Subject: Write marker if core.img was written to filesystem The Debian bug reporting script includes a warning in this case. Patch-Name: core_in_fs.patch --- util/setup.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/util/setup.c b/util/setup.c index 9fb91a8..3945eff 100644 --- a/util/setup.c +++ b/util/setup.c @@ -58,6 +58,8 @@ #include +#define CORE_IMG_IN_FS "setup_left_core_image_in_filesystem" + /* On SPARC this program fills in various fields inside of the 'boot' and 'core' * image files. * @@ -590,6 +592,8 @@ SETUP (const char *dir, grub_free (sectors); + unlink (DEFAULT_DIRECTORY "/" CORE_IMG_IN_FS); + goto finish; } @@ -632,6 +636,10 @@ unable_to_embed: /* The core image must be put on a filesystem unfortunately. */ grub_util_info ("will leave the core image on the filesystem"); + fp = grub_util_fd_open (DEFAULT_DIRECTORY "/" CORE_IMG_IN_FS, + GRUB_UTIL_FD_O_WRONLY); + grub_util_fd_close (fp); + grub_util_biosdisk_flush (root_dev->disk); /* Clean out the blocklists. */ debian/patches/mkrescue_arm64_naming.patch0000664000000000000000000000203112524662415016023 0ustar From 33b001c5cbe3406534e2ea420c23bb629d2fb7f2 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Mon, 10 Mar 2014 13:35:53 +0000 Subject: Change grub-mkrescue to use bootaa64.efi too Origin: upstream, http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commitdiff;h=e7cfa8d5e1c6d54d40731065e535889b2e8bc9a2 Last-Update: 2014-03-10 Patch-Name: mkrescue_arm64_naming.patch --- util/grub-mkrescue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index cf698ff..54b602d 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -669,7 +669,7 @@ main (int argc, char *argv[]) make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM_EFI, "arm-efi", imgname); free (imgname); - imgname = grub_util_path_concat (2, efidir_efi_boot, "bootaarch64.efi"); + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootaa64.efi"); make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM64_EFI, "arm64-efi", imgname); free (imgname); debian/patches/install_efi_ubuntu_flavours.patch0000664000000000000000000000171712524662415017471 0ustar From b02dbb917015a01bfdd039a66ae878d72d8059a8 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:27 +0000 Subject: Cope with Kubuntu setting GRUB_DISTRIBUTOR This is not a very good approach, and certainly not sanely upstreamable; we probably need to split GRUB_DISTRIBUTOR into a couple of different variables. Bug-Ubuntu: https://bugs.launchpad.net/bugs/1242417 Forwarded: not-needed Last-Update: 2013-12-25 Patch-Name: install_efi_ubuntu_flavours.patch --- util/grub-install.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/grub-install.c b/util/grub-install.c index 0d77a2a..1f27b65 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -1089,6 +1089,8 @@ main (int argc, char *argv[]) */ char *t; efi_distributor = bootloader_id; + if (strcmp (efi_distributor, "kubuntu") == 0) + efi_distributor = "ubuntu"; switch (platform) { case GRUB_INSTALL_PLATFORM_I386_EFI: debian/patches/install_stage2_confusion.patch0000664000000000000000000000253512524662415016652 0ustar From b8b97d8b852927ad913fb4c5c137bc30122329a5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:12:58 +0000 Subject: If GRUB Legacy is still around, tell packaging to ignore it Bug-Debian: http://bugs.debian.org/586143 Forwarded: not-needed Last-Update: 2013-12-25 Patch-Name: install_stage2_confusion.patch --- util/grub-install.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/util/grub-install.c b/util/grub-install.c index 8cfe0ea..3275209 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -1662,6 +1663,19 @@ main (int argc, char *argv[]) grub_util_bios_setup (platdir, "boot.img", "core.img", install_drive, force, fs_probe, allow_floppy, add_rs_codes); + + /* If vestiges of GRUB Legacy still exist, tell the Debian packaging + that they can ignore them. */ + if (!rootdir && grub_util_is_regular ("/boot/grub/stage2") && + grub_util_is_regular ("/boot/grub/menu.lst")) + { + grub_util_fd_t fd; + + fd = grub_util_fd_open ("/boot/grub/grub2-installed", + GRUB_UTIL_FD_O_WRONLY); + grub_util_fd_close (fd); + } + break; } case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: debian/patches/arm64-set-correct-length-of-device-path-end-entry.patch0000664000000000000000000000247712625413255023013 0ustar From 07a105d450ee701b7a690a562b7efa0d827bdc65 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Tue, 7 Jan 2014 17:52:50 +0000 Subject: arm64: set correct length of device path end entry The length of the Device Path End entry in the grub_linux_boot() function was incorrectly set to 0. This triggers an assert failure in debug builds of Tianocore. Set it to sizeof (grub_efi_device_path_t). Bug-Ubuntu: http://bugs.launchpad.net/bugs/1476882 Origin: http://git.savannah.gnu.org/cgit/grub.git/commit/grub-core/loader/arm64/linux.c?id=4d21c1019904598a991e847eef049c65f9c49bd9 Last-Update: 2015-07-22 Patch-Name: arm64-set-correct-length-of-device-path-end-entry.patch --- grub-core/loader/arm64/linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c index 9d15aad..75ad871 100644 --- a/grub-core/loader/arm64/linux.c +++ b/grub-core/loader/arm64/linux.c @@ -268,7 +268,7 @@ grub_linux_boot (void) mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; - mempath[1].header.length = 0; + mempath[1].header.length = sizeof (grub_efi_device_path_t); b = grub_efi_system_table->boot_services; status = b->load_image (0, grub_efi_image_handle, debian/patches/install_powerpc_machtypes.patch0000664000000000000000000001435712524674601017143 0ustar From 6b86ab9bd13c56b7cbf957e89a5e201ddc011979 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 28 Jan 2014 14:40:02 +0000 Subject: Port yaboot logic for various powerpc machine types Some powerpc machines require not updating the NVRAM. This can be handled by existing grub-install command-line options, but it's friendlier to detect this automatically. On chrp_ibm machines, use the nvram utility rather than nvsetenv. (This is possibly suitable for other machines too, but that needs to be verified.) Forwarded: no Last-Update: 2014-10-15 Patch-Name: install_powerpc_machtypes.patch --- grub-core/osdep/basic/platform.c | 5 +++ grub-core/osdep/linux/platform.c | 72 ++++++++++++++++++++++++++++++++++++++ grub-core/osdep/unix/platform.c | 28 +++++++++++---- grub-core/osdep/windows/platform.c | 6 ++++ include/grub/util/install.h | 3 ++ util/grub-install.c | 11 ++++++ 6 files changed, 119 insertions(+), 6 deletions(-) diff --git a/grub-core/osdep/basic/platform.c b/grub-core/osdep/basic/platform.c index 4b5502a..2ab9079 100644 --- a/grub-core/osdep/basic/platform.c +++ b/grub-core/osdep/basic/platform.c @@ -24,3 +24,8 @@ grub_install_get_default_x86_platform (void) return "i386-pc"; } +const char * +grub_install_get_default_powerpc_machtype (void) +{ + return "generic"; +} diff --git a/grub-core/osdep/linux/platform.c b/grub-core/osdep/linux/platform.c index 175da72..033afd8 100644 --- a/grub-core/osdep/linux/platform.c +++ b/grub-core/osdep/linux/platform.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -108,3 +109,74 @@ grub_install_get_default_x86_platform (void) grub_util_info ("... not found"); return "i386-pc"; } + +const char * +grub_install_get_default_powerpc_machtype (void) +{ + FILE *fp; + char *buf = NULL; + size_t len = 0; + const char *machtype = "generic"; + + fp = grub_util_fopen ("/proc/cpuinfo", "r"); + if (! fp) + return machtype; + + while (getline (&buf, &len, fp) > 0) + { + if (strncmp (buf, "pmac-generation", + sizeof ("pmac-generation") - 1) == 0) + { + if (strstr (buf, "NewWorld")) + { + machtype = "pmac_newworld"; + break; + } + if (strstr (buf, "OldWorld")) + { + machtype = "pmac_oldworld"; + break; + } + } + + if (strncmp (buf, "motherboard", sizeof ("motherboard") - 1) == 0 && + strstr (buf, "AAPL")) + { + machtype = "pmac_oldworld"; + break; + } + + if (strncmp (buf, "machine", sizeof ("machine") - 1) == 0 && + strstr (buf, "CHRP IBM")) + { + if (strstr (buf, "qemu")) + { + machtype = "chrp_ibm_qemu"; + break; + } + else + { + machtype = "chrp_ibm"; + break; + } + } + + if (strncmp (buf, "platform", sizeof ("platform") - 1) == 0) + { + if (strstr (buf, "Maple")) + { + machtype = "maple"; + break; + } + if (strstr (buf, "Cell")) + { + machtype = "cell"; + break; + } + } + } + + free (buf); + fclose (fp); + return machtype; +} diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c index a3fcfca..28cb37e 100644 --- a/grub-core/osdep/unix/platform.c +++ b/grub-core/osdep/unix/platform.c @@ -212,13 +212,29 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device, else boot_device = get_ofpathname (install_device); - if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device", - boot_device, NULL })) + if (strcmp (grub_install_get_default_powerpc_machtype (), "chrp_ibm") == 0) { - char *cmd = xasprintf ("setenv boot-device %s", boot_device); - grub_util_error (_("`nvsetenv' failed. \nYou will have to set `boot-device' variable manually. At the IEEE1275 prompt, type:\n %s\n"), - cmd); - free (cmd); + char *arg = xasprintf ("boot-device=%s", boot_device); + if (grub_util_exec ((const char * []){ "nvram", + "--update-config", arg, NULL })) + { + char *cmd = xasprintf ("setenv boot-device %s", boot_device); + grub_util_error (_("`nvram' failed. \nYou will have to set `boot-device' variable manually. At the IEEE1275 prompt, type:\n %s\n"), + cmd); + free (cmd); + } + free (arg); + } + else + { + if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device", + boot_device, NULL })) + { + char *cmd = xasprintf ("setenv boot-device %s", boot_device); + grub_util_error (_("`nvsetenv' failed. \nYou will have to set `boot-device' variable manually. At the IEEE1275 prompt, type:\n %s\n"), + cmd); + free (cmd); + } } free (boot_device); diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c index f2b9d71..cf2e39c 100644 --- a/grub-core/osdep/windows/platform.c +++ b/grub-core/osdep/windows/platform.c @@ -128,6 +128,12 @@ grub_install_get_default_x86_platform (void) return "i386-efi"; } +const char * +grub_install_get_default_powerpc_machtype (void) +{ + return "generic"; +} + static void * get_efi_variable (const wchar_t *varname, ssize_t *len) { diff --git a/include/grub/util/install.h b/include/grub/util/install.h index bc987aa..2de6c90 100644 --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -204,6 +204,9 @@ grub_install_create_envblk_file (const char *name); const char * grub_install_get_default_x86_platform (void); +const char * +grub_install_get_default_powerpc_machtype (void); + void grub_install_register_efi (grub_device_t efidir_grub_dev, const char *efifile_path, diff --git a/util/grub-install.c b/util/grub-install.c index 1f27b65..98da118 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -1143,7 +1143,18 @@ main (int argc, char *argv[]) if (platform == GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275) { + const char *machtype = grub_install_get_default_powerpc_machtype (); int is_guess = 0; + + if (strcmp (machtype, "pmac_oldworld") == 0) + update_nvram = 0; + else if (strcmp (machtype, "cell") == 0) + update_nvram = 0; + else if (strcmp (machtype, "generic") == 0) + update_nvram = 0; + else if (strcmp (machtype, "chrp_ibm_qemu") == 0) + update_nvram = 0; + if (!macppcdir) { char *d; debian/patches/linuxefi_require_shim.patch0000664000000000000000000000161112524662415016245 0ustar From 22fb5cb563a439aab34fd9b4ce33e10ee54c03e1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:19 +0000 Subject: Make linuxefi refuse to boot without shim This is only intended as a temporary measure. Forwarded: not-needed Last-Update: 2013-01-29 Patch-Name: linuxefi_require_shim.patch --- grub-core/loader/i386/efi/linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c index a124c5e..26a958c 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -63,7 +63,7 @@ grub_linuxefi_secure_validate (void *data, grub_uint32_t size) if (!shim_lock) { grub_dprintf ("linuxefi", "shim not available\n"); - return 1; + return 0; } grub_dprintf ("linuxefi", "Asking shim to verify kernel signature\n"); debian/patches/dpkg_version_comparison.patch0000664000000000000000000000276312524662415016603 0ustar From f16cf1523e8bd1caa9d80ec62c23275ede3223b8 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 13 Jan 2014 12:12:52 +0000 Subject: Improve handling of Debian kernel version numbers Forwarded: not-needed Last-Update: 2013-12-20 Patch-Name: dpkg_version_comparison.patch --- util/grub-mkconfig_lib.in | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 14fadbc..4f6c4fe 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -238,8 +238,9 @@ version_test_numeric () version_test_gt () { - version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`" - version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`" + version_test_gt_sedexp="s/[^-]*-//;s/[._-]\(pre\|rc\|test\|git\|old\|trunk\)/~\1/g" + version_test_gt_a="`echo "$1" | sed -e "$version_test_gt_sedexp"`" + version_test_gt_b="`echo "$2" | sed -e "$version_test_gt_sedexp"`" version_test_gt_cmp=gt if [ "x$version_test_gt_b" = "x" ] ; then return 0 @@ -249,7 +250,7 @@ version_test_gt () *.old:*) version_test_gt_a="`echo -n "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;; *:*.old) version_test_gt_b="`echo -n "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;; esac - version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b" + dpkg --compare-versions "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b" return "$?" } debian/patches/ieee1275-clear-reset.patch0000664000000000000000000000261212524675700015303 0ustar From 8500c4f400ae033c79f495bbb5a10079f633193c Mon Sep 17 00:00:00 2001 From: Paulo Flabiano Smorigo Date: Thu, 25 Sep 2014 18:41:29 -0300 Subject: Include a text attribute reset in the clear command for ppc Always clear text attribute for clear command in order to avoid problems after it boots. * grub-core/term/terminfo.c: Add escape for text attribute reset Bug-Ubuntu: https://bugs.launchpad.net/bugs/1295255 Origin: other, https://lists.gnu.org/archive/html/grub-devel/2014-09/msg00076.html Last-Update: 2014-09-26 Patch-Name: ieee1275-clear-reset.patch --- grub-core/term/terminfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: b/grub-core/term/terminfo.c =================================================================== --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -151,7 +151,7 @@ grub_terminfo_set_current (struct grub_t /* Clear the screen. Using serial console, screen(1) only recognizes the * ANSI escape sequence. Using video console, Apple Open Firmware * (version 3.1.1) only recognizes the literal ^L. So use both. */ - data->cls = grub_strdup (" \e[2J"); + data->cls = grub_strdup (" \e[2J\e[m"); data->reverse_video_on = grub_strdup ("\e[7m"); data->reverse_video_off = grub_strdup ("\e[m"); if (grub_strcmp ("ieee1275", str) == 0) debian/patches/linuxefi_amd64_only.patch0000664000000000000000000000123512524662415015527 0ustar From d17d82d5217170e5f3124ed1c5aa77a7b8f253d7 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:16 +0000 Subject: Only build linuxefi on amd64 Forwarded: no Last-Update: 2013-12-25 Patch-Name: linuxefi_amd64_only.patch --- grub-core/Makefile.core.def | 1 - 1 file changed, 1 deletion(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 8c246c6..8fed2fb 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1709,7 +1709,6 @@ module = { name = linuxefi; efi = loader/i386/efi/linux.c; efi = lib/cmdline.c; - enable = i386_efi; enable = x86_64_efi; }; debian/patches/gettext_quiet.patch0000664000000000000000000000174712524662415014553 0ustar From e045c368e20a7a1d5e845a034ffa7a71cb9bfa06 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:02 +0000 Subject: Silence error messages when translations are unavailable Bug: https://savannah.gnu.org/bugs/?35880 Forwarded: https://savannah.gnu.org/bugs/?35880 Last-Update: 2013-11-14 Patch-Name: gettext_quiet.patch --- grub-core/gettext/gettext.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c index 4880cef..3098e89 100644 --- a/grub-core/gettext/gettext.c +++ b/grub-core/gettext/gettext.c @@ -427,6 +427,11 @@ grub_gettext_init_ext (struct grub_gettext_context *ctx, if (locale[0] == 'e' && locale[1] == 'n' && (locale[2] == '\0' || locale[2] == '_')) grub_errno = err = GRUB_ERR_NONE; + + /* If no translations are available, fall back to untranslated text. */ + if (err == GRUB_ERR_FILE_NOT_FOUND) + grub_errno = err = GRUB_ERR_NONE; + return err; } debian/patches/arm64-setjmp-Add-missing-license-macro.patch0000664000000000000000000000213512625413255020753 0ustar From 2252bec27ecd3d0353d1868af5a5f325450cc1d2 Mon Sep 17 00:00:00 2001 From: dann frazier Date: Thu, 21 May 2015 10:28:48 -0600 Subject: arm64/setjmp: Add missing license macro Including the setjmp module in an arm64-efi image will cause it to immediately exit with an "incompatible license" error. The source file includes a GPLv3+ boilerplate, so fix this by declaring a GPLv3+ license using the GRUB_MOD_LICENSE macro. Signed-off-by: dann frazier Bug-Ubuntu: https://bugs.launchpad.net/bugs/1459871 Origin: upstream, http://git.savannah.gnu.org/cgit/grub.git/commit/?id=3ac342205dc81293bb8e2d91b8c5ebe124b4ad35 Patch-Name: arm64-setjmp-Add-missing-license-macro.patch --- grub-core/lib/arm64/setjmp.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grub-core/lib/arm64/setjmp.S b/grub-core/lib/arm64/setjmp.S index adaafe4..eabfd99 100644 --- a/grub-core/lib/arm64/setjmp.S +++ b/grub-core/lib/arm64/setjmp.S @@ -17,8 +17,10 @@ */ #include +#include .file "setjmp.S" +GRUB_MOD_LICENSE "GPLv3+" .text /* debian/patches/probe_fusionio.patch0000664000000000000000000000354612524662415014701 0ustar From bfc306550aef74d557c2838f5226cb87ee13bf8e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:31 +0000 Subject: Probe FusionIO devices Bug-Ubuntu: https://bugs.launchpad.net/bugs/1237519 Forwarded: no Last-Update: 2013-11-15 Patch-Name: probe_fusionio.patch --- grub-core/osdep/linux/getroot.c | 13 +++++++++++++ util/deviceiter.c | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c index 772de0a..6788e39 100644 --- a/grub-core/osdep/linux/getroot.c +++ b/grub-core/osdep/linux/getroot.c @@ -883,6 +883,19 @@ grub_util_part_to_disk (const char *os_dev, struct stat *st, *pp = '\0'; return path; } + + /* If this is a FusionIO disk. */ + if ((strncmp ("fio", p, 3) == 0) && p[3] >= 'a' && p[3] <= 'z') + { + char *pp = p + 3; + while (*pp >= 'a' && *pp <= 'z') + pp++; + if (*pp) + *is_part = 1; + /* /dev/fio[a-z]+[0-9]* */ + *pp = '\0'; + return path; + } } return path; diff --git a/util/deviceiter.c b/util/deviceiter.c index 75047ff..b61715d 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -365,6 +365,12 @@ get_xvd_disk_name (char *name, int unit) { sprintf (name, "/dev/xvd%c", unit + 'a'); } + +static void +get_fio_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/fio%c", unit + 'a'); +} #endif static struct seen_device @@ -856,6 +862,19 @@ grub_util_iterate_devices (int (*hook) (const char *, int, void *), void *hook_d } } + /* FusionIO. */ + for (i = 0; i < 26; i++) + { + char name[16]; + + get_fio_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + # ifdef HAVE_DEVICE_MAPPER # define dmraid_check(cond, ...) \ if (! (cond)) \ debian/patches/install_arm64_naming.patch0000664000000000000000000000210612524662415015656 0ustar From 46124b1faf70ea5c156f1d29c480f146a322a2b0 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Mon, 10 Mar 2014 13:34:10 +0000 Subject: use {grub,boot}aa64.efi for boot images on AArch64 According to UEFI 2.4 specification, default boot file name on AArch64 is BOOTAA64.EFI (3.4.1.1 Removable Media Boot Behavior). Also set default GRUB image name to grubaa64.efi to match it. Origin: backport, http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commitdiff;h=c9e839e2caaf278491f99e7d181cf20dcf5f0b75 Last-Update: 2014-03-10 Patch-Name: install_arm64_naming.patch --- util/grub-install.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/grub-install.c b/util/grub-install.c index 01170d3..f6a70dd 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -1111,8 +1111,8 @@ main (int argc, char *argv[]) efi_suffix_upper = "ARM"; break; case GRUB_INSTALL_PLATFORM_ARM64_EFI: - efi_suffix = "arm64"; - efi_suffix_upper = "AARCH64"; + efi_suffix = "aa64"; + efi_suffix_upper = "AA64"; break; default: break; debian/patches/ppc64el-disable-vsx.patch0000664000000000000000000000241212524675151015343 0ustar From 603e3eaf4807b988cb87e3dd8a00a0518dc237aa Mon Sep 17 00:00:00 2001 From: Paulo Flabiano Smorigo Date: Thu, 25 Sep 2014 19:33:39 -0300 Subject: Disable VSX instruction VSX bit is enabled by default for Power7 and Power8 CPU models, so we need to disable them in order to avoid instruction exceptions. Kernel will activate it when necessary. * grub-core/kern/powerpc/ieee1275/startup.S: Disable VSX. Also-By: Adhemerval Zanella Origin: other, https://lists.gnu.org/archive/html/grub-devel/2014-09/msg00078.html Last-Update: 2014-09-26 Patch-Name: ppc64el-disable-vsx.patch --- grub-core/kern/powerpc/ieee1275/startup.S | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/grub-core/kern/powerpc/ieee1275/startup.S b/grub-core/kern/powerpc/ieee1275/startup.S index 21c884b..b4d9c21 100644 --- a/grub-core/kern/powerpc/ieee1275/startup.S +++ b/grub-core/kern/powerpc/ieee1275/startup.S @@ -20,6 +20,8 @@ #include #include +#define MSR_VSX 0x80 + .extern __bss_start .extern _end @@ -28,6 +30,14 @@ .globl start, _start start: _start: + _start: + + /* Disable VSX instruction */ + mfmsr 0 + oris 0,0,MSR_VSX + mtmsrd 0 + isync + li 2, 0 li 13, 0 debian/patches/mkconfig_ubuntu_distributor.patch0000664000000000000000000000223212524662415017477 0ustar From 9b945075b6407e9cd862cee51eb244cb5f6ead80 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 13 Jan 2014 12:13:14 +0000 Subject: Remove GNU/Linux from default distributor string for Ubuntu Ubuntu is called "Ubuntu", not "Ubuntu GNU/Linux". Author: Colin Watson Author: Harald Sitter Forwarded: not-needed Last-Update: 2013-12-25 Patch-Name: mkconfig_ubuntu_distributor.patch --- util/grub.d/10_linux.in | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 5f5c1c9..d343263 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -32,7 +32,14 @@ CLASS="--class gnu-linux --class gnu --class os" if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then OS=GNU/Linux else - OS="${GRUB_DISTRIBUTOR} GNU/Linux" + case ${GRUB_DISTRIBUTOR} in + Ubuntu|Kubuntu) + OS="${GRUB_DISTRIBUTOR}" + ;; + *) + OS="${GRUB_DISTRIBUTOR} GNU/Linux" + ;; + esac CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" fi debian/patches/mkconfig_loopback.patch0000664000000000000000000000574012524662415015324 0ustar From 85024e437049f60a25c8d12bf42cdfc577066efd Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:00 +0000 Subject: Handle filesystems loop-mounted on file images Improve prepare_grub_to_access_device to emit appropriate commands for such filesystems, and ignore them in Linux grub.d scripts. This is needed for Ubuntu's Wubi installation method. This patch isn't inherently Debian/Ubuntu-specific. losetup and /proc/mounts are Linux-specific, though, so we might need to refine this before sending it upstream. The changes to the Linux grub.d scripts might be better handled by integrating 10_lupin properly instead. Patch-Name: mkconfig_loopback.patch --- util/grub-mkconfig_lib.in | 24 ++++++++++++++++++++++++ util/grub.d/10_linux.in | 5 +++++ util/grub.d/20_linux_xen.in | 5 +++++ 3 files changed, 34 insertions(+) diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 4f6c4fe..6da2c2d 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -133,6 +133,22 @@ prepare_grub_to_access_device () esac done + loop_file= + case $1 in + /dev/loop/*|/dev/loop[0-9]) + grub_loop_device="${1#/dev/}" + loop_file=`losetup "$1" | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"` + case $loop_file in + /dev/*) ;; + *) + loop_device="$1" + shift + set -- `"${grub_probe}" --target=device "${loop_file}"` "$@" + ;; + esac + ;; + esac + # Abstraction modules aren't auto-loaded. abstraction="`"${grub_probe}" --device $@ --target=abstraction`" for module in ${abstraction} ; do @@ -165,6 +181,14 @@ prepare_grub_to_access_device () echo "fi" fi IFS="$old_ifs" + + if [ "x${loop_file}" != x ]; then + loop_mountpoint="$(awk '"'${loop_file}'" ~ "^"$2 && $2 != "/" { print $2 }' /proc/mounts | tail -n1)" + if [ "x${loop_mountpoint}" != x ]; then + echo "loopback ${grub_loop_device} ${loop_file#$loop_mountpoint}" + echo "set root=(${grub_loop_device})" + fi + fi } grub_get_device_id () diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index a9f9b31..c83f1ed 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -40,6 +40,11 @@ fi case ${GRUB_DEVICE} in /dev/loop/*|/dev/loop[0-9]) GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"` + # We can't cope with devices loop-mounted from files here. + case ${GRUB_DEVICE} in + /dev/*) ;; + *) exit 0 ;; + esac ;; esac diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index a608435..fb4f615 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -40,6 +40,11 @@ fi case ${GRUB_DEVICE} in /dev/loop/*|/dev/loop[0-9]) GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"` + # We can't cope with devices loop-mounted from files here. + case ${GRUB_DEVICE} in + /dev/*) ;; + *) exit 0 ;; + esac ;; esac debian/patches/sleep_shift.patch0000664000000000000000000000472512524662415014164 0ustar From fefac6ff31f868cf53aa597ae4f5332170dbb063 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:23 +0000 Subject: Allow Shift to interrupt 'sleep --interruptible' Upstream would like to consider this at more length. See http://lists.gnu.org/archive/html/grub-devel/2009-08/msg00718.html, and the rest of the thread for context. Forwarded: http://lists.gnu.org/archive/html/grub-devel/2009-08/msg00694.html Last-Update: 2013-12-04 Patch-Name: sleep_shift.patch --- grub-core/commands/sleep.c | 27 ++++++++++++++++++++++++++- grub-core/normal/menu.c | 19 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/grub-core/commands/sleep.c b/grub-core/commands/sleep.c index e77e790..3906b14 100644 --- a/grub-core/commands/sleep.c +++ b/grub-core/commands/sleep.c @@ -46,6 +46,31 @@ do_print (int n) grub_refresh (); } +static int +grub_check_keyboard (void) +{ + int mods = 0; + grub_term_input_t term; + + if (grub_term_poll_usb) + grub_term_poll_usb (0); + + FOR_ACTIVE_TERM_INPUTS(term) + { + if (term->getkeystatus) + mods |= term->getkeystatus (term); + } + + if (mods >= 0 && + (mods & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) != 0) + return 1; + + if (grub_getkey_noblock () == GRUB_TERM_ESC) + return 1; + + return 0; +} + /* Based on grub_millisleep() from kern/generic/millisleep.c. */ static int grub_interruptible_millisleep (grub_uint32_t ms) @@ -55,7 +80,7 @@ grub_interruptible_millisleep (grub_uint32_t ms) start = grub_get_time_ms (); while (grub_get_time_ms () - start < ms) - if (grub_getkey_noblock () == GRUB_TERM_ESC) + if (grub_check_keyboard ()) return 1; return 0; diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index b47991a..2723547 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -615,8 +615,27 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) saved_time = grub_get_time_ms (); while (1) { + int mods = 0; + grub_term_input_t term; int key; + if (grub_term_poll_usb) + grub_term_poll_usb (0); + + FOR_ACTIVE_TERM_INPUTS(term) + { + if (term->getkeystatus) + mods |= term->getkeystatus (term); + } + + if (mods >= 0 && + (mods & (GRUB_TERM_STATUS_LSHIFT + | GRUB_TERM_STATUS_RSHIFT)) != 0) + { + timeout = -1; + break; + } + key = grub_getkey_noblock (); if (key != GRUB_TERM_NO_KEY) { debian/patches/blacklist_1440x900x32.patch0000664000000000000000000000230312524662415015243 0ustar From 4b0f317bcce4f33447c75c97bf5b5c26abfb1525 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:11 +0000 Subject: Blacklist 1440x900x32 from VBE preferred mode handling Bug-Ubuntu: https://bugs.launchpad.net/bugs/701111 Forwarded: no Last-Update: 2013-11-14 Patch-Name: blacklist_1440x900x32.patch --- grub-core/video/i386/pc/vbe.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index 62b5c22..9a64904 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -1053,6 +1053,15 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, || vbe_mode_info.y_resolution > height) /* Resolution exceeds that of preferred mode. */ continue; + + /* Blacklist 1440x900x32 from preferred mode handling until a + better solution is available. This mode causes problems on + many Thinkpads. See: + https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/701111 */ + if (vbe_mode_info.x_resolution == 1440 && + vbe_mode_info.y_resolution == 900 && + vbe_mode_info.bits_per_pixel == 32) + continue; } else { debian/patches/install_locale_langpack.patch0000664000000000000000000000654712524662415016510 0ustar From 4ca4b785f94d3635eb39a18824f6732362d0778b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:07 +0000 Subject: Prefer translations from Ubuntu language packs if available Bug-Ubuntu: https://bugs.launchpad.net/bugs/537998 Forwarded: not-needed Last-Update: 2013-12-25 Patch-Name: install_locale_langpack.patch --- util/grub-install-common.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/util/grub-install-common.c b/util/grub-install-common.c index 6ea0a8e..9cf3012 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -594,17 +594,25 @@ get_localedir (void) } static void -copy_locales (const char *dstd) +copy_locales (const char *dstd, int langpack) { grub_util_fd_dir_t d; grub_util_fd_dirent_t de; const char *locale_dir = get_localedir (); + char *dir; - d = grub_util_fd_opendir (locale_dir); + if (langpack) + dir = xasprintf ("%s-langpack", locale_dir); + else + dir = xstrdup (locale_dir); + + d = grub_util_fd_opendir (dir); if (!d) { - grub_util_warn (_("cannot open directory `%s': %s"), - locale_dir, grub_util_fd_strerror ()); + if (!langpack) + grub_util_warn (_("cannot open directory `%s': %s"), + dir, grub_util_fd_strerror ()); + free (dir); return; } @@ -621,14 +629,14 @@ copy_locales (const char *dstd) if (ext && (grub_strcmp (ext, ".mo") == 0 || grub_strcmp (ext, ".gmo") == 0)) { - srcf = grub_util_path_concat (2, locale_dir, de->d_name); + srcf = grub_util_path_concat (2, dir, de->d_name); dstf = grub_util_path_concat (2, dstd, de->d_name); ext = grub_strrchr (dstf, '.'); grub_strcpy (ext, ".mo"); } else { - srcf = grub_util_path_concat_ext (4, locale_dir, de->d_name, + srcf = grub_util_path_concat_ext (4, dir, de->d_name, "LC_MESSAGES", PACKAGE, ".mo"); dstf = grub_util_path_concat_ext (2, dstd, de->d_name, ".mo"); } @@ -637,6 +645,7 @@ copy_locales (const char *dstd) free (dstf); } grub_util_fd_closedir (d); + free (dir); } static struct @@ -760,12 +769,14 @@ grub_install_copy_files (const char *src, { char *srcd = grub_util_path_concat (2, src, "po"); copy_by_ext (srcd, dst_locale, ".mo", 0); - copy_locales (dst_locale); + copy_locales (dst_locale, 0); + copy_locales (dst_locale, 1); free (srcd); } else { const char *locale_dir = get_localedir (); + char *locale_langpack_dir = xasprintf ("%s-langpack", locale_dir); for (i = 0; i < install_locales.n_entries; i++) { @@ -784,6 +795,19 @@ grub_install_copy_files (const char *src, } free (srcf); srcf = grub_util_path_concat_ext (4, + locale_langpack_dir, + install_locales.entries[i], + "LC_MESSAGES", + PACKAGE, + ".mo"); + if (grub_install_compress_file (srcf, dstf, 0)) + { + free (srcf); + free (dstf); + continue; + } + free (srcf); + srcf = grub_util_path_concat_ext (4, locale_dir, install_locales.entries[i], "LC_MESSAGES", @@ -798,6 +822,8 @@ grub_install_copy_files (const char *src, grub_util_error (_("cannot find locale `%s'"), install_locales.entries[i]); } + + free (locale_langpack_dir); } if (install_themes.is_default) debian/patches/mkconfig_ubuntu_recovery.patch0000664000000000000000000000700512524662415016766 0ustar From 144268a6e1af6173166280bc006ceacf9098179d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:06 +0000 Subject: "single" -> "recovery" when friendly-recovery is installed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If configured with --enable-ubuntu-recovery, also set nomodeset for recovery mode, and disable 'set gfxpayload=keep' even if the system normally supports it. See https://launchpad.net/ubuntu/+spec/desktop-o-xorg-tools-and-processes. Author: Stéphane Graber Forwarded: no Last-Update: 2013-12-25 Patch-Name: mkconfig_ubuntu_recovery.patch --- configure.ac | 11 +++++++++++ util/grub.d/10_linux.in | 16 ++++++++++++++-- util/grub.d/30_os-prober.in | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 7c5d080..fb4e2dd 100644 --- a/configure.ac +++ b/configure.ac @@ -1572,6 +1572,17 @@ fi AC_SUBST([LIBZFS]) AC_SUBST([LIBNVPAIR]) +AC_ARG_ENABLE([ubuntu-recovery], + [AS_HELP_STRING([--enable-ubuntu-recovery], + [adjust boot options for the Ubuntu recovery mode (default=no)])], + [], [enable_ubuntu_recovery=no]) +if test x"$enable_ubuntu_recovery" = xyes ; then + UBUNTU_RECOVERY=1 +else + UBUNTU_RECOVERY=0 +fi +AC_SUBST([UBUNTU_RECOVERY]) + LIBS="" AC_SUBST([FONT_SOURCE]) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index c83f1ed..5f5c1c9 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -20,6 +20,7 @@ set -e prefix="@prefix@" exec_prefix="@exec_prefix@" datarootdir="@datarootdir@" +ubuntu_recovery="@UBUNTU_RECOVERY@" . "@datadir@/@PACKAGE@/grub-mkconfig_lib" @@ -72,6 +73,15 @@ esac title_correction_code= +if [ -x /lib/recovery-mode/recovery-menu ]; then + GRUB_CMDLINE_LINUX_RECOVERY=recovery +else + GRUB_CMDLINE_LINUX_RECOVERY=single +fi +if [ "$ubuntu_recovery" = 1 ]; then + GRUB_CMDLINE_LINUX_RECOVERY="$GRUB_CMDLINE_LINUX_RECOVERY nomodeset" +fi + linux_entry () { os="$1" @@ -111,7 +121,9 @@ linux_entry () if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then echo " load_video" | sed "s/^/$submenu_indentation/" fi - echo " set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" | sed "s/^/$submenu_indentation/" + if [ "$ubuntu_recovery" = 0 ] || [ x$type != xrecovery ]; then + echo " set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" | sed "s/^/$submenu_indentation/" + fi fi echo " insmod gzio" | sed "s/^/$submenu_indentation/" @@ -239,7 +251,7 @@ while [ "x$list" != "x" ] ; do "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then linux_entry "${OS}" "${version}" recovery \ - "single ${GRUB_CMDLINE_LINUX}" + "${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}" fi list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '` diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index 0470e66..dd639dd 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -213,7 +213,7 @@ EOF fi onstr="$(gettext_printf "(on %s)" "${DEVICE}")" - recovery_params="$(echo "${LPARAMS}" | grep single)" || true + recovery_params="$(echo "${LPARAMS}" | grep 'single\|recovery')" || true counter=1 while echo "$used_osprober_linux_ids" | grep 'osprober-gnulinux-$LKERNEL-${recovery_params}-$counter-$boot_device_id' > /dev/null; do counter=$((counter+1)); debian/patches/uefi_firmware_setup.patch0000664000000000000000000000502012524662415015710 0ustar From 1f7a967fdb2402b74258d7675f92ba5f99a05e7c Mon Sep 17 00:00:00 2001 From: Steve Langasek Date: Mon, 13 Jan 2014 12:13:12 +0000 Subject: Output a menu entry for firmware setup on UEFI FastBoot systems Forwarded: no Last-Update: 2013-12-25 Patch-Name: uefi_firmware_setup.patch --- Makefile.util.def | 6 ++++++ util/grub.d/30_uefi-firmware.in | 46 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 util/grub.d/30_uefi-firmware.in diff --git a/Makefile.util.def b/Makefile.util.def index f659fb4..e1f6089 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -508,6 +508,12 @@ script = { }; script = { + name = '30_uefi-firmware'; + common = util/grub.d/30_uefi-firmware.in; + installdir = grubconf; +}; + +script = { name = '40_custom'; common = util/grub.d/40_custom.in; installdir = grubconf; diff --git a/util/grub.d/30_uefi-firmware.in b/util/grub.d/30_uefi-firmware.in new file mode 100644 index 0000000..0f49bfc --- /dev/null +++ b/util/grub.d/30_uefi-firmware.in @@ -0,0 +1,46 @@ +#! /bin/sh +set -e + +# grub-mkconfig helper script. +# Copyright (C) 2012 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +prefix="@prefix@" +exec_prefix="@exec_prefix@" +datarootdir="@datarootdir@" + +export TEXTDOMAIN=@PACKAGE@ +export TEXTDOMAINDIR="@localedir@" + +. "@datadir@/@PACKAGE@/grub-mkconfig_lib" + +efi_vars_dir=/sys/firmware/efi/vars +EFI_GLOBAL_VARIABLE=8be4df61-93ca-11d2-aa0d-00e098032b8c +OsIndications="$efi_vars_dir/OsIndicationsSupported-$EFI_GLOBAL_VARIABLE/data" + +if [ -e "$OsIndications" ] && \ + [ "$(( $(printf %x \'"$(cat $OsIndications | cut -b1)") & 1 ))" = 1 ]; then + LABEL="System setup" + + gettext_printf "Adding boot menu entry for EFI firmware configuration\n" >&2 + + onstr="$(gettext_printf "(on %s)" "${DEVICE}")" + + cat << EOF +menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' { + fwsetup +} +EOF +fi debian/patches/freebsd_debugflags_eperm.patch0000664000000000000000000000353712524662415016644 0ustar From a4bf5ec8b5a29e7a6373cd0c1290e0a0326dd9db Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 17 Jan 2014 02:55:58 +0000 Subject: Ignore EPERM when modifying kern.geom.debugflags Many tests fail when run as a non-root user on FreeBSD. The failures all amount to an inability to open files using grub_util_fd_open, because we cannot set the kern.geom.debugflags sysctl. This sysctl is indeed important to allow us to do such things as installing GRUB to the MBR, but if we need to do that and can't then we will get an error later. Enforcing it here is unnecessary and prevents otherwise perfectly reasonable operations. Forwarded: https://lists.gnu.org/archive/html/grub-devel/2014-01/msg00086.html Last-Update: 2014-01-17 Patch-Name: freebsd_debugflags_eperm.patch --- grub-core/osdep/freebsd/hostdisk.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/grub-core/osdep/freebsd/hostdisk.c b/grub-core/osdep/freebsd/hostdisk.c index bd5fddb..a5b00f4 100644 --- a/grub-core/osdep/freebsd/hostdisk.c +++ b/grub-core/osdep/freebsd/hostdisk.c @@ -102,8 +102,16 @@ grub_util_fd_open (const char *os_dev, int flags) if (! (sysctl_oldflags & 0x10) && sysctlbyname ("kern.geom.debugflags", NULL , 0, &sysctl_flags, sysctl_size)) { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot set flags of sysctl kern.geom.debugflags"); - return GRUB_UTIL_FD_INVALID; + if (errno == EPERM) + /* Running as an unprivileged user; don't worry about restoring + flags, although if we try to write to anything interesting such + as the MBR then we may fail later. */ + sysctl_oldflags = 0x10; + else + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot set flags of sysctl kern.geom.debugflags"); + return GRUB_UTIL_FD_INVALID; + } } ret = open (os_dev, flags, S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR); debian/patches/tolerate-lvm-snapshots.patch0000664000000000000000000000456212524662415016311 0ustar From 9ba6625cf42e26aa6541878df4ee7adb8537e61b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 10 Apr 2014 16:54:33 +0100 Subject: Tolerate devices with no filesystem UUID returned by os-prober * util/grub.d/30_os-prober.in: Tolerate devices with no filesystem UUID. Other parts of grub-mkconfig tolerate these, they were previously allowed here up to commit 55e706c918922def17f5012c23cfe88c4c645208, and they can arise in practice when the system has active LVM snapshots. Fixes Ubuntu bug #1287436. Origin: upstream, http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commitdiff;h=3a310e842fb7a9818c2e7cf0f4118f13660871d2 Bug-Ubuntu: https://bugs.launchpad.net/bugs/1287436 Forwarded: not-needed Last-Update: 2014-04-10 Patch-Name: tolerate-lvm-snapshots.patch --- util/grub.d/30_os-prober.in | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index 1106ad1..f4c8f56 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -129,16 +129,17 @@ for OS in ${OSPROBED} ; do LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`" LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '^' ' '`" BOOT="`echo ${OS} | cut -d ':' -f 4`" - UUID="`${grub_probe} --target=fs_uuid --device ${DEVICE%@*}`" - EXPUUID="$UUID" + if UUID="`${grub_probe} --target=fs_uuid --device ${DEVICE%@*}`"; then + EXPUUID="$UUID" - if [ x"${DEVICE#*@}" != x ] ; then + if [ x"${DEVICE#*@}" != x ] ; then EXPUUID="${EXPUUID}@${DEVICE#*@}" - fi + fi - if [ "x${GRUB_OS_PROBER_SKIP_LIST}" != "x" -a "x`echo ${GRUB_OS_PROBER_SKIP_LIST} | grep -i -e '\b'${EXPUUID}'\b'`" != "x" ] ; then - echo "Skipped ${LONGNAME} on ${DEVICE} by user request." >&2 - continue + if [ "x${GRUB_OS_PROBER_SKIP_LIST}" != "x" -a "x`echo ${GRUB_OS_PROBER_SKIP_LIST} | grep -i -e '\b'${EXPUUID}'\b'`" != "x" ] ; then + echo "Skipped ${LONGNAME} on ${DEVICE} by user request." >&2 + continue + fi fi BTRFS="`echo ${OS} | cut -d ':' -f 5`" @@ -315,9 +316,11 @@ EOF echo "$title_correction_code" ;; macosx) - OSXUUID="${UUID}" - osx_entry xnu_kernel 32 - osx_entry xnu_kernel64 64 + if [ "${UUID}" ]; then + OSXUUID="${UUID}" + osx_entry xnu_kernel 32 + osx_entry xnu_kernel64 64 + fi ;; hurd) found_other_os=1 debian/patches/install_efi_fallback.patch0000664000000000000000000000362212524662415015762 0ustar From 8ea7fb1681e9bc7fbef508dc1b29403d8e7a4573 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:05 +0000 Subject: Fall back to i386-pc if booted using EFI but -efi is missing It may be possible, particularly in recovery situations, to be booted using EFI on x86 when only the i386-pc target is installed. There's nothing actually stopping us installing i386-pc from an EFI environment, and it's better than returning a confusing error. Forwarded: no Last-Update: 2013-12-20 Patch-Name: install_efi_fallback.patch --- grub-core/osdep/linux/platform.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/grub-core/osdep/linux/platform.c b/grub-core/osdep/linux/platform.c index 4b9f6ef..175da72 100644 --- a/grub-core/osdep/linux/platform.c +++ b/grub-core/osdep/linux/platform.c @@ -19,10 +19,12 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -76,11 +78,24 @@ grub_install_get_default_x86_platform (void) grub_util_info ("Looking for /sys/firmware/efi .."); if (is_not_empty_directory ("/sys/firmware/efi")) { + const char *pkglibdir = grub_util_get_pkglibdir (); + const char *platform; + char *pd; + int found; + grub_util_info ("...found"); if (is_64_kernel ()) - return "x86_64-efi"; + platform = "x86_64-efi"; + else + platform = "i386-efi"; + + pd = grub_util_path_concat (2, pkglibdir, platform); + found = grub_util_is_directory (pd); + free (pd); + if (found) + return platform; else - return "i386-efi"; + grub_util_info ("... but %s platform not available", platform); } grub_util_info ("... not found. Looking for /proc/device-tree .."); debian/patches/series0000664000000000000000000000327012634017610012036 0ustar olpc_prefix_hack.patch core_in_fs.patch dpkg_version_comparison.patch grub_legacy_0_based_partitions.patch disable_floppies.patch grub.cfg_400.patch gfxpayload_keep_default.patch install_stage2_confusion.patch mkrescue_efi_modules.patch mkconfig_loopback.patch restore_mkdevicemap.patch gettext_quiet.patch mkconfig_mid_upgrade.patch install_efi_fallback.patch mkconfig_ubuntu_recovery.patch install_locale_langpack.patch mkconfig_nonexistent_loopback.patch no_insmod_on_sb.patch default_grub_d.patch blacklist_1440x900x32.patch uefi_firmware_setup.patch mkconfig_ubuntu_distributor.patch linuxefi.patch linuxefi_amd64_only.patch linuxefi_debug.patch linuxefi_require_shim.patch linuxefi_non_sb_fallback.patch mkconfig_signed_kernel.patch install_signed.patch sleep_shift.patch wubi_no_windows.patch maybe_quiet.patch install_efi_ubuntu_flavours.patch quick_boot.patch gfxpayload_dynamic.patch vt_handoff.patch probe_fusionio.patch ignore_grub_func_test_failures.patch mkconfig_recovery_title.patch skip_gettext_strings_test.patch elf_bi_endian.patch macbless_mansection.patch grub-shell-no-pad.patch freebsd_debugflags_eperm.patch install_powerpc_machtypes.patch install_arm64_naming.patch mkrescue_arm64_naming.patch ieee1275-pseries-emulation.patch probe-delimiter.patch btrfs-endian.patch tolerate-lvm-snapshots.patch net-receive-packets-yield.patch net-ramp-up-interval.patch probe_nvme.patch ppc64el-disable-vsx.patch ieee1275-clear-reset.patch check_blocklists_overlap_fix.patch arm64-set-correct-length-of-device-path-end-entry.patch progress_avoid_null_deref.patch arm64-setjmp-Add-missing-license-macro.patch ofdisk_add_sas_disks.patch efinet-open-Simple-Network-Protocol-exclusively.patch CVE-2015-8370.patch debian/patches/grub.cfg_400.patch0000664000000000000000000000144312524662415013731 0ustar From e3361108b4e3a2ea5d26b9ce7eb20973b776b17e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:12:55 +0000 Subject: Make grub.cfg world-readable if it contains no passwords Patch-Name: grub.cfg_400.patch --- util/grub-mkconfig.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index ca040dd..0d7cabb 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -262,6 +262,10 @@ for i in "${grub_mkconfig_dir}"/* ; do esac done +if [ "x${grub_cfg}" != "x" ] && ! grep "^password" ${grub_cfg}.new >/dev/null; then + chmod 444 ${grub_cfg}.new || true +fi + if test "x${grub_cfg}" != "x" ; then if ! ${grub_script_check} ${grub_cfg}.new; then # TRANSLATORS: %s is replaced by filename debian/patches/quick_boot.patch0000664000000000000000000002360412526627003014007 0ustar From a6c14d009f574b026c8aebb977cd1e808827961b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:28 +0000 Subject: Add configure option to bypass boot menu if possible If other operating systems are installed, then automatically unhide the menu. Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus if available to check whether Shift is pressed. If it is, show the menu, otherwise boot immediately. If keystatus is not available, then fall back to a short delay interruptible with Escape. This may or may not remain Ubuntu-specific, although it's not obviously wanted upstream. It implements a requirement of https://wiki.ubuntu.com/DesktopExperienceTeam/KarmicBootExperienceDesignSpec#Bootloader. If the previous boot failed (defined as failing to get to the end of one of the normal runlevels), then show the boot menu regardless. Author: Richard Laager Author: Robie Basak Forwarded: no Last-Update: 2015-05-14 Patch-Name: quick_boot.patch --- configure.ac | 11 +++++++++ docs/grub.texi | 14 +++++++++++ grub-core/normal/menu.c | 24 +++++++++++++++++++ util/grub-mkconfig.in | 3 ++- util/grub.d/00_header.in | 58 +++++++++++++++++++++++++++++++++++---------- util/grub.d/10_linux.in | 4 ++++ util/grub.d/30_os-prober.in | 21 ++++++++++++++++ 7 files changed, 122 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index 7c8d0af..2a7e410 100644 --- a/configure.ac +++ b/configure.ac @@ -1594,6 +1594,17 @@ else fi AC_SUBST([QUIET_BOOT]) +AC_ARG_ENABLE([quick-boot], + [AS_HELP_STRING([--enable-quick-boot], + [bypass boot menu if possible (default=no)])], + [], [enable_quick_boot=no]) +if test x"$enable_quick_boot" = xyes ; then + QUICK_BOOT=1 +else + QUICK_BOOT=0 +fi +AC_SUBST([QUICK_BOOT]) + LIBS="" AC_SUBST([FONT_SOURCE]) diff --git a/docs/grub.texi b/docs/grub.texi index 46b9e7f..a79256b 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1490,6 +1490,20 @@ This option may be set to a list of GRUB module names separated by spaces. Each module will be loaded as early as possible, at the start of @file{grub.cfg}. +@item GRUB_RECORDFAIL_TIMEOUT +If this option is set, it overrides the default recordfail setting. A +setting of -1 causes GRUB to wait for user input indefinitely. However, a +false positive in the recordfail mechanism may occur if power is lost during +boot before boot success is recorded in userspace. The default setting is +30, which causes GRUB to wait for user input for thirty seconds before +continuing. This default allows interactive users the opportunity to switch +to a different, working kernel, while avoiding a false positive causing the +boot to block indefinitely on headless and appliance systems where access to +a console is restricted or limited. + +This option is only effective when GRUB was configured with the +@option{--enable-quick-boot} option. + @end table The following options are still accepted for compatibility with existing diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index 7b55c27..a968e0f 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -604,6 +604,30 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) static struct grub_term_coordinate *pos; int entry = -1; + if (timeout == 0) + { + /* If modifier key statuses can't be detected without a delay, + then a hidden timeout of zero cannot be interrupted in any way, + which is not very helpful. Bump it to three seconds in this + case to give the user a fighting chance. */ + grub_term_input_t term; + int nterms = 0; + int mods_detectable = 1; + + FOR_ACTIVE_TERM_INPUTS(term) + { + if (!term->getkeystatus) + { + mods_detectable = 0; + break; + } + else + nterms++; + } + if (!mods_detectable || !nterms) + timeout = 3; + } + if (timeout_style == TIMEOUT_STYLE_COUNTDOWN && timeout) { pos = grub_term_save_pos (); diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 62780bf..17350d4 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -236,7 +236,8 @@ export GRUB_DEFAULT \ GRUB_ENABLE_CRYPTODISK \ GRUB_BADRAM \ GRUB_OS_PROBER_SKIP_LIST \ - GRUB_DISABLE_SUBMENU + GRUB_DISABLE_SUBMENU \ + GRUB_RECORDFAIL_TIMEOUT if test "x${grub_cfg}" != "x"; then rm -f "${grub_cfg}.new" diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 0c82f23..2e6b5a4 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -21,6 +21,8 @@ prefix="@prefix@" exec_prefix="@exec_prefix@" datarootdir="@datarootdir@" grub_lang=`echo $LANG | cut -d . -f 1` +grubdir="`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`" +quick_boot="@QUICK_BOOT@" export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR="@localedir@" @@ -44,6 +46,7 @@ if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT cat << EOF if [ -s \$prefix/grubenv ]; then + set have_grubenv=true load_env fi EOF @@ -96,7 +99,31 @@ function savedefault { save_env saved_entry fi } +EOF +if [ "$quick_boot" = 1 ]; then + cat < Date: Mon, 13 Jan 2014 12:13:30 +0000 Subject: Add configure option to use vt.handoff=7 This is used for non-recovery Linux entries only; it enables flicker-free booting if gfxpayload=keep is in use and a suitable kernel is present. Author: Andy Whitcroft Forwarded: not-needed Last-Update: 2013-12-25 Patch-Name: vt_handoff.patch --- configure.ac | 11 +++++++++++ util/grub.d/10_linux.in | 28 +++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 7f26de6..735313d 100644 --- a/configure.ac +++ b/configure.ac @@ -1616,6 +1616,17 @@ else fi AC_SUBST([GFXPAYLOAD_DYNAMIC]) +AC_ARG_ENABLE([vt-handoff], + [AS_HELP_STRING([--enable-vt-handoff], + [use Linux vt.handoff option for flicker-free booting (default=no)])], + [], [enable_vt_handoff=no]) +if test x"$enable_vt_handoff" = xyes ; then + VT_HANDOFF=1 +else + VT_HANDOFF=0 +fi +AC_SUBST([VT_HANDOFF]) + LIBS="" AC_SUBST([FONT_SOURCE]) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 41f83ca..8d95887 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -24,6 +24,7 @@ ubuntu_recovery="@UBUNTU_RECOVERY@" quiet_boot="@QUIET_BOOT@" quick_boot="@QUICK_BOOT@" gfxpayload_dynamic="@GFXPAYLOAD_DYNAMIC@" +vt_handoff="@VT_HANDOFF@" . "@datadir@/@PACKAGE@/grub-mkconfig_lib" @@ -92,6 +93,14 @@ if [ "$ubuntu_recovery" = 1 ]; then GRUB_CMDLINE_LINUX_RECOVERY="$GRUB_CMDLINE_LINUX_RECOVERY nomodeset" fi +if [ "$vt_handoff" = 1 ]; then + for word in $GRUB_CMDLINE_LINUX_DEFAULT; do + if [ "$word" = splash ]; then + GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT \$vt_handoff" + fi + done +fi + linux_entry () { os="$1" @@ -137,7 +146,7 @@ linux_entry () fi if ([ "$ubuntu_recovery" = 0 ] || [ x$type != xrecovery ]) && \ ([ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 1 ]); then - echo " set gfxpayload=\$linux_gfx_mode" | sed "s/^/$submenu_indentation/" + echo " gfxmode \$linux_gfx_mode" | sed "s/^/$submenu_indentation/" fi echo " insmod gzio" | sed "s/^/$submenu_indentation/" @@ -210,6 +219,23 @@ prepare_root_cache= boot_device_id= title_correction_code= +cat << 'EOF' +function gfxmode { + set gfxpayload="${1}" +EOF +if [ "$vt_handoff" = 1 ]; then + cat << 'EOF' + if [ "${1}" = "keep" ]; then + set vt_handoff=vt.handoff=7 + else + set vt_handoff= + fi +EOF +fi +cat << EOF +} +EOF + # Use ELILO's generic "efifb" when it's known to be available. # FIXME: We need an interface to select vesafb in case efifb can't be used. if [ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 0 ]; then debian/patches/mkconfig_nonexistent_loopback.patch0000664000000000000000000000400012524662415017746 0ustar From 65685c2861e7af5b556f62223acd878b9963b22a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:08 +0000 Subject: Avoid getting confused by inaccessible loop device backing paths Bug-Ubuntu: https://bugs.launchpad.net/bugs/938724 Forwarded: no Last-Update: 2013-12-20 Patch-Name: mkconfig_nonexistent_loopback.patch --- util/grub-mkconfig_lib.in | 2 +- util/grub.d/30_os-prober.in | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 6da2c2d..5992506 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -143,7 +143,7 @@ prepare_grub_to_access_device () *) loop_device="$1" shift - set -- `"${grub_probe}" --target=device "${loop_file}"` "$@" + set -- `"${grub_probe}" --target=device "${loop_file}"` "$@" || return 0 ;; esac ;; diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index dd639dd..f8ac363 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -212,6 +212,11 @@ EOF LINITRD="${LINITRD#/boot}" fi + if [ -z "${prepare_boot_cache}" ]; then + prepare_boot_cache="$(prepare_grub_to_access_device ${LBOOT} | grub_add_tab)" + [ "${prepare_boot_cache}" ] || continue + fi + onstr="$(gettext_printf "(on %s)" "${DEVICE}")" recovery_params="$(echo "${LPARAMS}" | grep 'single\|recovery')" || true counter=1 @@ -223,10 +228,6 @@ EOF fi used_osprober_linux_ids="$used_osprober_linux_ids 'osprober-gnulinux-$LKERNEL-${recovery_params}-$counter-$boot_device_id'" - if [ -z "${prepare_boot_cache}" ]; then - prepare_boot_cache="$(prepare_grub_to_access_device ${LBOOT} | grub_add_tab)" - fi - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then cat << EOF menuentry '$(echo "$OS $onstr" | grub_quote)' --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux-simple-$boot_device_id' { debian/patches/linuxefi.patch0000664000000000000000000003226712524662415013504 0ustar From 2359f527c5091fb6633eec1b165db05c07eb83cf Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Mon, 13 Jan 2014 12:13:15 +0000 Subject: Add "linuxefi" loader which avoids ExitBootServices Origin: vendor, http://pkgs.fedoraproject.org/cgit/grub2.git/tree/grub2-linuxefi.patch Forwarded: no Last-Update: 2013-12-25 Patch-Name: linuxefi.patch --- grub-core/Makefile.core.def | 8 + grub-core/kern/efi/mm.c | 32 ++++ grub-core/loader/i386/efi/linux.c | 371 ++++++++++++++++++++++++++++++++++++++ include/grub/efi/efi.h | 3 + include/grub/i386/linux.h | 1 + 5 files changed, 415 insertions(+) create mode 100644 grub-core/loader/i386/efi/linux.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index c916246..8c246c6 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1706,6 +1706,14 @@ module = { }; module = { + name = linuxefi; + efi = loader/i386/efi/linux.c; + efi = lib/cmdline.c; + enable = i386_efi; + enable = x86_64_efi; +}; + +module = { name = chain; efi = loader/efi/chainloader.c; i386_pc = loader/i386/pc/chainloader.c; diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c index be37afd..ddeca60 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c @@ -49,6 +49,38 @@ static grub_efi_uintn_t finish_desc_size; static grub_efi_uint32_t finish_desc_version; int grub_efi_is_finished = 0; +/* Allocate pages below a specified address */ +void * +grub_efi_allocate_pages_max (grub_efi_physical_address_t max, + grub_efi_uintn_t pages) +{ + grub_efi_status_t status; + grub_efi_boot_services_t *b; + grub_efi_physical_address_t address = max; + + if (max > 0xffffffff) + return 0; + + b = grub_efi_system_table->boot_services; + status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); + + if (status != GRUB_EFI_SUCCESS) + return 0; + + if (address == 0) + { + /* Uggh, the address 0 was allocated... This is too annoying, + so reallocate another one. */ + address = max; + status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); + grub_efi_free_pages (0, pages); + if (status != GRUB_EFI_SUCCESS) + return 0; + } + + return (void *) ((grub_addr_t) address); +} + /* Allocate pages. Return the pointer to the first of allocated pages. */ void * grub_efi_allocate_pages (grub_efi_physical_address_t address, diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c new file mode 100644 index 0000000..b79e632 --- /dev/null +++ b/grub-core/loader/i386/efi/linux.c @@ -0,0 +1,371 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2012 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_dl_t my_mod; +static int loaded; +static void *kernel_mem; +static grub_uint64_t kernel_size; +static grub_uint8_t *initrd_mem; +static grub_uint32_t handover_offset; +struct linux_kernel_params *params; +static char *linux_cmdline; + +#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) + +#define SHIM_LOCK_GUID \ + { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} } + +struct grub_efi_shim_lock +{ + grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size); +}; +typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; + +static grub_efi_boolean_t +grub_linuxefi_secure_validate (void *data, grub_uint32_t size) +{ + grub_efi_guid_t guid = SHIM_LOCK_GUID; + grub_efi_shim_lock_t *shim_lock; + + shim_lock = grub_efi_locate_protocol(&guid, NULL); + + if (!shim_lock) + return 1; + + if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS) + return 1; + + return 0; +} + +typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *); + +static grub_err_t +grub_linuxefi_boot (void) +{ + handover_func hf; + int offset = 0; + +#ifdef __x86_64__ + offset = 512; +#endif + + hf = (handover_func)((char *)kernel_mem + handover_offset + offset); + + asm volatile ("cli"); + + hf (grub_efi_image_handle, grub_efi_system_table, params); + + /* Not reached */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linuxefi_unload (void) +{ + grub_dl_unref (my_mod); + loaded = 0; + if (initrd_mem) + grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(params->ramdisk_size)); + if (linux_cmdline) + grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(params->cmdline_size + 1)); + if (kernel_mem) + grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); + if (params) + grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t *files = 0; + int i, nfiles = 0; + grub_size_t size = 0; + grub_uint8_t *ptr; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + if (!loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); + goto fail; + } + + files = grub_zalloc (argc * sizeof (files[0])); + if (!files) + goto fail; + + for (i = 0; i < argc; i++) + { + grub_file_filter_disable_compression (); + files[i] = grub_file_open (argv[i]); + if (! files[i]) + goto fail; + nfiles++; + size += ALIGN_UP (grub_file_size (files[i]), 4); + } + + initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); + + if (!initrd_mem) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); + goto fail; + } + + params->ramdisk_size = size; + params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem; + + ptr = initrd_mem; + + for (i = 0; i < nfiles; i++) + { + grub_ssize_t cursize = grub_file_size (files[i]); + if (grub_file_read (files[i], ptr, cursize) != cursize) + { + if (!grub_errno) + grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), + argv[i]); + goto fail; + } + ptr += cursize; + grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); + ptr += ALIGN_UP_OVERHEAD (cursize, 4); + } + + params->ramdisk_size = size; + + fail: + for (i = 0; i < nfiles; i++) + grub_file_close (files[i]); + grub_free (files); + + if (initrd_mem && grub_errno) + grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(size)); + + return grub_errno; +} + +static grub_err_t +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file = 0; + struct linux_kernel_header lh; + grub_ssize_t len, start, filelen; + void *kernel; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + file = grub_file_open (argv[0]); + if (! file) + goto fail; + + filelen = grub_file_size (file); + + kernel = grub_malloc(filelen); + + if (!kernel) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); + goto fail; + } + + if (grub_file_read (file, kernel, filelen) != filelen) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]); + goto fail; + } + + if (! grub_linuxefi_secure_validate (kernel, filelen)) + { + grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]); + grub_free (kernel); + goto fail; + } + + grub_file_seek (file, 0); + + grub_free(kernel); + + params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); + + if (! params) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); + goto fail; + } + + memset (params, 0, 16384); + + if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); + goto fail; + } + + if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) + { + grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number")); + goto fail; + } + + if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) + { + grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors")); + goto fail; + } + + if (lh.version < grub_cpu_to_le16 (0x020b)) + { + grub_error (GRUB_ERR_BAD_OS, N_("kernel too old")); + goto fail; + } + + if (!lh.handover_offset) + { + grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover")); + goto fail; + } + + linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, + BYTES_TO_PAGES(lh.cmdline_size + 1)); + + if (!linux_cmdline) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); + goto fail; + } + + grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); + grub_create_loader_cmdline (argc, argv, + linux_cmdline + sizeof (LINUX_IMAGE) - 1, + lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1)); + + lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline; + + handover_offset = lh.handover_offset; + + start = (lh.setup_sects + 1) * 512; + len = grub_file_size(file) - start; + + kernel_mem = grub_efi_allocate_pages(lh.pref_address, + BYTES_TO_PAGES(lh.init_size)); + + if (!kernel_mem) + kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, + BYTES_TO_PAGES(lh.init_size)); + + if (!kernel_mem) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); + goto fail; + } + + if (grub_file_seek (file, start) == (grub_off_t) -1) + { + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); + goto fail; + } + + if (grub_file_read (file, kernel_mem, len) != len && !grub_errno) + { + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); + } + + if (grub_errno == GRUB_ERR_NONE) + { + grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); + loaded = 1; + lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; + } + + memcpy(params, &lh, 2 * 512); + + params->type_of_loader = 0x21; + + fail: + + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); + loaded = 0; + } + + if (linux_cmdline && !loaded) + grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1)); + + if (kernel_mem && !loaded) + grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); + + if (params && !loaded) + grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); + + return grub_errno; +} + +static grub_command_t cmd_linux, cmd_initrd; + +GRUB_MOD_INIT(linuxefi) +{ + cmd_linux = + grub_register_command ("linuxefi", grub_cmd_linux, + 0, N_("Load Linux.")); + cmd_initrd = + grub_register_command ("initrdefi", grub_cmd_initrd, + 0, N_("Load initrd.")); + my_mod = mod; +} + +GRUB_MOD_FINI(linuxefi) +{ + grub_unregister_command (cmd_linux); + grub_unregister_command (cmd_initrd); +} diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index db2169e..a000c38 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -40,6 +40,9 @@ void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds); void * EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, grub_efi_uintn_t pages); +void * +EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max, + grub_efi_uintn_t pages); void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, grub_efi_uintn_t pages); int diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h index da0ca3b..fc36bda 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -139,6 +139,7 @@ struct linux_kernel_header grub_uint64_t setup_data; grub_uint64_t pref_address; grub_uint32_t init_size; + grub_uint32_t handover_offset; } GRUB_PACKED; /* Boot parameters for Linux based on 2.6.12. This is used by the setup debian/patches/no_insmod_on_sb.patch0000664000000000000000000000544612524662415015025 0ustar From 413857c1fcc0626acbdd979e59d787d6ee73e186 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Mon, 13 Jan 2014 12:13:09 +0000 Subject: Don't permit loading modules on UEFI secure boot Author: Colin Watson Origin: vendor, http://pkgs.fedoraproject.org/cgit/grub2.git/tree/grub-2.00-no-insmod-on-sb.patch Forwarded: no Last-Update: 2013-12-25 Patch-Name: no_insmod_on_sb.patch --- grub-core/kern/dl.c | 13 +++++++++++++ grub-core/kern/efi/efi.c | 28 ++++++++++++++++++++++++++++ include/grub/efi/efi.h | 1 + 3 files changed, 42 insertions(+) diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 6850e04..587a316 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -38,6 +38,10 @@ #define GRUB_MODULES_MACHINE_READONLY #endif +#ifdef GRUB_MACHINE_EFI +#include +#endif + #pragma GCC diagnostic ignored "-Wcast-align" @@ -680,6 +684,15 @@ grub_dl_load_file (const char *filename) void *core = 0; grub_dl_t mod = 0; +#ifdef GRUB_MACHINE_EFI + if (grub_efi_secure_boot ()) + { + grub_error (GRUB_ERR_ACCESS_DENIED, + "Secure Boot forbids loading module from %s", filename); + return 0; + } +#endif + grub_boot_time ("Loading module %s", filename); file = grub_file_open (filename); diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index b253141..db0fd2d 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -259,6 +259,34 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, return NULL; } +grub_efi_boolean_t +grub_efi_secure_boot (void) +{ + grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; + grub_size_t datasize; + char *secure_boot = NULL; + char *setup_mode = NULL; + grub_efi_boolean_t ret = 0; + + secure_boot = grub_efi_get_variable ("SecureBoot", &efi_var_guid, &datasize); + + if (datasize != 1 || !secure_boot) + goto out; + + setup_mode = grub_efi_get_variable ("SetupMode", &efi_var_guid, &datasize); + + if (datasize != 1 || !setup_mode) + goto out; + + if (*secure_boot && !*setup_mode) + ret = 1; + + out: + grub_free (secure_boot); + grub_free (setup_mode); + return ret; +} + #pragma GCC diagnostic ignored "-Wcast-align" /* Search the mods section from the PE32/PE32+ image. This code uses diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index 489cf9e..db2169e 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -69,6 +69,7 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, const grub_efi_guid_t *guid, void *data, grub_size_t datasize); +grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); int EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, const grub_efi_device_path_t *dp2); debian/patches/probe_nvme.patch0000664000000000000000000000456512524662415014015 0ustar From 5439f9e3d0ad6929ff3cb2fbe3dc0fd9f2a326e1 Mon Sep 17 00:00:00 2001 From: Dimitri John Ledkov Date: Tue, 29 Apr 2014 16:45:44 +0100 Subject: Add support for nvme device in grub-mkdevicemap Author: Colin Watson Bug-Debian: https://bugs.debian.org/746396 Bug-Ubuntu: https://bugs.launchpad.net/bugs/1275162 Forwarded: no Last-Update: 2014-05-08 Patch-Name: probe_nvme.patch --- grub-core/osdep/linux/getroot.c | 14 ++++++++++++++ util/deviceiter.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c index 6788e39..f97f3a6 100644 --- a/grub-core/osdep/linux/getroot.c +++ b/grub-core/osdep/linux/getroot.c @@ -896,6 +896,20 @@ grub_util_part_to_disk (const char *os_dev, struct stat *st, *pp = '\0'; return path; } + + /* If this is an NVMe device. */ + if (strncmp ("nvme", p, sizeof ("nvme") - 1) == 0) + { + /* /dev/nvme[0-9]+n[0-9]+(p[0-9]+)? */ + p = strchr (p, 'p'); + if (p) + { + *is_part = 1; + *p = '\0'; + } + + return path; + } } return path; diff --git a/util/deviceiter.c b/util/deviceiter.c index b61715d..28dcc25 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -371,6 +371,12 @@ get_fio_disk_name (char *name, int unit) { sprintf (name, "/dev/fio%c", unit + 'a'); } + +static void +get_nvme_disk_name (char *name, int controller, int namespace) +{ + sprintf (name, "/dev/nvme%dn%d", controller, namespace); +} #endif static struct seen_device @@ -875,6 +881,29 @@ grub_util_iterate_devices (int (*hook) (const char *, int, void *), void *hook_d } } + /* This is for standard NVMe controllers + /dev/nvmenp. No idea about + actual limits of how many controllers a system can have and/or + how many namespace that would be, 10 for now. */ + { + int controller, namespace; + + for (controller = 0; controller < 10; controller++) + { + for (namespace = 0; namespace < 10; namespace++) + { + char name[16]; + + get_nvme_disk_name (name, controller, namespace); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + } + } + # ifdef HAVE_DEVICE_MAPPER # define dmraid_check(cond, ...) \ if (! (cond)) \ debian/patches/macbless_mansection.patch0000664000000000000000000000130712524662415015661 0ustar From 4d7721001a0080352388ab9da33ef8c2258caad0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 8 Jan 2014 11:05:20 +0000 Subject: * Makefile.util.def (grub-macbless): Change mansection to 8. Patch-Name: macbless_mansection.patch --- Makefile.util.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.util.def b/Makefile.util.def index e1f6089..691372d 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -422,7 +422,7 @@ program = { program = { name = grub-macbless; installdir = sbin; - mansection = 1; + mansection = 8; common = util/grub-macbless.c; common = grub-core/osdep/init.c; common = grub-core/kern/emu/argp_common.c; debian/patches/disable_floppies.patch0000664000000000000000000000213212524662415015151 0ustar From 83a9421ed05c7aa8431623ab077f8989d9e19db0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:12:54 +0000 Subject: Disable use of floppy devices An ugly kludge. Should this be merged upstream? Author: Robert Millan Patch-Name: disable_floppies.patch --- grub-core/kern/emu/hostdisk.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 44b0fcb..e538b36 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -532,6 +532,18 @@ read_device_map (const char *dev_map) continue; } + if (! strncmp (p, "/dev/fd", sizeof ("/dev/fd") - 1)) + { + char *q = p + sizeof ("/dev/fd") - 1; + if (*q >= '0' && *q <= '9') + { + free (map[drive].drive); + map[drive].drive = NULL; + grub_util_info ("`%s' looks like a floppy drive, skipping", p); + continue; + } + } + /* On Linux, the devfs uses symbolic links horribly, and that confuses the interface very much, so use realpath to expand symbolic links. */ debian/patches/check_blocklists_overlap_fix.patch0000664000000000000000000000327712600650747017564 0ustar From 2549deb51c3636669b42370c1b2a5c7091016420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D0=BE=D0=BC=D0=B0=D0=BD=20=D0=9F=D0=B5=D1=85=D0=BE?= =?UTF-8?q?=D0=B2?= Date: Sun, 22 Jun 2014 03:51:50 +0400 Subject: * grub-core/commands/loadenv.c (check_blocklists): Fix overlap check. Bug: http://savannah.gnu.org/bugs/?42134 Bug-Ubuntu: https://bugs.launchpad.net/bugs/1311247 Origin: upstream, http://git.savannah.gnu.org/cgit/grub.git/commit/?id=1f6af2a9f8b02a71f213b4717d8e62c8a6b14fc5 Last-Update: 2015-01-23 Patch-Name: check_blocklists_overlap_fix.patch --- grub-core/commands/loadenv.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c index 6af8112..acd93d1 100644 --- a/grub-core/commands/loadenv.c +++ b/grub-core/commands/loadenv.c @@ -263,7 +263,7 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, for (q = p->next; q; q = q->next) { grub_disk_addr_t s1, s2; - grub_disk_addr_t e1, e2, t; + grub_disk_addr_t e1, e2; s1 = p->sector; e1 = s1 + ((p->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); @@ -271,16 +271,7 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, s2 = q->sector; e2 = s2 + ((q->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - if (s2 > s1) - { - t = s2; - s2 = s1; - s1 = t; - t = e2; - e2 = e1; - e1 = t; - } - if (e1 > s2) + if (s1 < e2 && s2 < e1) { /* This might be actually valid, but it is unbelievable that any filesystem makes such a silly allocation. */ debian/patches/linuxefi_non_sb_fallback.patch0000664000000000000000000000640112524662415016650 0ustar From 34d4893c33d118806ebde0a0efbc6c2cd1687dcc Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:20 +0000 Subject: If running under UEFI secure boot, attempt to use linuxefi loader Author: Steve Langasek Forwarded: no Last-Update: 2013-12-20 Patch-Name: linuxefi_non_sb_fallback.patch --- grub-core/loader/i386/efi/linux.c | 2 +- grub-core/loader/i386/linux.c | 43 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c index 26a958c..eb4ba96 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -234,7 +234,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (! grub_linuxefi_secure_validate (kernel, filelen)) { - grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]); + grub_error (GRUB_ERR_ACCESS_DENIED, N_("%s has invalid signature"), argv[0]); grub_free (kernel); goto fail; } diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 31fb91e..2380642 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -76,6 +76,8 @@ static grub_size_t maximal_cmdline_size; static struct linux_kernel_params linux_params; static char *linux_cmdline; #ifdef GRUB_MACHINE_EFI +static int using_linuxefi; +static grub_command_t initrdefi_cmd; static grub_efi_uintn_t efi_mmap_size; #else static const grub_size_t efi_mmap_size = 0; @@ -690,6 +692,41 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_dl_ref (my_mod); +#ifdef GRUB_MACHINE_EFI + using_linuxefi = 0; + if (grub_efi_secure_boot ()) + { + /* Try linuxefi first, which will require a successful signature check + and then hand over to the kernel without calling ExitBootServices. + If that fails, however, fall back to calling ExitBootServices + ourselves and then booting an unsigned kernel. */ + grub_dl_t mod; + grub_command_t linuxefi_cmd; + + grub_dprintf ("linux", "Secure Boot enabled: trying linuxefi\n"); + + mod = grub_dl_load ("linuxefi"); + if (mod) + { + grub_dl_ref (mod); + linuxefi_cmd = grub_command_find ("linuxefi"); + initrdefi_cmd = grub_command_find ("initrdefi"); + if (linuxefi_cmd && initrdefi_cmd) + { + (linuxefi_cmd->func) (linuxefi_cmd, argc, argv); + if (grub_errno == GRUB_ERR_NONE) + { + grub_dprintf ("linux", "Handing off to linuxefi\n"); + using_linuxefi = 1; + return GRUB_ERR_NONE; + } + grub_dprintf ("linux", "linuxefi failed (%d)\n", grub_errno); + grub_errno = GRUB_ERR_NONE; + } + } + } +#endif + if (argc == 0) { grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); @@ -1052,6 +1089,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), grub_err_t err; struct grub_linux_initrd_context initrd_ctx; +#ifdef GRUB_MACHINE_EFI + /* If we're using linuxefi, just forward to initrdefi. */ + if (using_linuxefi && initrdefi_cmd) + return (initrdefi_cmd->func) (initrdefi_cmd, argc, argv); +#endif + if (argc == 0) { grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); debian/patches/install_signed.patch0000664000000000000000000002023012524662415014643 0ustar From 60122fc484c274c0a49565a6d6c1ee7658aba208 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:22 +0000 Subject: Install signed images if UEFI Secure Boot is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Author: Stéphane Graber Author: Steve Langasek Forwarded: no Last-Update: 2014-03-31 Patch-Name: install_signed.patch --- util/grub-install.c | 169 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 122 insertions(+), 47 deletions(-) diff --git a/util/grub-install.c b/util/grub-install.c index 3275209..0d77a2a 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -80,6 +80,7 @@ static char *label_color; static char *label_bgcolor; static char *product_version; static int add_rs_codes = 1; +static int uefi_secure_boot = 1; enum { @@ -111,7 +112,9 @@ enum OPTION_LABEL_FONT, OPTION_LABEL_COLOR, OPTION_LABEL_BGCOLOR, - OPTION_PRODUCT_VERSION + OPTION_PRODUCT_VERSION, + OPTION_UEFI_SECURE_BOOT, + OPTION_NO_UEFI_SECURE_BOOT }; static int fs_probe = 1; @@ -235,6 +238,14 @@ argp_parser (int key, char *arg, struct argp_state *state) bootloader_id = xstrdup (arg); return 0; + case OPTION_UEFI_SECURE_BOOT: + uefi_secure_boot = 1; + return 0; + + case OPTION_NO_UEFI_SECURE_BOOT: + uefi_secure_boot = 0; + return 0; + case ARGP_KEY_ARG: if (install_device) grub_util_error ("%s", _("More than one install device?")); @@ -304,6 +315,14 @@ static struct argp_option options[] = { {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2}, {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2}, {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2}, + {"uefi-secure-boot", OPTION_UEFI_SECURE_BOOT, 0, 0, + N_("install an image usable with UEFI Secure Boot. " + "This option is only available on EFI and if the grub-efi-amd64-signed " + "package is installed."), 2}, + {"no-uefi-secure-boot", OPTION_NO_UEFI_SECURE_BOOT, 0, 0, + N_("do not install an image usable with UEFI Secure Boot, even if the " + "system was currently started using it. " + "This option is only available on EFI."), 2}, {0, 0, 0, 0, 0, 0} }; @@ -809,7 +828,8 @@ main (int argc, char *argv[]) { int is_efi = 0; const char *efi_distributor = NULL; - const char *efi_file = NULL; + const char *efi_suffix = NULL, *efi_suffix_upper = NULL; + char *efi_file = NULL; char **grub_devices; grub_fs_t grub_fs; grub_device_t grub_dev = NULL; @@ -1069,6 +1089,31 @@ main (int argc, char *argv[]) */ char *t; efi_distributor = bootloader_id; + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + efi_suffix = "ia32"; + efi_suffix_upper = "IA32"; + break; + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + efi_suffix = "x64"; + efi_suffix_upper = "X64"; + break; + case GRUB_INSTALL_PLATFORM_IA64_EFI: + efi_suffix = "ia64"; + efi_suffix_upper = "IA64"; + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + efi_suffix = "arm"; + efi_suffix_upper = "ARM"; + break; + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + efi_suffix = "arm64"; + efi_suffix_upper = "AARCH64"; + break; + default: + break; + } if (removable) { /* The specification makes stricter requirements of removable @@ -1077,54 +1122,16 @@ main (int argc, char *argv[]) must have a specific file name depending on the architecture. */ efi_distributor = "BOOT"; - switch (platform) - { - case GRUB_INSTALL_PLATFORM_I386_EFI: - efi_file = "BOOTIA32.EFI"; - break; - case GRUB_INSTALL_PLATFORM_X86_64_EFI: - efi_file = "BOOTX64.EFI"; - break; - case GRUB_INSTALL_PLATFORM_IA64_EFI: - efi_file = "BOOTIA64.EFI"; - break; - case GRUB_INSTALL_PLATFORM_ARM_EFI: - efi_file = "BOOTARM.EFI"; - break; - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - efi_file = "BOOTAARCH64.EFI"; - break; - default: - grub_util_error ("%s", _("You've found a bug")); - break; - } + if (!efi_suffix) + grub_util_error ("%s", _("You've found a bug")); + efi_file = xasprintf ("BOOT%s.EFI", efi_suffix_upper); } else { /* It is convenient for each architecture to have a different efi_file, so that different versions can be installed in parallel. */ - switch (platform) - { - case GRUB_INSTALL_PLATFORM_I386_EFI: - efi_file = "grubia32.efi"; - break; - case GRUB_INSTALL_PLATFORM_X86_64_EFI: - efi_file = "grubx64.efi"; - break; - case GRUB_INSTALL_PLATFORM_IA64_EFI: - efi_file = "grubia64.efi"; - break; - case GRUB_INSTALL_PLATFORM_ARM_EFI: - efi_file = "grubarm.efi"; - break; - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - efi_file = "grubarm64.efi"; - break; - default: - efi_file = "grub.efi"; - break; - } + efi_file = xasprintf ("grub%s.efi", efi_suffix); } t = grub_util_path_concat (3, efidir, "EFI", efi_distributor); free (efidir); @@ -1329,14 +1336,40 @@ main (int argc, char *argv[]) } } - if (!have_abstractions) + char *efi_signed = NULL; + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + { + char *dir = xasprintf ("%s-signed", grub_install_source_directory); + char *signed_image; + if (removable) + signed_image = xasprintf ("gcd%s.efi.signed", efi_suffix); + else + signed_image = xasprintf ("grub%s.efi.signed", efi_suffix); + efi_signed = grub_util_path_concat (2, dir, signed_image); + break; + } + + default: + break; + } + + if (!efi_signed || !grub_util_is_regular (efi_signed)) + uefi_secure_boot = 0; + + if (!have_abstractions || uefi_secure_boot) { if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0) || grub_drives[1] || (!install_drive && platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275) || (install_drive && !is_same_disk (grub_drives[0], install_drive)) - || !have_bootdev (platform)) + || !have_bootdev (platform) + || uefi_secure_boot) { char *uuid = NULL; /* generic method (used on coreboot and ata mod). */ @@ -1857,7 +1890,49 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_IA64_EFI: { char *dst = grub_util_path_concat (2, efidir, efi_file); - grub_install_copy_file (imgfile, dst, 1); + if (uefi_secure_boot) + { + const char *shim_signed = "/usr/lib/shim/shim.efi.signed"; + char *config_dst; + FILE *config_dst_f; + + if (grub_util_is_regular (shim_signed)) + { + char *chained_base, *chained_dst, *mok_signed; + if (!removable) + { + free (efi_file); + efi_file = xasprintf ("shim%s.efi", efi_suffix); + free (dst); + dst = grub_util_path_concat (2, efidir, efi_file); + } + grub_install_copy_file (shim_signed, dst, 1); + chained_base = xasprintf ("grub%s.efi", efi_suffix); + chained_dst = grub_util_path_concat (2, efidir, chained_base); + grub_install_copy_file (efi_signed, chained_dst, 1); + /* Not critical, so not an error if it's not present (as it + won't be for older releases); but if we have it, make + sure it's installed. */ + mok_signed = grub_util_path_concat (2, efidir, + "MokManager.efi"); + grub_install_copy_file ("/usr/lib/shim/MokManager.efi.signed", + mok_signed, 0); + free (mok_signed); + free (chained_dst); + free (chained_base); + } + else + grub_install_copy_file (efi_signed, dst, 1); + + config_dst = grub_util_path_concat (2, efidir, "grub.cfg"); + grub_install_copy_file (load_cfg, config_dst, 1); + config_dst_f = grub_util_fopen (config_dst, "ab"); + fprintf (config_dst_f, "configfile $prefix/grub.cfg\n"); + fclose (config_dst_f); + free (config_dst); + } + else + grub_install_copy_file (imgfile, dst, 1); free (dst); } if (!removable && update_nvram) debian/patches/gfxpayload_keep_default.patch0000664000000000000000000000312712524662415016520 0ustar From e69dcbb40c2856ca7b0c9efea09a66cbf975d5b4 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:12:57 +0000 Subject: Disable gfxpayload=keep by default Setting gfxpayload=keep has been known to cause efifb to be inappropriately enabled. In any case, with the current Linux kernel the result of this option is that early kernelspace will be unable to print anything to the console, so (for example) if boot fails and you end up dumped to an initramfs prompt, you won't be able to see anything on the screen. As such it shouldn't be enabled by default in Debian, no matter what kernel options are enabled. gfxpayload=keep is a good idea but rather ahead of its time ... Bug-Debian: http://bugs.debian.org/567245 Forwarded: no Last-Update: 2013-12-25 Patch-Name: gfxpayload_keep_default.patch --- util/grub.d/10_linux.in | 4 ---- 1 file changed, 4 deletions(-) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 00d1931..a9f9b31 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -102,10 +102,6 @@ linux_entry () # FIXME: We need an interface to select vesafb in case efifb can't be used. if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then echo " load_video" | sed "s/^/$submenu_indentation/" - if grep -qx "CONFIG_FB_EFI=y" "${config}" 2> /dev/null \ - && grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" "${config}" 2> /dev/null; then - echo " set gfxpayload=keep" | sed "s/^/$submenu_indentation/" - fi else if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then echo " load_video" | sed "s/^/$submenu_indentation/" debian/patches/wubi_no_windows.patch0000664000000000000000000000325512524662415015070 0ustar From 903b3f130de1737e602bab3738a045e2f1acde77 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:24 +0000 Subject: Skip Windows os-prober entries on Wubi systems Since we're already being booted from the Windows boot loader, including entries that take us back to it mostly just causes confusion, and stops us from being able to hide the menu if there are no other OSes installed. https://blueprints.launchpad.net/ubuntu/+spec/foundations-o-wubi Forwarded: not-needed Last-Update: 2013-11-26 Patch-Name: wubi_no_windows.patch --- util/grub.d/30_os-prober.in | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index f8ac363..1c44cf2 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -107,6 +107,8 @@ EOF used_osprober_linux_ids= +wubi= + for OS in ${OSPROBED} ; do DEVICE="`echo ${OS} | cut -d ':' -f 1`" LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`" @@ -139,6 +141,23 @@ for OS in ${OSPROBED} ; do case ${BOOT} in chain) + case ${LONGNAME} in + Windows*) + if [ -z "$wubi" ]; then + if [ -x /usr/share/lupin-support/grub-mkimage ] && \ + /usr/share/lupin-support/grub-mkimage --test; then + wubi=yes + else + wubi=no + fi + fi + if [ "$wubi" = yes ]; then + echo "Skipping ${LONGNAME} on Wubi system" >&2 + continue + fi + ;; + esac + onstr="$(gettext_printf "(on %s)" "${DEVICE}")" cat << EOF menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class windows --class os \$menuentry_id_option 'osprober-chain-$(grub_get_device_id "${DEVICE}")' { debian/patches/linuxefi_debug.patch0000664000000000000000000000557312524662415014652 0ustar From 935cb0d861b3e0a0ab9340f7f1527fa1d0d388af Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:18 +0000 Subject: Add more debugging to linuxefi Forwarded: no Last-Update: 2013-01-29 Patch-Name: linuxefi_debug.patch --- grub-core/loader/i386/efi/linux.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c index b79e632..a124c5e 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -54,15 +55,27 @@ grub_linuxefi_secure_validate (void *data, grub_uint32_t size) { grub_efi_guid_t guid = SHIM_LOCK_GUID; grub_efi_shim_lock_t *shim_lock; + grub_efi_status_t status; + grub_dprintf ("linuxefi", "Locating shim protocol\n"); shim_lock = grub_efi_locate_protocol(&guid, NULL); if (!shim_lock) - return 1; + { + grub_dprintf ("linuxefi", "shim not available\n"); + return 1; + } - if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS) - return 1; + grub_dprintf ("linuxefi", "Asking shim to verify kernel signature\n"); + status = shim_lock->verify(data, size); + if (status == GRUB_EFI_SUCCESS) + { + grub_dprintf ("linuxefi", "Kernel signature verification passed\n"); + return 1; + } + grub_dprintf ("linuxefi", "Kernel signature verification failed (0x%lx)\n", + (unsigned long) status); return 0; } @@ -147,6 +160,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), goto fail; } + grub_dprintf ("linuxefi", "initrd_mem = %lx\n", (unsigned long) initrd_mem); + params->ramdisk_size = size; params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem; @@ -236,6 +251,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } + grub_dprintf ("linuxefi", "params = %lx\n", (unsigned long) params); + memset (params, 0, 16384); if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) @@ -279,6 +296,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } + grub_dprintf ("linuxefi", "linux_cmdline = %lx\n", + (unsigned long) linux_cmdline); + grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); grub_create_loader_cmdline (argc, argv, linux_cmdline + sizeof (LINUX_IMAGE) - 1, @@ -304,6 +324,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } + grub_dprintf ("linuxefi", "kernel_mem = %lx\n", (unsigned long) kernel_mem); + if (grub_file_seek (file, start) == (grub_off_t) -1) { grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), debian/patches/mkrescue_efi_modules.patch0000664000000000000000000000272512524662415016046 0ustar From 901f9c3dfb7bd2954b6351e3b086e07d14f2d66c Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 13 Jan 2014 12:12:59 +0000 Subject: Build part_msdos and vfat into EFI boot images Author: Colin Watson Bug-Ubuntu: https://bugs.launchpad.net/bugs/677758 Forwarded: http://lists.gnu.org/archive/html/grub-devel/2011-01/msg00028.html Last-Update: 2013-12-25 Patch-Name: mkrescue_efi_modules.patch --- util/grub-mkrescue.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index 317879d..cf698ff 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -653,12 +653,18 @@ main (int argc, char *argv[]) make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64-efi", imgname); free (imgname); + grub_install_push_module ("part_msdos"); + grub_install_push_module ("fat"); + img64 = grub_util_path_concat (2, efidir_efi_boot, "bootx64.efi"); make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64-efi", img64); img32 = grub_util_path_concat (2, efidir_efi_boot, "bootia32.efi"); make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_I386_EFI, "i386-efi", img32); + grub_install_pop_module (); + grub_install_pop_module (); + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootarm.efi"); make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM_EFI, "arm-efi", imgname); free (imgname); debian/patches/grub-shell-no-pad.patch0000664000000000000000000000261112524662415015067 0ustar From bf38ce6ea0f81f27367deaa631131ef8fafe7e8a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 16 Jan 2014 12:51:23 +0000 Subject: grub-shell: Pass -no-pad to xorriso when building floppy images The floppy images built by grub-shell are currently just over the floppy limit, and the Debian patch set plus the 915resolution extra bring this up to the point where GRUB tries to actually read past the floppy limit, breaking fddboot_test. Passing -no-pad buys us 300KiB, which should keep us going for a while. * tests/util/grub-shell.in: Pass -no-pad to xorriso when building floppy images, saving 300KiB. Forwarded: https://lists.gnu.org/archive/html/grub-devel/2014-01/msg00074.html Last-Update: 2014-01-16 Patch-Name: grub-shell-no-pad.patch --- tests/util/grub-shell.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index d9a5253..6f13591 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -346,6 +346,10 @@ if test -z "$debug"; then qemuopts="${qemuopts} -nographic -monitor file:/dev/null" fi +if [ x$boot = xfd ]; then + mkrescue_args="${mkrescue_args} -- -no-pad" +fi + if [ x$boot != xnet ] && [ x$boot != xemu ]; then pkgdatadir="@builddir@" "@builddir@/grub-mkrescue" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \ --rom-directory="${rom_directory}" \ debian/patches/efinet-open-Simple-Network-Protocol-exclusively.patch0000664000000000000000000000463312625413255023113 0ustar From 99d5df36311e15d60a16f6cba6e3b4ca442b0472 Mon Sep 17 00:00:00 2001 From: Andrei Borzenkov Date: Thu, 7 May 2015 20:37:17 +0300 Subject: efinet: open Simple Network Protocol exclusively Patch-Name: efinet-open-Simple-Network-Protocol-exclusively.patch Origin: upstream, http://git.savannah.gnu.org/cgit/grub.git/commit/?id=49426e9fd2e562c73a4f1206f32eff9e424a1a73 Bug-Ubuntu: https://bugs.launchpad.net/bugs/1508893 Last-Update: 2015-11-25 --- grub-core/net/drivers/efi/efinet.c | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c index 2b344d6..658b3d1 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c @@ -130,9 +130,55 @@ get_card_packet (struct grub_net_card *dev) return nb; } +static grub_err_t +open_card (struct grub_net_card *dev) +{ + grub_efi_simple_network_t *net; + + /* Try to reopen SNP exlusively to close any active MNP protocol instance + that may compete for packet polling + */ + net = grub_efi_open_protocol (dev->efi_handle, &net_io_guid, + GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE); + if (net) + { + if (net->mode->state == GRUB_EFI_NETWORK_STOPPED + && efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net start failed", + dev->name); + + if (net->mode->state == GRUB_EFI_NETWORK_STOPPED) + return grub_error (GRUB_ERR_NET_NO_CARD, "%s: card stopped", + dev->name); + + if (net->mode->state == GRUB_EFI_NETWORK_STARTED + && efi_call_3 (net->initialize, net, 0, 0) != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net initialize failed", + dev->name); + + efi_call_4 (grub_efi_system_table->boot_services->close_protocol, + dev->efi_net, &net_io_guid, + grub_efi_image_handle, dev->efi_handle); + dev->efi_net = net; + } + + /* If it failed we just try to run as best as we can */ + return GRUB_ERR_NONE; +} + +static void +close_card (struct grub_net_card *dev) +{ + efi_call_4 (grub_efi_system_table->boot_services->close_protocol, + dev->efi_net, &net_io_guid, + grub_efi_image_handle, dev->efi_handle); +} + static struct grub_net_card_driver efidriver = { .name = "efinet", + .open = open_card, + .close = close_card, .send = send_card_buffer, .recv = get_card_packet }; debian/patches/skip_gettext_strings_test.patch0000664000000000000000000000136212524662415017173 0ustar From 8cf057b2d09e1831c422521b9d63f1e84ece036a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:34 +0000 Subject: Don't run gettext_strings_test This test is mainly useful as an upstream maintenance check. Forwarded: not-needed Last-Update: 2013-12-23 Patch-Name: skip_gettext_strings_test.patch --- tests/gettext_strings_test.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/gettext_strings_test.in b/tests/gettext_strings_test.in index 5c305e7..15405cf 100644 --- a/tests/gettext_strings_test.in +++ b/tests/gettext_strings_test.in @@ -1,5 +1,8 @@ #!/bin/sh +echo "Skipping upstream maintenance check." +exit 77 + cd '@srcdir@' tdir="$(mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")" debian/patches/btrfs-endian.patch0000664000000000000000000000221612524662415014224 0ustar From 2efb97d0215ecb284faefcd09f0012f2bf2fec4a Mon Sep 17 00:00:00 2001 From: Thomas Falcon Date: Mon, 31 Mar 2014 15:32:30 +0100 Subject: btrfs: fix get_root key comparison failures due to endianness * grub-core/fs/btrfs.c (get_root): Convert GRUB_BTRFS_ROOT_VOL_OBJECTID to little-endian. Origin: upstream, http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commitdiff;h=4afd0107efa6a2d9cbe6fc71c529264dc2b9fb8a Forwarded: not-needed Last-Update: 2014-03-31 Patch-Name: btrfs-endian.patch --- grub-core/fs/btrfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 89666b6..f7b6c15 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -1201,7 +1201,7 @@ get_root (struct grub_btrfs_data *data, struct grub_btrfs_key *key, struct grub_btrfs_key key_out, key_in; struct grub_btrfs_root_item ri; - key_in.object_id = GRUB_BTRFS_ROOT_VOL_OBJECTID; + key_in.object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_ROOT_VOL_OBJECTID); key_in.offset = 0; key_in.type = GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM; err = lower_bound (data, &key_in, &key_out, debian/patches/net-ramp-up-interval.patch0000664000000000000000000000666112524662415015647 0ustar From c7968962ae59204cb6ffb4b46b115db592cb578e Mon Sep 17 00:00:00 2001 From: Paulo Flabiano Smorigo Date: Tue, 21 Jan 2014 11:03:51 -0200 Subject: increase network try interval gradually * grub-core/net/arp.c (grub_net_arp_send_request): Increase network try interval gradually. * grub-core/net/icmp6.c (grub_net_icmp6_send_request): Likewise. * grub-core/net/net.c (grub_net_fs_read_real): Likewise. * grub-core/net/tftp.c (tftp_open): Likewise. * include/grub/net.h (GRUB_NET_INTERVAL_ADDITION): New define. Origin: upstream, http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commitdiff;h=6f65e36cc4f92fe40672181eccf12eac4afb6738 Bug-Ubuntu: https://bugs.launchpad.net/bugs/1314134 Last-Update: 2014-04-29 Patch-Name: net-ramp-up-interval.patch --- grub-core/net/arp.c | 3 ++- grub-core/net/icmp6.c | 3 ++- grub-core/net/net.c | 5 +++-- grub-core/net/tftp.c | 3 ++- include/grub/net.h | 1 + 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index e92c7e7..d62d0cc 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -110,7 +110,8 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf, return GRUB_ERR_NONE; pending_req = proto_addr->ipv4; have_pending = 0; - grub_net_poll_cards (GRUB_NET_INTERVAL, &have_pending); + grub_net_poll_cards (GRUB_NET_INTERVAL + (i * GRUB_NET_INTERVAL_ADDITION), + &have_pending); if (grub_net_link_layer_resolve_check (inf, proto_addr)) return GRUB_ERR_NONE; nb.data = nbd; diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c index 2741e6f..bbc9020 100644 --- a/grub-core/net/icmp6.c +++ b/grub-core/net/icmp6.c @@ -518,7 +518,8 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf, { if (grub_net_link_layer_resolve_check (inf, proto_addr)) break; - grub_net_poll_cards (GRUB_NET_INTERVAL, 0); + grub_net_poll_cards (GRUB_NET_INTERVAL + (i * GRUB_NET_INTERVAL_ADDITION), + 0); if (grub_net_link_layer_resolve_check (inf, proto_addr)) break; nb->data = nbd; diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 56355f3..1521d8d 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -1558,8 +1558,9 @@ grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len) if (!net->eof) { try++; - grub_net_poll_cards (GRUB_NET_INTERVAL, &net->stall); - } + grub_net_poll_cards (GRUB_NET_INTERVAL + + (try * GRUB_NET_INTERVAL_ADDITION), &net->stall); + } else return total; } diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 9c489f1..5173614 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -398,7 +398,8 @@ tftp_open (struct grub_file *file, const char *filename) destroy_pq (data); return err; } - grub_net_poll_cards (GRUB_NET_INTERVAL, &data->have_oack); + grub_net_poll_cards (GRUB_NET_INTERVAL + (i * GRUB_NET_INTERVAL_ADDITION), + &data->have_oack); if (data->have_oack) break; } diff --git a/include/grub/net.h b/include/grub/net.h index de6259e..0e0a605 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -532,5 +532,6 @@ extern char *grub_net_default_server; #define GRUB_NET_TRIES 40 #define GRUB_NET_INTERVAL 400 +#define GRUB_NET_INTERVAL_ADDITION 20 #endif /* ! GRUB_NET_HEADER */ debian/patches/maybe_quiet.patch0000664000000000000000000002603512524662415014161 0ustar From 63e1dfabb116c7582721d4d6ae94749541abfbf4 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:26 +0000 Subject: Add configure option to reduce visual clutter at boot time If this option is enabled, then do all of the following: Don't display introductory message about line editing unless we're actually offering a shell prompt. (This is believed to be a workaround for a different bug. We'll go with this for now, but will drop this in favour of a better fix upstream if somebody figures out what that is.) Don't clear the screen just before booting if we never drew the menu in the first place. Remove verbose messages printed before reading configuration. In some ways this is awkward because it makes debugging harder, but it's a requirement for a smooth-looking boot process; we may be able to do better in future. Upstream doesn't want this, though. Disable the cursor as well, for similar reasons of tidiness. Suppress kernel/initrd progress messages, except in recovery mode. Suppress "GRUB loading" message unless Shift is held down. Upstream doesn't want this, as it makes debugging harder. Ubuntu wants it to provide a cleaner boot experience. Bug-Ubuntu: https://bugs.launchpad.net/bugs/386922 Bug-Ubuntu: https://bugs.launchpad.net/bugs/861048 Forwarded: (partial) http://lists.gnu.org/archive/html/grub-devel/2009-09/msg00056.html Last-Update: 2014-01-03 Patch-Name: maybe_quiet.patch --- config.h.in | 2 ++ configure.ac | 16 ++++++++++++++++ grub-core/boot/i386/pc/boot.S | 11 +++++++++++ grub-core/boot/i386/pc/diskboot.S | 26 ++++++++++++++++++++++++++ grub-core/kern/main.c | 17 +++++++++++++++++ grub-core/kern/rescue_reader.c | 2 ++ grub-core/normal/main.c | 11 +++++++++++ grub-core/normal/menu.c | 17 +++++++++++++++-- util/grub.d/10_linux.in | 15 +++++++++++---- 9 files changed, 111 insertions(+), 6 deletions(-) diff --git a/config.h.in b/config.h.in index 4b63014..247cf11 100644 --- a/config.h.in +++ b/config.h.in @@ -11,6 +11,8 @@ /* Define to 1 to enable disk cache statistics. */ #define DISK_CACHE_STATS @DISK_CACHE_STATS@ #define BOOT_TIME_STATS @BOOT_TIME_STATS@ +/* Define to 1 to make GRUB quieter at boot time. */ +#define QUIET_BOOT @QUIET_BOOT@ #if defined (GRUB_BUILD) #undef ENABLE_NLS diff --git a/configure.ac b/configure.ac index fb4e2dd..7c8d0af 100644 --- a/configure.ac +++ b/configure.ac @@ -1583,6 +1583,17 @@ else fi AC_SUBST([UBUNTU_RECOVERY]) +AC_ARG_ENABLE([quiet-boot], + [AS_HELP_STRING([--enable-quiet-boot], + [emit fewer messages at boot time (default=no)])], + [], [enable_quiet_boot=no]) +if test x"$enable_quiet_boot" = xyes ; then + QUIET_BOOT=1 +else + QUIET_BOOT=0 +fi +AC_SUBST([QUIET_BOOT]) + LIBS="" AC_SUBST([FONT_SOURCE]) @@ -1837,5 +1848,10 @@ echo "Without liblzma (no support for XZ-compressed mips images) ($liblzma_excus else echo "With liblzma from $LIBLZMA (support for XZ-compressed mips images)" fi +if [ x"$enable_quiet_boot" = xyes ]; then +echo With quiet boot: Yes +else +echo With quiet boot: No +fi echo "*******************************************************" ] diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S index b4975e2..7ebd96b 100644 --- a/grub-core/boot/i386/pc/boot.S +++ b/grub-core/boot/i386/pc/boot.S @@ -19,6 +19,9 @@ #include #include +#if defined(QUIET_BOOT) && !defined(HYBRID_BOOT) +#include +#endif /* * defines for the code go here @@ -249,9 +252,17 @@ real_start: /* save drive reference first thing! */ pushw %dx +#if defined(QUIET_BOOT) && !defined(HYBRID_BOOT) + /* is either shift key held down? */ + movw $(GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR + 0x17), %bx + testb $3, (%bx) + jz 2f +#endif + /* print a notification message on the screen */ MSG(notification_string) +2: /* set %si to the disk address packet */ movw $disk_address_packet, %si diff --git a/grub-core/boot/i386/pc/diskboot.S b/grub-core/boot/i386/pc/diskboot.S index d030a14..7534991 100644 --- a/grub-core/boot/i386/pc/diskboot.S +++ b/grub-core/boot/i386/pc/diskboot.S @@ -18,6 +18,9 @@ #include #include +#ifdef QUIET_BOOT +#include +#endif /* * defines for the code go here @@ -25,6 +28,12 @@ #define MSG(x) movw $x, %si; call LOCAL(message) +#ifdef QUIET_BOOT +#define SILENT(x) call LOCAL(check_silent); jz LOCAL(x) +#else +#define SILENT(x) +#endif + .file "diskboot.S" .text @@ -50,11 +59,14 @@ _start: /* save drive reference first thing! */ pushw %dx + SILENT(after_notification_string) + /* print a notification message on the screen */ pushw %si MSG(notification_string) popw %si +LOCAL(after_notification_string): /* this sets up for the first run through "bootloop" */ movw $LOCAL(firstlist), %di @@ -279,7 +291,10 @@ LOCAL(copy_buffer): /* restore addressing regs and print a dot with correct DS (MSG modifies SI, which is saved, and unused AX and BX) */ popw %ds + SILENT(after_notification_step) MSG(notification_step) + +LOCAL(after_notification_step): popa /* check if finished with this dataset */ @@ -295,8 +310,11 @@ LOCAL(copy_buffer): /* END OF MAIN LOOP */ LOCAL(bootit): + SILENT(after_notification_done) /* print a newline */ MSG(notification_done) + +LOCAL(after_notification_done): popw %dx /* this makes sure %dl is our "boot" drive */ ljmp $0, $(GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200) @@ -320,6 +338,14 @@ LOCAL(general_error): /* go here when you need to stop the machine hard after an error condition */ LOCAL(stop): jmp LOCAL(stop) +#ifdef QUIET_BOOT +LOCAL(check_silent): + /* is either shift key held down? */ + movw $(GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR + 0x17), %bx + testb $3, (%bx) + ret +#endif + notification_string: .asciz "loading" notification_step: .asciz "." diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 9cad0c4..5613cd5 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -264,15 +264,25 @@ reclaim_module_space (void) void __attribute__ ((noreturn)) grub_main (void) { +#ifdef QUIET_BOOT + struct grub_term_output *term; +#endif + /* First of all, initialize the machine. */ grub_machine_init (); grub_boot_time ("After machine init."); +#ifdef QUIET_BOOT + /* Disable the cursor until we need it. */ + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_term_setcursor (term, 0); +#else /* Hello. */ grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); grub_printf ("Welcome to GRUB!\n\n"); grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); +#endif grub_load_config (); @@ -308,5 +318,12 @@ grub_main (void) grub_boot_time ("After execution of embedded config. Attempt to go to normal mode"); grub_load_normal_mode (); + +#ifdef QUIET_BOOT + /* If we have to enter rescue mode, enable the cursor again. */ + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_term_setcursor (term, 1); +#endif + grub_rescue_run (); } diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c index dcd7d44..03826cf 100644 --- a/grub-core/kern/rescue_reader.c +++ b/grub-core/kern/rescue_reader.c @@ -78,7 +78,9 @@ grub_rescue_read_line (char **line, int cont, void __attribute__ ((noreturn)) grub_rescue_run (void) { +#ifdef QUIET_BOOT grub_printf ("Entering rescue mode...\n"); +#endif while (1) { diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index c36663f..99622cb 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -381,6 +381,15 @@ static grub_err_t grub_normal_read_line_real (char **line, int cont, int nested) { const char *prompt; +#ifdef QUIET_BOOT + static int displayed_intro; + + if (! displayed_intro) + { + grub_normal_reader_init (nested); + displayed_intro = 1; + } +#endif if (cont) /* TRANSLATORS: it's command line prompt. */ @@ -429,7 +438,9 @@ grub_cmdline_run (int nested) return; } +#ifndef QUIET_BOOT grub_normal_reader_init (nested); +#endif while (1) { diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index 2723547..7b55c27 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -826,12 +826,18 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) /* Callback invoked immediately before a menu entry is executed. */ static void -notify_booting (grub_menu_entry_t entry, +notify_booting (grub_menu_entry_t entry +#ifdef QUIET_BOOT + __attribute__((unused)) +#endif + , void *userdata __attribute__((unused))) { +#ifndef QUIET_BOOT grub_printf (" "); grub_printf_ (N_("Booting `%s'"), entry->title); grub_printf ("\n\n"); +#endif } /* Callback invoked when a default menu entry executed because of a timeout @@ -879,6 +885,9 @@ show_menu (grub_menu_t menu, int nested, int autobooted) int boot_entry; grub_menu_entry_t e; int auto_boot; +#ifdef QUIET_BOOT + int initial_timeout = grub_menu_get_timeout (); +#endif boot_entry = run_menu (menu, nested, &auto_boot); if (boot_entry < 0) @@ -888,7 +897,11 @@ show_menu (grub_menu_t menu, int nested, int autobooted) if (! e) continue; /* Menu is empty. */ - grub_cls (); +#ifdef QUIET_BOOT + /* Only clear the screen if we drew the menu in the first place. */ + if (initial_timeout != 0) +#endif + grub_cls (); if (auto_boot) grub_menu_execute_with_fallback (menu, e, autobooted, diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 1b55116..0616c6d 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -21,6 +21,7 @@ prefix="@prefix@" exec_prefix="@exec_prefix@" datarootdir="@datarootdir@" ubuntu_recovery="@UBUNTU_RECOVERY@" +quiet_boot="@QUIET_BOOT@" . "@datadir@/@PACKAGE@/grub-mkconfig_lib" @@ -146,10 +147,12 @@ linux_entry () fi printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" fi - message="$(gettext_printf "Loading Linux %s ..." ${version})" - sed "s/^/$submenu_indentation/" << EOF + if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then + message="$(gettext_printf "Loading Linux %s ..." ${version})" + sed "s/^/$submenu_indentation/" << EOF echo '$(echo "$message" | grub_quote)' EOF + fi if test -d /sys/firmware/efi && test -e "${linux}.efi.signed"; then sed "s/^/$submenu_indentation/" << EOF linux ${rel_dirname}/${basename}.efi.signed root=${linux_root_device_thisversion} ro ${args} @@ -161,9 +164,13 @@ EOF fi if test -n "${initrd}" ; then # TRANSLATORS: ramdisk isn't identifier. Should be translated. - message="$(gettext_printf "Loading initial ramdisk ...")" - sed "s/^/$submenu_indentation/" << EOF + if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then + message="$(gettext_printf "Loading initial ramdisk ...")" + sed "s/^/$submenu_indentation/" << EOF echo '$(echo "$message" | grub_quote)' +EOF + fi + sed "s/^/$submenu_indentation/" << EOF initrd ${rel_dirname}/${initrd} EOF fi debian/patches/ofdisk_add_sas_disks.patch0000664000000000000000000000655612625413255016013 0ustar From 4b75a4a0f2438e1afd6ff3cb15697dbc52dfbd74 Mon Sep 17 00:00:00 2001 From: Paulo Flabiano Smorigo Date: Sun, 8 Nov 2015 21:52:22 -0200 Subject: ofdisk: add sas disks to the device list Patch-Name: ofdisk_add_sas_disks.patch Origin: upstream, http://git.savannah.gnu.org/cgit/grub.git/commit/?id=c899d9f42c543939abc92d79c9729d429740492e Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1517586 Last-Update: 2015-11-20 --- grub-core/disk/ieee1275/ofdisk.c | 76 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index 6870b39..6735a66 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -255,6 +255,82 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) grub_free (buf); return; } + else if (grub_strcmp (alias->type, "sas_ioa") == 0) + { + /* The method returns the number of disks and a table where + * each ID is 64-bit long. Example of sas paths: + * /pci@80000002000001f/pci1014,034A@0/sas/disk@c05db70800 + * /pci@80000002000001f/pci1014,034A@0/sas/disk@a05db70800 + * /pci@80000002000001f/pci1014,034A@0/sas/disk@805db70800 */ + + struct sas_children + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t method; + grub_ieee1275_cell_t ihandle; + grub_ieee1275_cell_t max; + grub_ieee1275_cell_t table; + grub_ieee1275_cell_t catch_result; + grub_ieee1275_cell_t nentries; + } + args; + char *buf, *bufptr; + unsigned i; + grub_uint64_t *table; + grub_uint16_t table_size; + grub_ieee1275_ihandle_t ihandle; + + buf = grub_malloc (grub_strlen (alias->path) + + sizeof ("/disk@7766554433221100")); + if (!buf) + return; + bufptr = grub_stpcpy (buf, alias->path); + + /* Power machines documentation specify 672 as maximum SAS disks in + one system. Using a slightly larger value to be safe. */ + table_size = 768; + table = grub_malloc (table_size * sizeof (grub_uint64_t)); + + if (!table) + { + grub_free (buf); + return; + } + + if (grub_ieee1275_open (alias->path, &ihandle)) + { + grub_free (buf); + grub_free (table); + return; + } + + INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 2); + args.method = (grub_ieee1275_cell_t) "get-sas-children"; + args.ihandle = ihandle; + args.max = table_size; + args.table = (grub_ieee1275_cell_t) table; + args.catch_result = 0; + args.nentries = 0; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + { + grub_ieee1275_close (ihandle); + grub_free (table); + grub_free (buf); + return; + } + + for (i = 0; i < args.nentries; i++) + { + grub_snprintf (bufptr, sizeof ("/disk@7766554433221100"), + "/disk@%" PRIxGRUB_UINT64_T, table[i]); + dev_iterate_real (buf, buf); + } + + grub_ieee1275_close (ihandle); + grub_free (table); + grub_free (buf); + } if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS) && grub_strcmp (alias->type, "block") == 0) debian/patches/probe-delimiter.patch0000664000000000000000000002454112524662415014740 0ustar From d9c202af30a1989246e0878af3c67b7aa9c6f83b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 31 Mar 2014 14:48:33 +0100 Subject: Fix partmap, cryptodisk, and abstraction handling in grub-mkconfig. Commit 588744d0dc655177d5883bdcb8f72ff5160109ed caused grub-mkconfig no longer to be forgiving of trailing spaces on grub-probe output lines, which among other things means that util/grub.d/10_linux.in no longer detects LVM. To fix this, make grub-probe's output delimiting more consistent. As a bonus, this improves the coverage of the -0 option. Fixes Debian bug #735935. * grub-core/disk/cryptodisk.c (grub_util_cryptodisk_get_abstraction): Add a user-data argument. * grub-core/disk/diskfilter.c (grub_diskfilter_get_partmap): Likewise. * include/grub/cryptodisk.h (grub_util_cryptodisk_get_abstraction): Update prototype. * include/grub/diskfilter.h (grub_diskfilter_get_partmap): Likewise. * util/grub-install.c (push_partmap_module, push_cryptodisk_module, probe_mods): Adjust for extra user-data arguments. * util/grub-probe.c (do_print, probe_partmap, probe_cryptodisk_uuid, probe_abstraction): Use configured delimiter. Update callers. Origin: upstream, http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commitdiff;h=24024dac7f51d3c0df8e1bec63c02d52828de534 Bug-Debian: http://bugs.debian.org/735935 Forwarded: not-needed Last-Update: 2014-03-31 Patch-Name: probe-delimiter.patch --- grub-core/disk/cryptodisk.c | 19 ++++++++++--------- grub-core/disk/diskfilter.c | 5 +++-- include/grub/cryptodisk.h | 3 ++- include/grub/diskfilter.h | 3 ++- util/grub-install.c | 14 ++++++++++---- util/grub-probe.c | 46 ++++++++++++++++++++++----------------------- 6 files changed, 49 insertions(+), 41 deletions(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index 75c6e1f..f0e3a90 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -762,25 +762,26 @@ grub_cryptodisk_cheat_insert (grub_cryptodisk_t newdev, const char *name, void grub_util_cryptodisk_get_abstraction (grub_disk_t disk, - void (*cb) (const char *val)) + void (*cb) (const char *val, void *data), + void *data) { grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; - cb ("cryptodisk"); - cb (dev->modname); + cb ("cryptodisk", data); + cb (dev->modname, data); if (dev->cipher) - cb (dev->cipher->cipher->modname); + cb (dev->cipher->cipher->modname, data); if (dev->secondary_cipher) - cb (dev->secondary_cipher->cipher->modname); + cb (dev->secondary_cipher->cipher->modname, data); if (dev->essiv_cipher) - cb (dev->essiv_cipher->cipher->modname); + cb (dev->essiv_cipher->cipher->modname, data); if (dev->hash) - cb (dev->hash->modname); + cb (dev->hash->modname, data); if (dev->essiv_hash) - cb (dev->essiv_hash->modname); + cb (dev->essiv_hash->modname, data); if (dev->iv_hash) - cb (dev->iv_hash->modname); + cb (dev->iv_hash->modname, data); } const char * diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c index 28b70c6..e8a3bcb 100644 --- a/grub-core/disk/diskfilter.c +++ b/grub-core/disk/diskfilter.c @@ -354,7 +354,8 @@ grub_diskfilter_memberlist (grub_disk_t disk) void grub_diskfilter_get_partmap (grub_disk_t disk, - void (*cb) (const char *pm)) + void (*cb) (const char *pm, void *data), + void *data) { struct grub_diskfilter_lv *lv = disk->data; struct grub_diskfilter_pv *pv; @@ -376,7 +377,7 @@ grub_diskfilter_get_partmap (grub_disk_t disk, continue; } for (s = 0; pv->partmaps[s]; s++) - cb (pv->partmaps[s]); + cb (pv->partmaps[s], data); } } diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index 66f3e1e..f2ad2a7 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -145,7 +145,8 @@ grub_cryptodisk_cheat_insert (grub_cryptodisk_t newdev, const char *name, grub_disk_t source, const char *cheat); void grub_util_cryptodisk_get_abstraction (grub_disk_t disk, - void (*cb) (const char *val)); + void (*cb) (const char *val, void *data), + void *data); char * grub_util_get_geli_uuid (const char *dev); diff --git a/include/grub/diskfilter.h b/include/grub/diskfilter.h index 042fe04..1aedcd3 100644 --- a/include/grub/diskfilter.h +++ b/include/grub/diskfilter.h @@ -202,7 +202,8 @@ grub_diskfilter_get_pv_from_disk (grub_disk_t disk, struct grub_diskfilter_vg **vg); void grub_diskfilter_get_partmap (grub_disk_t disk, - void (*cb) (const char *val)); + void (*cb) (const char *val, void *data), + void *data); #endif #endif /* ! GRUB_RAID_H */ diff --git a/util/grub-install.c b/util/grub-install.c index f6a70dd..34f3db2 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -402,7 +402,7 @@ probe_raid_level (grub_disk_t disk) } static void -push_partmap_module (const char *map) +push_partmap_module (const char *map, void *data __attribute__ ((unused))) { char buf[50]; @@ -417,6 +417,12 @@ push_partmap_module (const char *map) } static void +push_cryptodisk_module (const char *mod, void *data __attribute__ ((unused))) +{ + grub_install_push_module (mod); +} + +static void probe_mods (grub_disk_t disk) { grub_partition_t part; @@ -427,11 +433,11 @@ probe_mods (grub_disk_t disk) grub_util_info ("no partition map found for %s", disk->name); for (part = disk->partition; part; part = part->parent) - push_partmap_module (part->partmap->name); + push_partmap_module (part->partmap->name, NULL); if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID) { - grub_diskfilter_get_partmap (disk, push_partmap_module); + grub_diskfilter_get_partmap (disk, push_partmap_module, NULL); have_abstractions = 1; } @@ -447,7 +453,7 @@ probe_mods (grub_disk_t disk) if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) { grub_util_cryptodisk_get_abstraction (disk, - grub_install_push_module); + push_cryptodisk_module, NULL); have_abstractions = 1; have_cryptodisk = 1; } diff --git a/util/grub-probe.c b/util/grub-probe.c index 1f3b59f..e4b5729 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -130,13 +130,14 @@ get_targets_string (void) } static void -do_print (const char *x) +do_print (const char *x, void *data) { - grub_printf ("%s ", x); + char delim = *(const char *) data; + grub_printf ("%s%c", x, delim); } static void -probe_partmap (grub_disk_t disk) +probe_partmap (grub_disk_t disk, char delim) { grub_partition_t part; grub_disk_memberlist_t list = NULL, tmp; @@ -147,10 +148,10 @@ probe_partmap (grub_disk_t disk) } for (part = disk->partition; part; part = part->parent) - printf ("%s ", part->partmap->name); + printf ("%s%c", part->partmap->name, delim); if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID) - grub_diskfilter_get_partmap (disk, do_print); + grub_diskfilter_get_partmap (disk, do_print, &delim); /* In case of LVM/RAID, check the member devices as well. */ if (disk->dev->memberlist) @@ -159,7 +160,7 @@ probe_partmap (grub_disk_t disk) } while (list) { - probe_partmap (list->disk); + probe_partmap (list->disk, delim); tmp = list->next; free (list); list = tmp; @@ -167,7 +168,7 @@ probe_partmap (grub_disk_t disk) } static void -probe_cryptodisk_uuid (grub_disk_t disk) +probe_cryptodisk_uuid (grub_disk_t disk, char delim) { grub_disk_memberlist_t list = NULL, tmp; @@ -178,7 +179,7 @@ probe_cryptodisk_uuid (grub_disk_t disk) } while (list) { - probe_cryptodisk_uuid (list->disk); + probe_cryptodisk_uuid (list->disk, delim); tmp = list->next; free (list); list = tmp; @@ -186,7 +187,7 @@ probe_cryptodisk_uuid (grub_disk_t disk) if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) { const char *uu = grub_util_cryptodisk_get_uuid (disk); - grub_printf ("%s ", uu); + grub_printf ("%s%c", uu, delim); } } @@ -210,7 +211,7 @@ probe_raid_level (grub_disk_t disk) } static void -probe_abstraction (grub_disk_t disk) +probe_abstraction (grub_disk_t disk, char delim) { grub_disk_memberlist_t list = NULL, tmp; int raid_level; @@ -219,7 +220,7 @@ probe_abstraction (grub_disk_t disk) list = disk->dev->memberlist (disk); while (list) { - probe_abstraction (list->disk); + probe_abstraction (list->disk, delim); tmp = list->next; free (list); @@ -229,26 +230,26 @@ probe_abstraction (grub_disk_t disk) if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID && (grub_memcmp (disk->name, "lvm/", sizeof ("lvm/") - 1) == 0 || grub_memcmp (disk->name, "lvmid/", sizeof ("lvmid/") - 1) == 0)) - printf ("lvm "); + printf ("lvm%c", delim); if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID && grub_memcmp (disk->name, "ldm/", sizeof ("ldm/") - 1) == 0) - printf ("ldm "); + printf ("ldm%c", delim); if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) - grub_util_cryptodisk_get_abstraction (disk, do_print); + grub_util_cryptodisk_get_abstraction (disk, do_print, &delim); raid_level = probe_raid_level (disk); if (raid_level >= 0) { - printf ("diskfilter "); + printf ("diskfilter%c", delim); if (disk->dev->raidname) - printf ("%s ", disk->dev->raidname (disk)); + printf ("%s%c", disk->dev->raidname (disk), delim); } if (raid_level == 5) - printf ("raid5rec "); + printf ("raid5rec%c", delim); if (raid_level == 6) - printf ("raid6rec "); + printf ("raid6rec%c", delim); } static void @@ -630,16 +631,14 @@ probe (const char *path, char **device_names, char delim) if (print == PRINT_ABSTRACTION) { - probe_abstraction (dev->disk); - putchar (delim); + probe_abstraction (dev->disk, delim); grub_device_close (dev); continue; } if (print == PRINT_CRYPTODISK_UUID) { - probe_cryptodisk_uuid (dev->disk); - putchar (delim); + probe_cryptodisk_uuid (dev->disk, delim); grub_device_close (dev); continue; } @@ -647,8 +646,7 @@ probe (const char *path, char **device_names, char delim) if (print == PRINT_PARTMAP) { /* Check if dev->disk itself is contained in a partmap. */ - probe_partmap (dev->disk); - putchar (delim); + probe_partmap (dev->disk, delim); grub_device_close (dev); continue; } debian/patches/elf_bi_endian.patch0000664000000000000000000001462712524662415014417 0ustar From 7c73be59758d8dad3b2189bf422ff140d084af58 Mon Sep 17 00:00:00 2001 From: Tomohiro B Berry Date: Tue, 14 Jan 2014 17:43:25 +0000 Subject: Add bi-endian support to ELF parser This patch adds bi-endian support for both 32-bit and 64-bit elf files. It compares the native endianness to the endianness of the elf file, and swaps the header bytes if necessary. This will allow, for example, 32-bit Big Endian grub to load a 64-bit Little Endian kernel. Origin: other, https://lists.gnu.org/archive/html/grub-devel/2014-01/msg00039.html Patch-Name: elf_bi_endian.patch --- grub-core/kern/elf.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++-- grub-core/kern/elfXX.c | 43 +++++++++++++++++++++++++++++++++++++++ include/grub/elf.h | 7 +++++++ 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/grub-core/kern/elf.c b/grub-core/kern/elf.c index 5f99c43..9a3cc71 100644 --- a/grub-core/kern/elf.c +++ b/grub-core/kern/elf.c @@ -28,20 +28,45 @@ GRUB_MOD_LICENSE ("GPLv3+"); +void grub_elf32_byteswap_header (grub_elf_t elf); +void grub_elf64_byteswap_header (grub_elf_t elf); +grub_err_t grub_elf32_check_version (grub_elf_t elf); +grub_err_t grub_elf64_check_version (grub_elf_t elf); + /* Check if EHDR is a valid ELF header. */ static grub_err_t grub_elf_check_header (grub_elf_t elf) { + /* e_ident is the same for both 64-bit and 32-bit so just load into a 32-bit struct for now */ Elf32_Ehdr *e = &elf->ehdr.ehdr32; + /* check if it is an ELF image at all */ if (e->e_ident[EI_MAG0] != ELFMAG0 || e->e_ident[EI_MAG1] != ELFMAG1 || e->e_ident[EI_MAG2] != ELFMAG2 || e->e_ident[EI_MAG3] != ELFMAG3 - || e->e_ident[EI_VERSION] != EV_CURRENT - || e->e_version != EV_CURRENT) + || e->e_ident[EI_VERSION] != EV_CURRENT) return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-independent ELF magic")); + switch (e->e_ident[EI_CLASS]) + { + case ELFCLASS32: + if (e->e_ident[EI_DATA] != ELFDATA_NATIVE) + grub_elf32_byteswap_header (elf); + if (grub_elf32_check_version (elf) != GRUB_ERR_NONE) + return grub_errno; + break; + case ELFCLASS64: + if (e->e_ident[EI_DATA] != ELFDATA_NATIVE) + grub_elf64_byteswap_header (elf); + if (grub_elf64_check_version (elf) != GRUB_ERR_NONE) + return grub_errno; + break; + default: + return grub_error (GRUB_ERR_BAD_OS, N_("unrecognized ELF class")); + break; + } + return GRUB_ERR_NONE; } @@ -127,7 +152,16 @@ grub_elf_open (const char *name) #define grub_elf_is_elfXX grub_elf_is_elf32 #define grub_elfXX_load_phdrs grub_elf32_load_phdrs #define ElfXX_Phdr Elf32_Phdr +#define ElfXX_Ehdr Elf32_Ehdr #define grub_uintXX_t grub_uint32_t +/* for phdr/ehdr byte swaps */ +#define byte_swap_halfXX grub_swap_bytes16 +#define byte_swap_wordXX grub_swap_bytes32 +#define byte_swap_addrXX grub_swap_bytes32 +#define byte_swap_offXX grub_swap_bytes32 +#define byte_swap_XwordXX byte_swap_wordXX /* the 64-bit phdr uses Xwords and the 32-bit uses words */ +#define grub_elfXX_byteswap_header grub_elf32_byteswap_header +#define grub_elfXX_check_version grub_elf32_check_version #include "elfXX.c" @@ -140,7 +174,15 @@ grub_elf_open (const char *name) #undef grub_elf_is_elfXX #undef grub_elfXX_load_phdrs #undef ElfXX_Phdr +#undef ElfXX_Ehdr #undef grub_uintXX_t +#undef byte_swap_halfXX +#undef byte_swap_wordXX +#undef byte_swap_addrXX +#undef byte_swap_offXX +#undef byte_swap_XwordXX +#undef grub_elfXX_byteswap_header +#undef grub_elfXX_check_version /* 64-bit */ @@ -153,6 +195,15 @@ grub_elf_open (const char *name) #define grub_elf_is_elfXX grub_elf_is_elf64 #define grub_elfXX_load_phdrs grub_elf64_load_phdrs #define ElfXX_Phdr Elf64_Phdr +#define ElfXX_Ehdr Elf64_Ehdr #define grub_uintXX_t grub_uint64_t +/* for phdr/ehdr byte swaps */ +#define byte_swap_halfXX grub_swap_bytes16 +#define byte_swap_wordXX grub_swap_bytes32 +#define byte_swap_addrXX grub_swap_bytes64 +#define byte_swap_offXX grub_swap_bytes64 +#define byte_swap_XwordXX grub_swap_bytes64 +#define grub_elfXX_byteswap_header grub_elf64_byteswap_header +#define grub_elfXX_check_version grub_elf64_check_version #include "elfXX.c" diff --git a/grub-core/kern/elfXX.c b/grub-core/kern/elfXX.c index 1d09971..639cda6 100644 --- a/grub-core/kern/elfXX.c +++ b/grub-core/kern/elfXX.c @@ -154,3 +154,46 @@ grub_elfXX_load (grub_elf_t elf, const char *filename, return grub_errno; } + +void +grub_elfXX_byteswap_header (grub_elf_t elf) +{ + ElfXX_Ehdr *e = &(elf->ehdr.ehdrXX); + ElfXX_Phdr *phdr; + + e->e_type = byte_swap_halfXX (e->e_type); + e->e_machine = byte_swap_halfXX (e->e_machine); + e->e_version = byte_swap_wordXX (e->e_version); + e->e_entry = byte_swap_addrXX (e->e_entry); + e->e_phoff = byte_swap_offXX (e->e_phoff); + e->e_shoff = byte_swap_offXX (e->e_shoff); + e->e_flags = byte_swap_wordXX (e->e_flags); + e->e_ehsize = byte_swap_halfXX (e->e_ehsize); + e->e_phentsize = byte_swap_halfXX (e->e_phentsize); + e->e_phnum = byte_swap_halfXX (e->e_phnum); + e->e_shentsize = byte_swap_halfXX (e->e_shentsize); + e->e_shnum = byte_swap_halfXX (e->e_shnum); + e->e_shstrndx = byte_swap_halfXX (e->e_shstrndx); + + FOR_ELFXX_PHDRS (elf,phdr) + { + phdr->p_type = byte_swap_wordXX (phdr->p_type); + phdr->p_flags = byte_swap_wordXX (phdr->p_flags); + phdr->p_offset = byte_swap_offXX (phdr->p_offset); + phdr->p_vaddr = byte_swap_addrXX (phdr->p_vaddr); + phdr->p_paddr = byte_swap_addrXX (phdr->p_paddr); + phdr->p_filesz = byte_swap_XwordXX (phdr->p_filesz); + phdr->p_memsz = byte_swap_XwordXX (phdr->p_memsz); + phdr->p_align = byte_swap_XwordXX (phdr->p_align); + } + +} + +grub_err_t +grub_elfXX_check_version (grub_elf_t elf) +{ + if (elf->ehdr.ehdrXX.e_version != EV_CURRENT) + return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-independent ELF magic")); + + return GRUB_ERR_NONE; +} diff --git a/include/grub/elf.h b/include/grub/elf.h index caa7963..ca6e436 100644 --- a/include/grub/elf.h +++ b/include/grub/elf.h @@ -56,6 +56,13 @@ typedef grub_uint16_t Elf64_Section; typedef Elf32_Half Elf32_Versym; typedef Elf64_Half Elf64_Versym; +/* Define the native endianness */ + +#ifdef GRUB_CPU_WORDS_BIGENDIAN +#define ELFDATA_NATIVE ELFDATA2MSB +#else +#define ELFDATA_NATIVE ELFDATA2LSB +#endif /* The ELF file header. This appears at the start of every ELF file. */ debian/patches/default_grub_d.patch0000664000000000000000000001210712524662415014616 0ustar From b7b657b655fb49c41eaa51293aa54097a5dbdfa5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:10 +0000 Subject: Read /etc/default/grub.d/*.cfg after /etc/default/grub Bug-Ubuntu: https://bugs.launchpad.net/bugs/901600 Forwarded: no Last-Update: 2014-01-28 Patch-Name: default_grub_d.patch --- grub-core/osdep/unix/config.c | 114 ++++++++++++++++++++++++++++++++++-------- util/grub-mkconfig.in | 5 ++ 2 files changed, 98 insertions(+), 21 deletions(-) diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c index f4b0bb4..95eabc8 100644 --- a/grub-core/osdep/unix/config.c +++ b/grub-core/osdep/unix/config.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -61,13 +63,27 @@ grub_util_get_localedir (void) return LOCALEDIR; } +struct cfglist +{ + struct cfglist *next; + struct cfglist *prev; + char *path; +}; + void grub_util_load_config (struct grub_util_config *cfg) { pid_t pid; const char *argv[4]; - char *script, *ptr; + char *script = NULL, *ptr; const char *cfgfile, *iptr; + char *cfgdir; + grub_util_fd_dir_t d; + struct cfglist *cfgpaths = NULL, *cfgpath, *next_cfgpath; + int num_cfgpaths = 0; + size_t len_cfgpaths = 0; + char **sorted_cfgpaths = NULL; + int i; FILE *f = NULL; int fd; const char *v; @@ -83,29 +99,75 @@ grub_util_load_config (struct grub_util_config *cfg) cfg->grub_distributor = xstrdup (v); cfgfile = grub_util_get_config_filename (); - if (!grub_util_is_regular (cfgfile)) - return; + if (grub_util_is_regular (cfgfile)) + { + ++num_cfgpaths; + len_cfgpaths += strlen (cfgfile) * 4 + sizeof (". ''; ") - 1; + } + + cfgdir = xasprintf ("%s.d", cfgfile); + d = grub_util_fd_opendir (cfgdir); + if (d) + { + grub_util_fd_dirent_t de; + + while ((de = grub_util_fd_readdir (d))) + { + const char *ext = strrchr (de->d_name, '.'); + + if (!ext || strcmp (ext, ".cfg") != 0) + continue; + + cfgpath = xmalloc (sizeof (*cfgpath)); + cfgpath->path = grub_util_path_concat (2, cfgdir, de->d_name); + grub_list_push (GRUB_AS_LIST_P (&cfgpaths), GRUB_AS_LIST (cfgpath)); + ++num_cfgpaths; + len_cfgpaths += strlen (cfgpath->path) * 4 + sizeof (". ''; ") - 1; + } + grub_util_fd_closedir (d); + } + + if (num_cfgpaths == 0) + goto out; + + sorted_cfgpaths = xmalloc (num_cfgpaths * sizeof (*sorted_cfgpaths)); + i = 0; + if (grub_util_is_regular (cfgfile)) + sorted_cfgpaths[i++] = xstrdup (cfgfile); + FOR_LIST_ELEMENTS_SAFE (cfgpath, next_cfgpath, cfgpaths) + { + sorted_cfgpaths[i++] = cfgpath->path; + free (cfgpath); + } + assert (i == num_cfgpaths); + qsort (sorted_cfgpaths + 1, num_cfgpaths - 1, sizeof (*sorted_cfgpaths), + (int (*) (const void *, const void *)) strcmp); argv[0] = "sh"; argv[1] = "-c"; - script = xmalloc (4 * strlen (cfgfile) + 300); + script = xmalloc (len_cfgpaths + 300); ptr = script; - memcpy (ptr, ". '", 3); - ptr += 3; - for (iptr = cfgfile; *iptr; iptr++) + for (i = 0; i < num_cfgpaths; i++) { - if (*iptr == '\\') + memcpy (ptr, ". '", 3); + ptr += 3; + for (iptr = sorted_cfgpaths[i]; *iptr; iptr++) { - memcpy (ptr, "'\\''", 4); - ptr += 4; - continue; + if (*iptr == '\\') + { + memcpy (ptr, "'\\''", 4); + ptr += 4; + continue; + } + *ptr++ = *iptr; } - *ptr++ = *iptr; + memcpy (ptr, "'; ", 3); + ptr += 3; } - strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\", " + strcpy (ptr, "printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\", " "\"$GRUB_ENABLE_CRYPTODISK\", \"$GRUB_DISTRIBUTOR\""); argv[2] = script; @@ -125,15 +187,25 @@ grub_util_load_config (struct grub_util_config *cfg) waitpid (pid, NULL, 0); } if (f) - return; + goto out; - f = grub_util_fopen (cfgfile, "r"); - if (f) + for (i = 0; i < num_cfgpaths; i++) { - grub_util_parse_config (f, cfg, 0); - fclose (f); + f = grub_util_fopen (sorted_cfgpaths[i], "r"); + if (f) + { + grub_util_parse_config (f, cfg, 0); + fclose (f); + } + else + grub_util_warn (_("cannot open configuration file `%s': %s"), + cfgfile, strerror (errno)); } - else - grub_util_warn (_("cannot open configuration file `%s': %s"), - cfgfile, strerror (errno)); + +out: + free (script); + for (i = 0; i < num_cfgpaths; i++) + free (sorted_cfgpaths[i]); + free (sorted_cfgpaths); + free (cfgdir); } diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 81a9afd..62780bf 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -154,6 +154,11 @@ fi if test -f ${sysconfdir}/default/grub ; then . ${sysconfdir}/default/grub fi +for x in ${sysconfdir}/default/grub.d/*.cfg ; do + if [ -e "${x}" ]; then + . "${x}" + fi +done # XXX: should this be deprecated at some point? if [ "x${GRUB_TERMINAL}" != "x" ] ; then debian/patches/progress_avoid_null_deref.patch0000664000000000000000000000432212625413255017073 0ustar From df958de5315158a421d3cf938ccbb5164096526a Mon Sep 17 00:00:00 2001 From: Andrei Borzenkov Date: Sat, 10 Oct 2015 11:44:14 +0300 Subject: progress: avoid NULL dereference for net files From original patch by dann frazier : grub_net_fs_open() saves off a copy of the file structure it gets passed and uses it to create a bufio structure. It then overwrites the passed in file structure with this new bufio structure. Since file->name doesn't get set until we return back to grub_file_open(), it means that only the bufio structure gets a valid file->name. The "real" file's name is left uninitialized. This leads to a crash when the progress module hook is called on it. grub_net_fs_open() already saved copy of file name as ->net->name, so change progress module to use it. Also, grub_file_open may leave file->name as NULL if grub_strdup fails. Check for it. Also-By: dann frazier Patch-Name: progress_avoid_null_deref.patch Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1459872 --- grub-core/lib/progress.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/grub-core/lib/progress.c b/grub-core/lib/progress.c index 63a0767..95a4a62 100644 --- a/grub-core/lib/progress.c +++ b/grub-core/lib/progress.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -70,7 +71,15 @@ grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)), percent = grub_divmod64 (100 * file->progress_offset, file->size, 0); - partial_file_name = grub_strrchr (file->name, '/'); + /* grub_net_fs_open() saves off partial file structure before name is initialized. + It already saves passed file name in net structure so just use it in this case. + */ + if (file->device->net) + partial_file_name = grub_strrchr (file->device->net->name, '/'); + else if (file->name) /* grub_file_open() may leave it as NULL */ + partial_file_name = grub_strrchr (file->name, '/'); + else + partial_file_name = NULL; if (partial_file_name) partial_file_name++; else debian/patches/ignore_grub_func_test_failures.patch0000664000000000000000000000165712524662415020126 0ustar From ef2f02cb746eefe682e65a8948beb6cf30643a4e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:32 +0000 Subject: Ignore functional test failures for now as they are broken See: https://lists.gnu.org/archive/html/grub-devel/2013-11/msg00242.html Forwarded: not-needed Last-Update: 2013-11-19 Patch-Name: ignore_grub_func_test_failures.patch --- tests/grub_func_test.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/grub_func_test.in b/tests/grub_func_test.in index c8cc263..f458f74 100644 --- a/tests/grub_func_test.in +++ b/tests/grub_func_test.in @@ -16,6 +16,8 @@ out=`echo all_functional_test | @builddir@/grub-shell --timeout=3600 --files="/b if [ "$(echo "$out" | tail -n 1)" != "ALL TESTS PASSED" ]; then echo "Functional test failure: $out" - exit 1 + # Disabled temporarily due to unrecognised video checksum failures. + #exit 1 + exit 0 fi debian/patches/CVE-2015-8370.patch0000664000000000000000000000261412634017610013244 0ustar From 88c9657960a6c5d3673a25c266781e876c181add Mon Sep 17 00:00:00 2001 From: Hector Marco-Gisbert Date: Fri, 13 Nov 2015 16:21:09 +0100 Subject: [PATCH] Fix security issue when reading username and password This patch fixes two integer underflows at: * grub-core/lib/crypto.c * grub-core/normal/auth.c Resolves: CVE-2015-8370 Signed-off-by: Hector Marco-Gisbert Signed-off-by: Ismael Ripoll-Ripoll --- grub-core/lib/crypto.c | 2 +- grub-core/normal/auth.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: grub2-2.02~beta2/grub-core/lib/crypto.c =================================================================== --- grub2-2.02~beta2.orig/grub-core/lib/crypto.c 2015-12-15 08:45:31.307836075 -0500 +++ grub2-2.02~beta2/grub-core/lib/crypto.c 2015-12-15 08:45:31.303836031 -0500 @@ -456,7 +456,7 @@ break; } - if (key == '\b') + if (key == '\b' && cur_len) { cur_len--; continue; Index: grub2-2.02~beta2/grub-core/normal/auth.c =================================================================== --- grub2-2.02~beta2.orig/grub-core/normal/auth.c 2015-12-15 08:45:31.307836075 -0500 +++ grub2-2.02~beta2/grub-core/normal/auth.c 2015-12-15 08:45:31.303836031 -0500 @@ -172,7 +172,7 @@ break; } - if (key == '\b') + if (key == '\b' && cur_len) { cur_len--; grub_printf ("\b"); debian/patches/olpc_prefix_hack.patch0000664000000000000000000000266412524662415015157 0ustar From c79d05703ec41571c44a0a09df31cf220d951c09 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:12:50 +0000 Subject: Hack prefix for OLPC This sucks, but it's better than what OFW was giving us. Patch-Name: olpc_prefix_hack.patch --- grub-core/kern/ieee1275/init.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index 89b2822..ecce450 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c @@ -65,6 +65,7 @@ grub_exit (void) grub_ieee1275_exit (); } +#ifndef __i386__ /* Translate an OF filesystem path (separated by backslashes), into a GRUB path (separated by forward slashes). */ static void @@ -79,10 +80,19 @@ grub_translate_ieee1275_path (char *filepath) backslash = grub_strchr (filepath, '\\'); } } +#endif void (*grub_ieee1275_net_config) (const char *dev, char **device, char **path); +#ifdef __i386__ +void +grub_machine_get_bootlocation (char **device __attribute__ ((unused)), + char **path __attribute__ ((unused))) +{ + grub_env_set ("prefix", "(sd,1)/"); +} +#else void grub_machine_get_bootlocation (char **device, char **path) { @@ -150,6 +160,7 @@ grub_machine_get_bootlocation (char **device, char **path) } grub_free (bootpath); } +#endif /* Claim some available memory in the first /memory node. */ #ifdef __sparc__ debian/patches/net-receive-packets-yield.patch0000664000000000000000000000237512524662415016620 0ustar From 85c0479ed5f45e91929efdd829a2496e263c3cd4 Mon Sep 17 00:00:00 2001 From: Paulo Flabiano Smorigo Date: Tue, 21 Jan 2014 10:49:39 -0200 Subject: change stop condition to avoid infinite loops In net/net.c there is a while (1) that only exits if there is a stop condition and more then 10 packages or if there is no package received. If GRUB is idle and enter in this loop, the only condition to leave is if it doesn't have incoming packages. In a network with heavy traffic this never happens. Origin: upstream, http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commitdiff;h=d99d2f84166b0f60673d5c0714605a153946c0fc Bug-Ubuntu: https://bugs.launchpad.net/bugs/1314134 Last-Update: 2014-04-29 Patch-Name: net-receive-packets-yield.patch --- grub-core/net/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 0e57e93..56355f3 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -1453,7 +1453,7 @@ receive_packets (struct grub_net_card *card, int *stop_condition) } card->opened = 1; } - while (1) + while (received < 100) { /* Maybe should be better have a fixed number of packets for each card and just mark them as used and not used. */ debian/patches/grub_legacy_0_based_partitions.patch0000664000000000000000000000224412524662415017765 0ustar From 4adb3bb965773724b1c9107bdb475b265778faf2 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 13 Jan 2014 12:12:53 +0000 Subject: Support running grub-probe in grub-legacy's update-grub Author: Colin Watson Forwarded: not-needed Last-Update: 2013-12-25 Patch-Name: grub_legacy_0_based_partitions.patch --- util/getroot.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/util/getroot.c b/util/getroot.c index 3958105..704855c 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -244,6 +244,20 @@ find_partition (grub_disk_t dsk __attribute__ ((unused)), if (ctx->start == part_start) { + /* This is dreadfully hardcoded, but there's a limit to what GRUB + Legacy was able to deal with anyway. */ + if (getenv ("GRUB_LEGACY_0_BASED_PARTITIONS")) + { + if (partition->parent) + /* Probably a BSD slice. */ + ctx->partname = xasprintf ("%d,%d", partition->parent->number, + partition->number + 1); + else + ctx->partname = xasprintf ("%d", partition->number); + + return 1; + } + ctx->partname = grub_partition_get_name (partition); return 1; } debian/patches/gfxpayload_dynamic.patch0000664000000000000000000001736212524662415015522 0ustar From 343ea9dab997e510d0eae6d396842a437b4bc28a Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Mon, 13 Jan 2014 12:13:29 +0000 Subject: Add configure option to enable gfxpayload=keep dynamically Set GRUB_GFXPAYLOAD_LINUX=keep unless it's known to be unsupported on the current hardware. See https://blueprints.launchpad.net/ubuntu/+spec/packageselection-foundations-n-grub2-boot-framebuffer. Author: Colin Watson Forwarded: no Last-Update: 2013-12-25 Patch-Name: gfxpayload_dynamic.patch --- configure.ac | 11 +++ grub-core/Makefile.core.def | 9 +++ grub-core/commands/i386/pc/hwmatch.c | 146 +++++++++++++++++++++++++++++++++++ util/grub.d/10_linux.in | 37 ++++++++- 4 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 grub-core/commands/i386/pc/hwmatch.c diff --git a/configure.ac b/configure.ac index 2a7e410..7f26de6 100644 --- a/configure.ac +++ b/configure.ac @@ -1605,6 +1605,17 @@ else fi AC_SUBST([QUICK_BOOT]) +AC_ARG_ENABLE([gfxpayload-dynamic], + [AS_HELP_STRING([--enable-gfxpayload-dynamic], + [use GRUB_GFXPAYLOAD_LINUX=keep unless explicitly unsupported on current hardware (default=no)])], + [], [enable_gfxpayload_dynamic=no]) +if test x"$enable_gfxpayload_dynamic" = xyes ; then + GFXPAYLOAD_DYNAMIC=1 +else + GFXPAYLOAD_DYNAMIC=0 +fi +AC_SUBST([GFXPAYLOAD_DYNAMIC]) + LIBS="" AC_SUBST([FONT_SOURCE]) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 8fed2fb..27988ad 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -897,6 +897,15 @@ module = { }; module = { + name = hwmatch; + i386_pc = commands/i386/pc/hwmatch.c; + enable = i386_pc; + common = gnulib/regex.c; + cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; + cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)'; +}; + +module = { name = keystatus; common = commands/keystatus.c; }; diff --git a/grub-core/commands/i386/pc/hwmatch.c b/grub-core/commands/i386/pc/hwmatch.c new file mode 100644 index 0000000..c9f7c9f --- /dev/null +++ b/grub-core/commands/i386/pc/hwmatch.c @@ -0,0 +1,146 @@ +/* hwmatch.c - Match hardware against a whitelist/blacklist. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* Context for grub_cmd_hwmatch. */ +struct hwmatch_ctx +{ + grub_file_t matches_file; + int class_match; + int match; +}; + +/* Helper for grub_cmd_hwmatch. */ +static int +hwmatch_iter (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) +{ + struct hwmatch_ctx *ctx = data; + grub_pci_address_t addr; + grub_uint32_t class, baseclass, vendor, device; + grub_pci_id_t subpciid; + grub_uint32_t subvendor, subdevice, subclass; + char *id, *line; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + baseclass = class >> 24; + + if (ctx->class_match != baseclass) + return 0; + + vendor = pciid & 0xffff; + device = pciid >> 16; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_SUBVENDOR); + subpciid = grub_pci_read (addr); + + subclass = (class >> 16) & 0xff; + subvendor = subpciid & 0xffff; + subdevice = subpciid >> 16; + + id = grub_xasprintf ("v%04xd%04xsv%04xsd%04xbc%02xsc%02x", + vendor, device, subvendor, subdevice, + baseclass, subclass); + + grub_file_seek (ctx->matches_file, 0); + while ((line = grub_file_getline (ctx->matches_file)) != NULL) + { + char *anchored_line; + regex_t regex; + int ret; + + if (! *line || *line == '#') + { + grub_free (line); + continue; + } + + anchored_line = grub_xasprintf ("^%s$", line); + ret = regcomp (®ex, anchored_line, REG_EXTENDED | REG_NOSUB); + grub_free (anchored_line); + if (ret) + { + grub_free (line); + continue; + } + + ret = regexec (®ex, id, 0, NULL, 0); + regfree (®ex); + grub_free (line); + if (! ret) + { + ctx->match = 1; + return 1; + } + } + + return 0; +} + +static grub_err_t +grub_cmd_hwmatch (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct hwmatch_ctx ctx = { .match = 0 }; + char *match_str; + + if (argc < 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "list file and class required"); + + ctx.matches_file = grub_file_open (args[0]); + if (! ctx.matches_file) + return grub_errno; + + ctx.class_match = grub_strtol (args[1], 0, 10); + + grub_pci_iterate (hwmatch_iter, &ctx); + + match_str = grub_xasprintf ("%d", ctx.match); + grub_env_set ("match", match_str); + grub_free (match_str); + + grub_file_close (ctx.matches_file); + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(hwmatch) +{ + cmd = grub_register_command ("hwmatch", grub_cmd_hwmatch, + N_("MATCHES-FILE CLASS"), + N_("Match PCI devices.")); +} + +GRUB_MOD_FINI(hwmatch) +{ + grub_unregister_command (cmd); +} diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index aa2c369..41f83ca 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -23,6 +23,7 @@ datarootdir="@datarootdir@" ubuntu_recovery="@UBUNTU_RECOVERY@" quiet_boot="@QUIET_BOOT@" quick_boot="@QUICK_BOOT@" +gfxpayload_dynamic="@GFXPAYLOAD_DYNAMIC@" . "@datadir@/@PACKAGE@/grub-mkconfig_lib" @@ -133,9 +134,10 @@ linux_entry () if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then echo " load_video" | sed "s/^/$submenu_indentation/" fi - if [ "$ubuntu_recovery" = 0 ] || [ x$type != xrecovery ]; then - echo " set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" | sed "s/^/$submenu_indentation/" - fi + fi + if ([ "$ubuntu_recovery" = 0 ] || [ x$type != xrecovery ]) && \ + ([ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 1 ]); then + echo " set gfxpayload=\$linux_gfx_mode" | sed "s/^/$submenu_indentation/" fi echo " insmod gzio" | sed "s/^/$submenu_indentation/" @@ -208,6 +210,35 @@ prepare_root_cache= boot_device_id= title_correction_code= +# Use ELILO's generic "efifb" when it's known to be available. +# FIXME: We need an interface to select vesafb in case efifb can't be used. +if [ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 0 ]; then + echo "set linux_gfx_mode=$GRUB_GFXPAYLOAD_LINUX" +else + cat << EOF +if [ "\${recordfail}" != 1 ]; then + if [ -e \${prefix}/gfxblacklist.txt ]; then + if hwmatch \${prefix}/gfxblacklist.txt 3; then + if [ \${match} = 0 ]; then + set linux_gfx_mode=keep + else + set linux_gfx_mode=text + fi + else + set linux_gfx_mode=text + fi + else + set linux_gfx_mode=keep + fi +else + set linux_gfx_mode=text +fi +EOF +fi +cat << EOF +export linux_gfx_mode +EOF + # Extra indentation to add to menu entries in a submenu. We're not in a submenu # yet, so it's empty. In a submenu it will be equal to '\t' (one tab). submenu_indentation="" debian/patches/restore_mkdevicemap.patch0000664000000000000000000007526512524662415015716 0ustar From ad38e8808898569ceaa084611000843e81f4683b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:01 +0000 Subject: Restore grub-mkdevicemap This is kind of a mess, requiring lots of OS-specific code to iterate over all possible devices. However, we use it in a number of scripts to discover devices and reimplementing those in terms of something else would be very complicated. Patch-Name: restore_mkdevicemap.patch --- Makefile.util.def | 17 + docs/man/grub-mkdevicemap.h2m | 4 + include/grub/util/deviceiter.h | 14 + util/deviceiter.c | 954 +++++++++++++++++++++++++++++++++++++++++ util/devicemap.c | 13 + util/grub-mkdevicemap.c | 181 ++++++++ 6 files changed, 1183 insertions(+) create mode 100644 docs/man/grub-mkdevicemap.h2m create mode 100644 include/grub/util/deviceiter.h create mode 100644 util/deviceiter.c create mode 100644 util/devicemap.c create mode 100644 util/grub-mkdevicemap.c diff --git a/Makefile.util.def b/Makefile.util.def index 985e76c..f659fb4 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -313,6 +313,23 @@ program = { }; program = { + name = grub-mkdevicemap; + installdir = sbin; + mansection = 8; + + common = util/grub-mkdevicemap.c; + common = util/deviceiter.c; + common = util/devicemap.c; + common = grub-core/osdep/init.c; + + ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; +}; + +program = { name = grub-probe; installdir = sbin; mansection = 8; diff --git a/docs/man/grub-mkdevicemap.h2m b/docs/man/grub-mkdevicemap.h2m new file mode 100644 index 0000000..96cd6ee --- /dev/null +++ b/docs/man/grub-mkdevicemap.h2m @@ -0,0 +1,4 @@ +[NAME] +grub-mkdevicemap \- make a device map file automatically +[SEE ALSO] +.BR grub-probe (8) diff --git a/include/grub/util/deviceiter.h b/include/grub/util/deviceiter.h new file mode 100644 index 0000000..8537497 --- /dev/null +++ b/include/grub/util/deviceiter.h @@ -0,0 +1,14 @@ +#ifndef GRUB_DEVICEITER_MACHINE_UTIL_HEADER +#define GRUB_DEVICEITER_MACHINE_UTIL_HEADER 1 + +#include + +typedef int (*grub_util_iterate_devices_hook_t) (const char *name, + int is_floppy, void *data); + +void grub_util_iterate_devices (grub_util_iterate_devices_hook_t hook, + void *hook_data, int floppy_disks); +void grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy, + int *num_fd, int *num_hd); + +#endif /* ! GRUB_DEVICEITER_MACHINE_UTIL_HEADER */ diff --git a/util/deviceiter.c b/util/deviceiter.c new file mode 100644 index 0000000..75047ff --- /dev/null +++ b/util/deviceiter.c @@ -0,0 +1,954 @@ +/* deviceiter.c - iterate over system devices */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef __linux__ +# if !defined(__GLIBC__) || \ + ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))) +/* Maybe libc doesn't have large file support. */ +# include /* _llseek */ +# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */ +# include /* ioctl */ +# ifndef HDIO_GETGEO +# define HDIO_GETGEO 0x0301 /* get device geometry */ +/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is + defined. */ +struct hd_geometry +{ + unsigned char heads; + unsigned char sectors; + unsigned short cylinders; + unsigned long start; +}; +# endif /* ! HDIO_GETGEO */ +# ifndef FLOPPY_MAJOR +# define FLOPPY_MAJOR 2 /* the major number for floppy */ +# endif /* ! FLOPPY_MAJOR */ +# ifndef MAJOR +# define MAJOR(dev) \ + ({ \ + unsigned long long __dev = (dev); \ + (unsigned) ((__dev >> 8) & 0xfff) \ + | ((unsigned int) (__dev >> 32) & ~0xfff); \ + }) +# endif /* ! MAJOR */ +# ifndef MINOR +# define MINOR(dev) \ + ({ \ + unsigned long long __dev = (dev); \ + (unsigned) (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); \ + }) +# endif /* ! MINOR */ +# ifndef CDROM_GET_CAPABILITY +# define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */ +# endif /* ! CDROM_GET_CAPABILITY */ +# ifndef BLKGETSIZE +# define BLKGETSIZE _IO(0x12,96) /* return device size */ +# endif /* ! BLKGETSIZE */ + +#ifdef HAVE_DEVICE_MAPPER +# include +# pragma GCC diagnostic ignored "-Wcast-align" +#endif +#endif /* __linux__ */ + +/* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with + kFreeBSD-based non-FreeBSD systems (e.g. GNU/kFreeBSD) */ +#if defined(__FreeBSD__) && ! defined(__FreeBSD_kernel__) +# define __FreeBSD_kernel__ +#endif +#ifdef __FreeBSD_kernel__ + /* Obtain version of kFreeBSD headers */ +# include +# ifndef __FreeBSD_kernel_version +# define __FreeBSD_kernel_version __FreeBSD_version +# endif + + /* Runtime detection of kernel */ +# include +static int +get_kfreebsd_version (void) +{ + struct utsname uts; + int major; + int minor; + int v[2]; + + uname (&uts); + sscanf (uts.release, "%d.%d", &major, &minor); + + if (major >= 9) + major = 9; + if (major >= 5) + { + v[0] = minor/10; v[1] = minor%10; + } + else + { + v[0] = minor%10; v[1] = minor/10; + } + return major*100000+v[0]*10000+v[1]*1000; +} +#endif /* __FreeBSD_kernel__ */ + +#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) +# include /* ioctl */ +# include +# include /* CDIOCCLRDEBUG */ +# if defined(__FreeBSD_kernel__) +# include +# if __FreeBSD_kernel_version >= 500040 +# include +# endif +# endif /* __FreeBSD_kernel__ */ +#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */ + +#ifdef HAVE_OPENDISK +# include +#endif /* HAVE_OPENDISK */ + +#ifdef __linux__ +/* Check if we have devfs support. */ +static int +have_devfs (void) +{ + struct stat st; + return stat ("/dev/.devfsd", &st) == 0; +} +#endif /* __linux__ */ + +/* These three functions are quite different among OSes. */ +static void +get_floppy_disk_name (char *name, int unit) +{ +#if defined(__linux__) + /* GNU/Linux */ + if (have_devfs ()) + sprintf (name, "/dev/floppy/%d", unit); + else + sprintf (name, "/dev/fd%d", unit); +#elif defined(__GNU__) + /* GNU/Hurd */ + sprintf (name, "/dev/fd%d", unit); +#elif defined(__FreeBSD_kernel__) + /* kFreeBSD */ + if (get_kfreebsd_version () >= 400000) + sprintf (name, "/dev/fd%d", unit); + else + sprintf (name, "/dev/rfd%d", unit); +#elif defined(__NetBSD__) + /* NetBSD */ + /* opendisk() doesn't work for floppies. */ + sprintf (name, "/dev/rfd%da", unit); +#elif defined(__OpenBSD__) + /* OpenBSD */ + sprintf (name, "/dev/rfd%dc", unit); +#elif defined(__QNXNTO__) + /* QNX RTP */ + sprintf (name, "/dev/fd%d", unit); +#elif defined(__CYGWIN__) + /* Cygwin */ + sprintf (name, "/dev/fd%d", unit); +#elif defined(__MINGW32__) + (void) unit; + *name = 0; +#else +# warning "BIOS floppy drives cannot be guessed in your operating system." + /* Set NAME to a bogus string. */ + *name = 0; +#endif +} + +static void +get_ide_disk_name (char *name, int unit) +{ +#if defined(__linux__) + /* GNU/Linux */ + sprintf (name, "/dev/hd%c", unit + 'a'); +#elif defined(__GNU__) + /* GNU/Hurd */ + sprintf (name, "/dev/hd%d", unit); +#elif defined(__FreeBSD_kernel__) + /* kFreeBSD */ + if (get_kfreebsd_version () >= 400000) + sprintf (name, "/dev/ad%d", unit); + else + sprintf (name, "/dev/rwd%d", unit); +#elif defined(__NetBSD__) && defined(HAVE_OPENDISK) + /* NetBSD */ + char shortname[16]; + int fd; + + sprintf (shortname, "wd%d", unit); + fd = opendisk (shortname, O_RDONLY, name, + 16, /* length of NAME */ + 0 /* char device */ + ); + close (fd); +#elif defined(__OpenBSD__) + /* OpenBSD */ + sprintf (name, "/dev/rwd%dc", unit); +#elif defined(__QNXNTO__) + /* QNX RTP */ + /* Actually, QNX RTP doesn't distinguish IDE from SCSI, so this could + contain SCSI disks. */ + sprintf (name, "/dev/hd%d", unit); +#elif defined(__CYGWIN__) + /* Cygwin emulates all disks as /dev/sdX. */ + (void) unit; + *name = 0; +#elif defined(__MINGW32__) + sprintf (name, "//./PHYSICALDRIVE%d", unit); +#else +# warning "BIOS IDE drives cannot be guessed in your operating system." + /* Set NAME to a bogus string. */ + *name = 0; +#endif +} + +static void +get_scsi_disk_name (char *name, int unit) +{ +#if defined(__linux__) + /* GNU/Linux */ + sprintf (name, "/dev/sd%c", unit + 'a'); +#elif defined(__GNU__) + /* GNU/Hurd */ + sprintf (name, "/dev/sd%d", unit); +#elif defined(__FreeBSD_kernel__) + /* kFreeBSD */ + if (get_kfreebsd_version () >= 400000) + sprintf (name, "/dev/da%d", unit); + else + sprintf (name, "/dev/rda%d", unit); +#elif defined(__NetBSD__) && defined(HAVE_OPENDISK) + /* NetBSD */ + char shortname[16]; + int fd; + + sprintf (shortname, "sd%d", unit); + fd = opendisk (shortname, O_RDONLY, name, + 16, /* length of NAME */ + 0 /* char device */ + ); + close (fd); +#elif defined(__OpenBSD__) + /* OpenBSD */ + sprintf (name, "/dev/rsd%dc", unit); +#elif defined(__QNXNTO__) + /* QNX RTP */ + /* QNX RTP doesn't distinguish SCSI from IDE, so it is better to + disable the detection of SCSI disks here. */ + *name = 0; +#elif defined(__CYGWIN__) + /* Cygwin emulates all disks as /dev/sdX. */ + sprintf (name, "/dev/sd%c", unit + 'a'); +#elif defined(__MINGW32__) + (void) unit; + *name = 0; +#else +# warning "BIOS SCSI drives cannot be guessed in your operating system." + /* Set NAME to a bogus string. */ + *name = 0; +#endif +} + +#ifdef __FreeBSD_kernel__ +static void +get_ada_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/ada%d", unit); +} + +static void +get_ataraid_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/ar%d", unit); +} + +static void +get_mfi_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/mfid%d", unit); +} +#endif + +#ifdef __linux__ +static void +get_virtio_disk_name (char *name, int unit) +{ +#ifdef __sparc__ + sprintf (name, "/dev/vdisk%c", unit + 'a'); +#else + sprintf (name, "/dev/vd%c", unit + 'a'); +#endif +} + +static void +get_dac960_disk_name (char *name, int controller, int drive) +{ + sprintf (name, "/dev/rd/c%dd%d", controller, drive); +} + +static void +get_acceleraid_disk_name (char *name, int controller, int drive) +{ + sprintf (name, "/dev/rs/c%dd%d", controller, drive); +} + +static void +get_ataraid_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/ataraid/d%c", unit + '0'); +} + +static void +get_i2o_disk_name (char *name, char unit) +{ + sprintf (name, "/dev/i2o/hd%c", unit); +} + +static void +get_cciss_disk_name (char *name, int controller, int drive) +{ + sprintf (name, "/dev/cciss/c%dd%d", controller, drive); +} + +static void +get_ida_disk_name (char *name, int controller, int drive) +{ + sprintf (name, "/dev/ida/c%dd%d", controller, drive); +} + +static void +get_mmc_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/mmcblk%d", unit); +} + +static void +get_xvd_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/xvd%c", unit + 'a'); +} +#endif + +static struct seen_device +{ + struct seen_device *next; + struct seen_device **prev; + const char *name; +} *seen; + +/* Check if DEVICE can be read. Skip any DEVICE that we have already seen. + If an error occurs, return zero, otherwise return non-zero. */ +static int +check_device_readable_unique (const char *device) +{ + char *real_device; + char buf[512]; + FILE *fp; + struct seen_device *seen_elt; + + /* If DEVICE is empty, just return error. */ + if (*device == 0) + return 0; + + /* Have we seen this device already? */ + real_device = canonicalize_file_name (device); + if (! real_device) + return 0; + if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), real_device)) + { + grub_dprintf ("deviceiter", "Already seen %s (%s)\n", + device, real_device); + goto fail; + } + + fp = fopen (device, "r"); + if (! fp) + { + switch (errno) + { +#ifdef ENOMEDIUM + case ENOMEDIUM: +# if 0 + /* At the moment, this finds only CDROMs, which can't be + read anyway, so leave it out. Code should be + reactivated if `removable disks' and CDROMs are + supported. */ + /* Accept it, it may be inserted. */ + return 1; +# endif + break; +#endif /* ENOMEDIUM */ + default: + /* Break case and leave. */ + break; + } + /* Error opening the device. */ + goto fail; + } + + /* Make sure CD-ROMs don't get assigned a BIOS disk number + before SCSI disks! */ +#ifdef __linux__ +# ifdef CDROM_GET_CAPABILITY + if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0) + goto fail; +# else /* ! CDROM_GET_CAPABILITY */ + /* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl. */ + { + struct hd_geometry hdg; + struct stat st; + + if (fstat (fileno (fp), &st)) + goto fail; + + /* If it is a block device and isn't a floppy, check if HDIO_GETGEO + succeeds. */ + if (S_ISBLK (st.st_mode) + && MAJOR (st.st_rdev) != FLOPPY_MAJOR + && ioctl (fileno (fp), HDIO_GETGEO, &hdg)) + goto fail; + } +# endif /* ! CDROM_GET_CAPABILITY */ +#endif /* __linux__ */ + +#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) +# ifdef CDIOCCLRDEBUG + if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0) + goto fail; +# endif /* CDIOCCLRDEBUG */ +#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */ + + /* Attempt to read the first sector. */ + if (fread (buf, 1, 512, fp) != 512) + { + fclose (fp); + goto fail; + } + + /* Remember that we've seen this device. */ + seen_elt = xmalloc (sizeof (*seen_elt)); + seen_elt->name = real_device; /* steal memory */ + grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); + + fclose (fp); + return 1; + +fail: + free (real_device); + return 0; +} + +static void +clear_seen_devices (void) +{ + while (seen) + { + struct seen_device *seen_elt = seen; + seen = seen->next; + free (seen_elt); + } + seen = NULL; +} + +#ifdef __linux__ +struct device +{ + char *stable; + char *kernel; +}; + +/* Sort by the kernel name for preference since that most closely matches + older device.map files, but sort by stable by-id names as a fallback. + This is because /dev/disk/by-id/ usually has a few alternative + identifications of devices (e.g. ATA vs. SATA). + check_device_readable_unique will ensure that we only get one for any + given disk, but sort the list so that the choice of which one we get is + stable. */ +static int +compare_devices (const void *a, const void *b) +{ + const struct device *left = (const struct device *) a; + const struct device *right = (const struct device *) b; + + if (left->kernel && right->kernel) + { + int ret = strcmp (left->kernel, right->kernel); + if (ret) + return ret; + } + + return strcmp (left->stable, right->stable); +} +#endif /* __linux__ */ + +void +grub_util_iterate_devices (int (*hook) (const char *, int, void *), void *hook_data, + int floppy_disks) +{ + int i; + + clear_seen_devices (); + + /* Floppies. */ + for (i = 0; i < floppy_disks; i++) + { + char name[16]; + struct stat st; + + get_floppy_disk_name (name, i); + if (stat (name, &st) < 0) + break; + /* In floppies, write the map, whether check_device_readable_unique + succeeds or not, because the user just may not insert floppies. */ + if (hook (name, 1, hook_data)) + goto out; + } + +#ifdef __linux__ + { + DIR *dir = opendir ("/dev/disk/by-id"); + + if (dir) + { + struct dirent *entry; + struct device *devs; + size_t devs_len = 0, devs_max = 1024, dev; + + devs = xmalloc (devs_max * sizeof (*devs)); + + /* Dump all the directory entries into names, resizing if + necessary. */ + for (entry = readdir (dir); entry; entry = readdir (dir)) + { + /* Skip current and parent directory entries. */ + if (strcmp (entry->d_name, ".") == 0 || + strcmp (entry->d_name, "..") == 0) + continue; + /* Skip partition entries. */ + if (strstr (entry->d_name, "-part")) + continue; + /* Skip device-mapper entries; we'll handle the ones we want + later. */ + if (strncmp (entry->d_name, "dm-", sizeof ("dm-") - 1) == 0) + continue; + /* Skip RAID entries; they are handled by upper layers. */ + if (strncmp (entry->d_name, "md-", sizeof ("md-") - 1) == 0) + continue; + if (devs_len >= devs_max) + { + devs_max *= 2; + devs = xrealloc (devs, devs_max * sizeof (*devs)); + } + devs[devs_len].stable = + xasprintf ("/dev/disk/by-id/%s", entry->d_name); + devs[devs_len].kernel = + canonicalize_file_name (devs[devs_len].stable); + devs_len++; + } + + qsort (devs, devs_len, sizeof (*devs), &compare_devices); + + closedir (dir); + + /* Now add all the devices in sorted order. */ + for (dev = 0; dev < devs_len; ++dev) + { + if (check_device_readable_unique (devs[dev].stable)) + { + if (hook (devs[dev].stable, 0, hook_data)) + goto out; + } + free (devs[dev].stable); + free (devs[dev].kernel); + } + free (devs); + } + } + + if (have_devfs ()) + { + i = 0; + while (1) + { + char discn[32]; + char name[PATH_MAX]; + struct stat st; + + /* Linux creates symlinks "/dev/discs/discN" for convenience. + The way to number disks is the same as GRUB's. */ + sprintf (discn, "/dev/discs/disc%d", i++); + if (stat (discn, &st) < 0) + break; + + if (realpath (discn, name)) + { + strcat (name, "/disc"); + if (hook (name, 0, hook_data)) + goto out; + } + } + goto out; + } +#endif /* __linux__ */ + + /* IDE disks. */ + for (i = 0; i < 96; i++) + { + char name[16]; + + get_ide_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + +#ifdef __FreeBSD_kernel__ + /* IDE disks using ATA Direct Access driver. */ + if (get_kfreebsd_version () >= 800000) + for (i = 0; i < 96; i++) + { + char name[16]; + + get_ada_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + + /* ATARAID disks. */ + for (i = 0; i < 8; i++) + { + char name[20]; + + get_ataraid_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + + /* LSI MegaRAID SAS. */ + for (i = 0; i < 32; i++) + { + char name[20]; + + get_mfi_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } +#endif + +#ifdef __linux__ + /* Virtio disks. */ + for (i = 0; i < 26; i++) + { + char name[16]; + + get_virtio_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + + /* ATARAID disks. */ + for (i = 0; i < 8; i++) + { + char name[20]; + + get_ataraid_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + + /* Xen virtual block devices. */ + for (i = 0; i < 26; i++) + { + char name[16]; + + get_xvd_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } +#endif /* __linux__ */ + + /* The rest is SCSI disks. */ + for (i = 0; i < 48; i++) + { + char name[16]; + + get_scsi_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + +#ifdef __linux__ + /* This is for DAC960 - we have + /dev/rd/cdp. + + DAC960 driver currently supports up to 8 controllers, 32 logical + drives, and 7 partitions. */ + { + int controller, drive; + + for (controller = 0; controller < 8; controller++) + { + for (drive = 0; drive < 15; drive++) + { + char name[24]; + + get_dac960_disk_name (name, controller, drive); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + } + } + + /* This is for Mylex Acceleraid - we have + /dev/rd/cdp. */ + { + int controller, drive; + + for (controller = 0; controller < 8; controller++) + { + for (drive = 0; drive < 15; drive++) + { + char name[24]; + + get_acceleraid_disk_name (name, controller, drive); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + } + } + + /* This is for CCISS - we have + /dev/cciss/cdp. */ + { + int controller, drive; + + for (controller = 0; controller < 3; controller++) + { + for (drive = 0; drive < 16; drive++) + { + char name[24]; + + get_cciss_disk_name (name, controller, drive); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + } + } + + /* This is for Compaq Intelligent Drive Array - we have + /dev/ida/cdp. */ + { + int controller, drive; + + for (controller = 0; controller < 3; controller++) + { + for (drive = 0; drive < 16; drive++) + { + char name[24]; + + get_ida_disk_name (name, controller, drive); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + } + } + + /* This is for I2O - we have /dev/i2o/hd */ + { + char unit; + + for (unit = 'a'; unit < 'f'; unit++) + { + char name[24]; + + get_i2o_disk_name (name, unit); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + } + + /* MultiMediaCard (MMC). */ + for (i = 0; i < 10; i++) + { + char name[16]; + + get_mmc_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + goto out; + } + } + +# ifdef HAVE_DEVICE_MAPPER +# define dmraid_check(cond, ...) \ + if (! (cond)) \ + { \ + grub_dprintf ("deviceiter", __VA_ARGS__); \ + goto dmraid_end; \ + } + + /* DM-RAID. */ + if (grub_device_mapper_supported ()) + { + struct dm_tree *tree = NULL; + struct dm_task *task = NULL; + struct dm_names *names = NULL; + unsigned int next = 0; + void *top_handle, *second_handle; + struct dm_tree_node *root, *top, *second; + + /* Build DM tree for all devices. */ + tree = dm_tree_create (); + dmraid_check (tree, "dm_tree_create failed\n"); + task = dm_task_create (DM_DEVICE_LIST); + dmraid_check (task, "dm_task_create failed\n"); + dmraid_check (dm_task_run (task), "dm_task_run failed\n"); + names = dm_task_get_names (task); + dmraid_check (names, "dm_task_get_names failed\n"); + dmraid_check (names->dev, "No DM devices found\n"); + do + { + names = (struct dm_names *) ((char *) names + next); + dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), + MINOR (names->dev)), + "dm_tree_add_dev (%s) failed\n", names->name); + next = names->next; + } + while (next); + + /* Walk the second-level children of the inverted tree; that is, devices + which are directly composed of non-DM devices such as hard disks. + This class includes all DM-RAID disks and excludes all DM-RAID + partitions. */ + root = dm_tree_find_node (tree, 0, 0); + top_handle = NULL; + top = dm_tree_next_child (&top_handle, root, 1); + while (top) + { + second_handle = NULL; + second = dm_tree_next_child (&second_handle, top, 1); + while (second) + { + const char *node_name, *node_uuid; + char *name; + + node_name = dm_tree_node_get_name (second); + dmraid_check (node_name, "dm_tree_node_get_name failed\n"); + node_uuid = dm_tree_node_get_uuid (second); + dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); + if (strstr (node_uuid, "DMRAID-") == 0) + { + grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); + goto dmraid_next_child; + } + + name = xasprintf ("/dev/mapper/%s", node_name); + if (check_device_readable_unique (name)) + { + if (hook (name, 0, hook_data)) + { + free (name); + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + goto out; + } + } + free (name); + +dmraid_next_child: + second = dm_tree_next_child (&second_handle, top, 1); + } + top = dm_tree_next_child (&top_handle, root, 1); + } + +dmraid_end: + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + } +# endif /* HAVE_DEVICE_MAPPER */ +#endif /* __linux__ */ + +out: + clear_seen_devices (); +} diff --git a/util/devicemap.c b/util/devicemap.c new file mode 100644 index 0000000..c618644 --- /dev/null +++ b/util/devicemap.c @@ -0,0 +1,13 @@ +#include + +#include + +void +grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy, + int *num_fd, int *num_hd) +{ + if (is_floppy) + fprintf (fp, "(fd%d)\t%s\n", (*num_fd)++, name); + else + fprintf (fp, "(hd%d)\t%s\n", (*num_hd)++, name); +} diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c new file mode 100644 index 0000000..c4bbdbf --- /dev/null +++ b/util/grub-mkdevicemap.c @@ -0,0 +1,181 @@ +/* grub-mkdevicemap.c - make a device map file automatically */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define _GNU_SOURCE 1 +#include + +#include "progname.h" + +/* Context for make_device_map. */ +struct make_device_map_ctx +{ + FILE *fp; + int num_fd; + int num_hd; +}; + +/* Helper for make_device_map. */ +static int +process_device (const char *name, int is_floppy, void *data) +{ + struct make_device_map_ctx *ctx = data; + + grub_util_emit_devicemap_entry (ctx->fp, (char *) name, + is_floppy, &ctx->num_fd, &ctx->num_hd); + return 0; +} + +static void +make_device_map (const char *device_map, int floppy_disks) +{ + struct make_device_map_ctx ctx = { + .num_fd = 0, + .num_hd = 0 + }; + + if (strcmp (device_map, "-") == 0) + ctx.fp = stdout; + else + ctx.fp = fopen (device_map, "w"); + + if (! ctx.fp) + grub_util_error (_("cannot open %s"), device_map); + + grub_util_iterate_devices (process_device, &ctx, floppy_disks); + + if (ctx.fp != stdout) + fclose (ctx.fp); +} + +static struct option options[] = + { + {"device-map", required_argument, 0, 'm'}, + {"probe-second-floppy", no_argument, 0, 's'}, + {"no-floppy", no_argument, 0, 'n'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, + _("Try `%s --help' for more information.\n"), program_name); + else + printf (_("\ +Usage: %s [OPTION]...\n\ +\n\ +Generate a device map file automatically.\n\ +\n\ + -n, --no-floppy do not probe any floppy drive\n\ + -s, --probe-second-floppy probe the second floppy drive\n\ + -m, --device-map=FILE use FILE as the device map [default=%s]\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n\ +"), program_name, + DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); + + exit (status); +} + +int +main (int argc, char *argv[]) +{ + char *dev_map = 0; + int floppy_disks = 1; + + grub_util_host_init (&argc, &argv); + + /* Check for options. */ + while (1) + { + int c = getopt_long (argc, argv, "snm:r:hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'm': + if (dev_map) + free (dev_map); + + dev_map = xstrdup (optarg); + break; + + case 'n': + floppy_disks = 0; + break; + + case 's': + floppy_disks = 2; + break; + + case 'h': + usage (0); + break; + + case 'V': + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + if (verbosity > 1) + grub_env_set ("debug", "all"); + + make_device_map (dev_map ? : DEFAULT_DEVICE_MAP, floppy_disks); + + free (dev_map); + + return 0; +} debian/patches/mkconfig_recovery_title.patch0000664000000000000000000001232412524662415016565 0ustar From 41ab038c1cab19aca1266561fe41a27d6f5a33f3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:33 +0000 Subject: Add GRUB_RECOVERY_TITLE option This allows the controversial "recovery mode" text to be customised. Bug-Ubuntu: https://bugs.launchpad.net/bugs/1240360 Forwarded: no Last-Update: 2013-12-25 Patch-Name: mkconfig_recovery_title.patch --- docs/grub.texi | 5 +++++ util/grub-mkconfig.in | 7 ++++++- util/grub.d/10_hurd.in | 4 ++-- util/grub.d/10_kfreebsd.in | 2 +- util/grub.d/10_linux.in | 2 +- util/grub.d/10_netbsd.in | 2 +- util/grub.d/20_linux_xen.in | 2 +- 7 files changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/grub.texi b/docs/grub.texi index 28743d5..af020ec 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1499,6 +1499,11 @@ restricted or limited. This option is only effective when GRUB was configured with the @option{--enable-quick-boot} option. +@item GRUB_RECOVERY_TITLE +This option sets the English text of the string that will be displayed in +parentheses to indicate that a boot option is provided to help users recover +a broken system. The default is "recovery mode". + @end table The following options are still accepted for compatibility with existing diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 17350d4..ccce9e5 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -186,6 +186,10 @@ GRUB_ACTUAL_DEFAULT="$GRUB_DEFAULT" if [ "x${GRUB_ACTUAL_DEFAULT}" = "xsaved" ] ; then GRUB_ACTUAL_DEFAULT="`"${grub_editenv}" - list | sed -n '/^saved_entry=/ s,^saved_entry=,,p'`" ; fi +if [ "x${GRUB_RECOVERY_TITLE}" = "x" ]; then + GRUB_RECOVERY_TITLE="recovery mode" +fi + # These are defined in this script, export them here so that user can # override them. @@ -237,7 +241,8 @@ export GRUB_DEFAULT \ GRUB_BADRAM \ GRUB_OS_PROBER_SKIP_LIST \ GRUB_DISABLE_SUBMENU \ - GRUB_RECORDFAIL_TIMEOUT + GRUB_RECORDFAIL_TIMEOUT \ + GRUB_RECOVERY_TITLE if test "x${grub_cfg}" != "x"; then rm -f "${grub_cfg}.new" diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 82dfe19..6fafe1a 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -88,8 +88,8 @@ hurd_entry () { if [ x$type != xsimple ] ; then if [ x$type = xrecovery ] ; then - title="$(gettext_printf "%s, with Hurd %s (recovery mode)" "${OS}" "${kernel_base}")" - oldtitle="$OS using $kernel_base (recovery mode)" + title="$(gettext_printf "%s, with Hurd %s (%s)" "${OS}" "${kernel_base}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" + oldtitle="$OS using $kernel_base ($GRUB_RECOVERY_TITLE)" else title="$(gettext_printf "%s, with Hurd %s" "${OS}" "${kernel_base}")" oldtitle="$OS using $kernel_base" diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index a524762..7b04a87 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -76,7 +76,7 @@ kfreebsd_entry () fi if [ x$type != xsimple ] ; then if [ x$type = xrecovery ] ; then - title="$(gettext_printf "%s, with kFreeBSD %s (recovery mode)" "${os}" "${version}")" + title="$(gettext_printf "%s, with kFreeBSD %s (%s)" "${os}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" else title="$(gettext_printf "%s, with kFreeBSD %s" "${os}" "${version}")" fi diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 8d95887..024a89e 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -114,7 +114,7 @@ linux_entry () if [ x$type != xsimple ] ; then case $type in recovery) - title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;; + title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" ;; *) title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;; esac diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in index 29a0e41..21c7e7d 100644 --- a/util/grub.d/10_netbsd.in +++ b/util/grub.d/10_netbsd.in @@ -102,7 +102,7 @@ netbsd_entry () if [ x$type != xsimple ] ; then if [ x$type = xrecovery ] ; then - title="$(gettext_printf "%s, with kernel %s (via %s, recovery mode)" "${OS}" "$(echo ${kernel} | sed -e 's,^.*/,,')" "${loader}")" + title="$(gettext_printf "%s, with kernel %s (via %s, %s)" "${OS}" "$(echo ${kernel} | sed -e 's,^.*/,,')" "${loader}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" else title="$(gettext_printf "%s, with kernel %s (via %s)" "${OS}" "$(echo ${kernel} | sed -e 's,^.*/,,')" "${loader}")" fi diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index fb4f615..10a3db5 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -93,7 +93,7 @@ linux_entry () fi if [ x$type != xsimple ] ; then if [ x$type = xrecovery ] ; then - title="$(gettext_printf "%s, with Xen %s and Linux %s (recovery mode)" "${os}" "${xen_version}" "${version}")" + title="$(gettext_printf "%s, with Xen %s and Linux %s (%s)" "${os}" "${xen_version}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" else title="$(gettext_printf "%s, with Xen %s and Linux %s" "${os}" "${xen_version}" "${version}")" fi debian/patches/mkconfig_mid_upgrade.patch0000664000000000000000000000253012524662415016004 0ustar From a20dfe95e776dde2707b3daa6b3887944932dd57 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:03 +0000 Subject: Bail out if trying to run grub-mkconfig during upgrade to 2.00 Since files in /etc/grub.d/ are conffiles, they are not put in place until grub-common is configured, meaning that they may be out of sync with the parts of grub-mkconfig that reside in /usr/. In GRUB 1.99, /etc/grub.d/00_header contained a reference to ${GRUB_PREFIX}/video.lst. This and other code from 1.99 breaks with 2.00's grub-mkconfig. Deferring this to when grub-PLATFORM.postinst eventually runs is safe and avoids this problem. Forwarded: no Last-Update: 2013-12-25 Patch-Name: mkconfig_mid_upgrade.patch --- util/grub-mkconfig.in | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 0d7cabb..81a9afd 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -99,6 +99,13 @@ do esac done +if fgrep -qs '${GRUB_PREFIX}/video.lst' "${grub_mkconfig_dir}/00_header"; then + echo "GRUB >= 2.00 has been unpacked but not yet configured." >&2 + echo "grub-mkconfig will not work until the upgrade is complete." >&2 + echo "It should run later as part of configuring the new GRUB packages." >&2 + exit 0 +fi + if [ "x$EUID" = "x" ] ; then EUID=`id -u` fi debian/patches/mkconfig_signed_kernel.patch0000664000000000000000000000322312524662415016335 0ustar From d17e028ba932b3583e36074e62fa1a1bf1b24bd1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:21 +0000 Subject: Generate configuration for signed UEFI kernels if available Forwarded: no Last-Update: 2013-12-25 Patch-Name: mkconfig_signed_kernel.patch --- util/grub.d/10_linux.in | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index d343263..1b55116 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -149,8 +149,16 @@ linux_entry () message="$(gettext_printf "Loading Linux %s ..." ${version})" sed "s/^/$submenu_indentation/" << EOF echo '$(echo "$message" | grub_quote)' +EOF + if test -d /sys/firmware/efi && test -e "${linux}.efi.signed"; then + sed "s/^/$submenu_indentation/" << EOF + linux ${rel_dirname}/${basename}.efi.signed root=${linux_root_device_thisversion} ro ${args} +EOF + else + sed "s/^/$submenu_indentation/" << EOF linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} EOF + fi if test -n "${initrd}" ; then # TRANSLATORS: ramdisk isn't identifier. Should be translated. message="$(gettext_printf "Loading initial ramdisk ...")" @@ -196,6 +204,13 @@ submenu_indentation="" is_top_level=true while [ "x$list" != "x" ] ; do linux=`version_find_latest $list` + case $linux in + *.efi.signed) + # We handle these in linux_entry. + list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '` + continue + ;; + esac gettext_printf "Found linux image: %s\n" "$linux" >&2 basename=`basename $linux` dirname=`dirname $linux` debian/patches/ieee1275-pseries-emulation.patch0000664000000000000000000000256512524662415016550 0ustar From 9eb07b055ef09b7afb79ceadbdcb7ec154c51c32 Mon Sep 17 00:00:00 2001 From: Nikunj A Dadhania Date: Thu, 20 Mar 2014 16:57:12 +0530 Subject: ieee1275: check for IBM pseries emulated machine is_qemu is not being set lead to disabling of feature like GRUB_IEEE1275_FLAG_HAS_CURSORONOFF. This resulted in cursor not being displayed during the grub-menu edit. Author: Nikunj A Dadhania Origin: upstream, http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commitdiff;h=e4a1fe391906bfcd1a778c5ec4e242c4b07d429d Forwarded: not-needed Last-Update: 2014-03-24 Patch-Name: ieee1275-pseries-emulation.patch --- grub-core/kern/ieee1275/cmain.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c index d92ae14..3e12e6b 100644 --- a/grub-core/kern/ieee1275/cmain.c +++ b/grub-core/kern/ieee1275/cmain.c @@ -84,8 +84,10 @@ grub_ieee1275_find_options (void) rc = grub_ieee1275_get_property (root, "model", tmp, sizeof (tmp), 0); - if (rc >= 0 && !grub_strcmp (tmp, "Emulated PC")) + if (rc >= 0 && (!grub_strcmp (tmp, "Emulated PC") + || !grub_strcmp (tmp, "IBM pSeries (emulated by qemu)"))) { is_qemu = 1; + } if (rc >= 0 && grub_strncmp (tmp, "IBM", 3) == 0) grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS); debian/grub-common.maintscript.kfreebsd.in0000664000000000000000000000016112524662415016072 0ustar # Removed in 1.96+20090307-1. rm_conffile /etc/grub.d/10_hurd 2.00-14~ rm_conffile /etc/grub.d/10_linux 2.00-14~ debian/.git-dpm0000664000000000000000000000043012524662415010536 0ustar # see git-dpm(1) from git-dpm package 5439f9e3d0ad6929ff3cb2fbe3dc0fd9f2a326e1 5439f9e3d0ad6929ff3cb2fbe3dc0fd9f2a326e1 e8f07821cce1bd0ab6d5622c2a42440f15f4fd71 e8f07821cce1bd0ab6d5622c2a42440f15f4fd71 grub2_2.02~beta2.orig.tar.xz 1bf580f1e8bce4909a7ac7ca485cee02b00ed383 5798740 debian/install.in0000664000000000000000000000016012524662415011172 0ustar ../../debian/kernel/zz-update-grub etc/kernel/postinst.d ../../debian/kernel/zz-update-grub etc/kernel/postrm.d debian/postrm.in0000664000000000000000000000245612524662415011062 0ustar #!/bin/bash set -e case "$1" in purge) rm -f /etc/default/grub if which ucf >/dev/null ; then ucf --purge /etc/default/grub fi if which ucfr >/dev/null ; then ucfr --purge @PACKAGE@ /etc/default/grub || true fi case @PACKAGE@ in grub-pc) # debconf could have been purged if [ -e /usr/share/debconf/confmodule ] ; then . /usr/share/debconf/confmodule fi db_input high grub-pc/postrm_purge_boot_grub || true db_go || true db_get grub-pc/postrm_purge_boot_grub || true if [ "$RET" = "true" ] ; then rm -f /boot/grub/{grub.cfg,ascii.pf2,unicode.pf2,moreblue-orbit-grub.png,*.mod,*.lst,*.img,efiemu32.o,efiemu64.o,device.map,grubenv,installed-version,.background_cache.jpeg,.background_cache.png,.background_cache.tga} || true rm -rf /boot/grub/locale rmdir --ignore-fail-on-non-empty /boot/grub || true fi ;; grub-efi-ia32|grub-efi-amd64) rm -f /boot/grub/unicode.pf2 ;; esac ;; remove|upgrade|failed-upgrade|abort-upgrade|abort-install) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 debian/grub-emu-dbg.install.in0000664000000000000000000000015012524662415013445 0ustar usr/lib/grub/*-*/*.exec usr/lib/grub/*-*/*.module usr/lib/grub/*-*/gdb_grub usr/lib/grub/*-*/gmodule.pl debian/NEWS0000664000000000000000000000111012524662415007667 0ustar grub2 (1.96+20090609-1) experimental; urgency=low Before this version, grub-efi was 32bit on i386 and 64bit on amd64. However, EFI can be 32bit even if you have a 64bit CPU, like in the first MacBook models with Core 2 Duo released in late 2006. Thus, grub-efi has been split into grub-efi-amd64 and grub-efi-ia32 which are available on both amd64 and i386. If you've experienced problems trying to load grub.efi, please try again using the package that doesn't match your CPU's architecture. -- Felix Zielcke Tue, 09 Jun 2009 19:21:15 +0200 debian/grub-ieee1275-bin.install.amd64.in0000664000000000000000000000004612524662415015037 0ustar usr/lib/grub/@CPU_PLATFORM@/efiemu*.o debian/copyright0000664000000000000000000005433612524662415011145 0ustar Name: GNU GRUB Source: http://www.gnu.org/software/grub/ Files: * Copyright: 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc License: GPL-3+ Files: debian/* Copyright: 2003, 2004, 2005, 2006, 2007, 2008, 2009, Robert Millan 2005, 2006, 2007, Otavio Salvador 2008, 2009, Felix Zielcke 2009, Jordi Mallach License: GPL-3+ Files: debian/grub-extras/* Copyright: Nathan Coulson 2003, 2007 Free Software Foundation, Inc 2003 NIIBE Yutaka License: GPL-3+ Files: themes/starfield/* Copyright: 2012 Free Software Foundation, Inc License: CC-BY-SA-3.0 Files: themes/starfield/theme.txt Copyright: 2011 Daniel Tschudi License: Expat License: GPL-3+ On Debian systems the full text of the GNU General Public License can be found in the `/usr/share/common-licenses/GPL' file. License: CC-BY-SA-3.0 CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. . License . THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. . BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. . 1. Definitions "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined below) for the purposes of this License. "Creative Commons Compatible License" means a license that is listed at http://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being essentially equivalent to this License, including, at a minimum, because that license: (i) contains terms that have the same purpose, meaning and effect as the License Elements of this License; and, (ii) explicitly permits the relicensing of adaptations of works made available under that license under this License or a Creative Commons jurisdiction license with the same License Elements as this License. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. . 2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. . 3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: . to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; to Distribute and Publicly Perform the Work including as incorporated in Collections; and, to Distribute and Publicly Perform Adaptations. . For the avoidance of doubt: Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and, Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License. . The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved. . 4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: . You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested. You may Distribute or Publicly Perform an Adaptation only under the terms of: (i) this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible License. If you license the Adaptation under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Adaptation under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and the following provisions: (I) You must include a copy of, or the URI for, the Applicable License with every copy of each Adaptation You Distribute or Publicly Perform; (II) You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform; (IV) when You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Ssection 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. . 5. Representations, Warranties and Disclaimer . UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. . 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. . 7. Termination . This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. . 8. Miscellaneous . Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. License: Expat Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. debian/watch0000664000000000000000000000033012524662415010224 0ustar version=3 opts=pgpsigurlmangle=s/$/.sig/ \ ftp://ftp.gnu.org/gnu/grub/grub-([a-z0-9.~]+).tar.xz debian uupdate opts=pgpsigurlmangle=s/$/.sig/ \ ftp://alpha.gnu.org/gnu/grub/grub-([a-z0-9.~]+).tar.xz debian uupdate debian/grub-ieee1275.install.sparc.in0000664000000000000000000000010412524662415014461 0ustar usr/sbin/grub-sparc64-setup usr/share/man/man8/grub-sparc64-setup.8 debian/grub-common.install.linux.in0000664000000000000000000000006312524662415014556 0ustar usr/bin/grub-mount usr/share/man/man1/grub-mount.1 debian/grub-ieee1275-bin.install.kopensolaris-i386.in0000664000000000000000000000004612524662415017324 0ustar usr/lib/grub/@CPU_PLATFORM@/efiemu*.o debian/platform-subst0000775000000000000000000000146012524662415012110 0ustar #! /usr/bin/perl use warnings; use strict; my %subst = (); while ($ARGV[0] =~ /(.*?)=(.*)/) { $subst{$1} = $2; shift; } die "no package specified\n" unless exists $subst{PACKAGE}; (my $package = $subst{PACKAGE}) =~ s/-(?:bin|dbg)$//; my $grub_dir_path = "debian/tmp-$package/usr/lib/grub"; opendir my $grub_dir, $grub_dir_path or die "can't opendir $grub_dir_path: $!"; my @cpu_platforms = grep { !/^\./ } readdir $grub_dir; closedir $grub_dir; $subst{FIRST_CPU_PLATFORM} = $cpu_platforms[0]; sub emit ($) { my $line = shift; while (my ($key, $value) = each %subst) { $line =~ s/\@$key\@/$value/g; } print $line; } while (<>) { if (/\@CPU_PLATFORM\@/) { for my $cpu_platform (@cpu_platforms) { (my $line = $_) =~ s/\@CPU_PLATFORM\@/$cpu_platform/g; emit($line); } } else { emit($_); } } debian/grub-linuxbios.postinst0000664000000000000000000000066512524662415013764 0ustar #! /bin/sh set -e case "$1" in configure) if dpkg --compare-versions "$2" lt-nl 2.00-6; then # Force dpkg to replace this directory with a symlink. if [ ! -L /usr/share/doc/grub-linuxbios ] && [ -d /usr/share/doc/grub-linuxbios ]; then if rmdir /usr/share/doc/grub-linuxbios 2>/dev/null; then ln -sf grub-common /usr/share/doc/grub-linuxbios fi fi fi ;; esac #DEBHELPER# exit 0 debian/grub-firmware-qemu.install0000664000000000000000000000005712524662415014307 0ustar obj/grub-firmware-qemu/grub.bin usr/share/qemu debian/grub-common.install.kfreebsd.in0000664000000000000000000000006312524662415015204 0ustar usr/bin/grub-mount usr/share/man/man1/grub-mount.1 debian/grub-efi.postinst0000664000000000000000000000063512524662415012510 0ustar #! /bin/sh set -e case "$1" in configure) if dpkg --compare-versions "$2" lt-nl 2.00-6; then # Force dpkg to replace this directory with a symlink. if [ ! -L /usr/share/doc/grub-efi ] && [ -d /usr/share/doc/grub-efi ]; then if rmdir /usr/share/doc/grub-efi 2>/dev/null; then ln -sf grub-common /usr/share/doc/grub-efi fi fi fi ;; esac #DEBHELPER# exit 0 debian/templates.in0000664000000000000000000000346712524662415011537 0ustar Template: grub2/linux_cmdline Type: string _Description: Linux command line: The following Linux command line was extracted from /etc/default/grub or the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is correct, and modify it if necessary. The command line is allowed to be empty. Template: grub2/linux_cmdline_default Type: string Default: @DEFAULT_CMDLINE@ _Description: Linux default command line: The following string will be used as Linux parameters for the default menu entry but not for the recovery mode. # still unused Template: grub2/kfreebsd_cmdline Type: string _Description: kFreeBSD command line: The following kFreeBSD command line was extracted from /etc/default/grub or the `kopt' parameter in GRUB Legacy's menu.lst. Please verify that it is correct, and modify it if necessary. The command line is allowed to be empty. # still unused Template: grub2/kfreebsd_cmdline_default Type: string Default: @DEFAULT_CMDLINE@ _Description: kFreeBSD default command line: The following string will be used as kFreeBSD parameters for the default menu entry but not for the recovery mode. Template: grub2/device_map_regenerated Type: note _Description: /boot/grub/device.map has been regenerated The file /boot/grub/device.map has been rewritten to use stable device names. In most cases, this should significantly reduce the need to change it in future, and boot menu entries generated by GRUB should not be affected. . However, since more than one disk is present in the system, it is possible that the system is depending on the old device map. Please check whether there are any custom boot menu entries that rely on GRUB's (hdN) drive numbering, and update them if necessary. . If you do not understand this message, or if there are no custom boot menu entries, you can ignore this message. debian/install-bin.in0000664000000000000000000000026212524662415011743 0ustar usr/lib/grub/@CPU_PLATFORM@/*.img usr/lib/grub/@CPU_PLATFORM@/*.lst usr/lib/grub/@CPU_PLATFORM@/*.mod usr/lib/grub/@CPU_PLATFORM@/config.h usr/lib/grub/@CPU_PLATFORM@/modinfo.sh debian/grub-emu.postinst.in0000664000000000000000000000064112524662415013135 0ustar #! /bin/sh set -e case "$1" in configure) if dpkg --compare-versions "$2" lt-nl 2.00-2; then # Force dpkg to replace this directory with a symlink. if [ ! -L /usr/share/doc/@PACKAGE@ ] && [ -d /usr/share/doc/@PACKAGE@ ]; then if rmdir /usr/share/doc/@PACKAGE@ 2>/dev/null; then ln -sf grub-common /usr/share/doc/@PACKAGE@ fi fi fi ;; esac #DEBHELPER# exit 0 debian/update-grub.80000664000000000000000000000053012524662415011505 0ustar .\" Copyright 2009 Felix Zielcke .\" Lincensed under GPL3+ .TH UPDATE-GRUB "8" "April 2009" .SH NAME update-grub, update-grub2 \- stub for grub-mkconfig .SH SYNOPSIS .B update-grub .SH DESCRIPTION .B update-grub is a stub for running .B grub-mkconfig -o /boot/grub/grub.cfg to generate a grub2 config file. .SH "SEE ALSO" .BR grub-mkconfig (8) debian/grub-emu.install.in0000664000000000000000000000030012524662415012710 0ustar usr/bin/grub-emu usr/bin/grub-emu-lite usr/lib/grub/*-*/*.img usr/lib/grub/*-*/*.lst usr/lib/grub/*-*/*.mod usr/lib/grub/*-*/config.h usr/lib/grub/*-*/modinfo.sh usr/share/man/man1/grub-emu.1 debian/grub-common.pm-sleep0000664000000000000000000000032212524662415013065 0ustar #!/bin/sh # Tell grub that resume was successful case "$1" in thaw) [ -s /boot/grub/grubenv ] || rm -f /boot/grub/grubenv mkdir -p /boot/grub grub-editenv /boot/grub/grubenv unset recordfail ;; esac debian/grub2-common.links0000664000000000000000000000016012524662415012545 0ustar usr/sbin/update-grub usr/sbin/update-grub2 usr/share/man/man8/update-grub.8 usr/share/man/man8/update-grub2.8 debian/dirs.in0000664000000000000000000000004012524662415010462 0ustar usr/bin usr/sbin usr/share/grub debian/clean0000664000000000000000000000003312524662415010200 0ustar debian/grub-common.install debian/grub-rescue-pc.README.Debian0000664000000000000000000000134112524662415014061 0ustar grub-rescue-pc ~~~~~~~~~~~~~~ How to test the images with qemu: qemu -fda /usr/lib/grub-rescue/grub-rescue-floppy.img qemu -cdrom /usr/lib/grub-rescue/grub-rescue-cdrom.iso qemu -hda /usr/lib/grub-rescue/grub-rescue-usb.img How to write the images to bootable media: sudo dd if=/usr/lib/grub-rescue/grub-rescue-floppy.img of=/dev/fd0 bs=32k sudo wodim /usr/lib/grub-rescue/grub-rescue-cdrom.iso # or just use your favourite CD burning program sudo dd if=/usr/lib/grub-rescue/grub-rescue-usb.img of=DEVICE bs=32k # where DEVICE is something like /dev/sdb, corresponding to your USB # stick's device name; be VERY CAREFUL that this is the correct device as # otherwise you could destroy data on your hard disk! debian/grub2.postinst0000664000000000000000000000062112524662415012024 0ustar #! /bin/sh set -e case "$1" in configure) if dpkg --compare-versions "$2" lt-nl 2.00-6; then # Force dpkg to replace this directory with a symlink. if [ ! -L /usr/share/doc/grub2 ] && [ -d /usr/share/doc/grub2 ]; then if rmdir /usr/share/doc/grub2 2>/dev/null; then ln -sf grub-common /usr/share/doc/grub2 fi fi fi ;; esac #DEBHELPER# exit 0 debian/grub-extras/0000775000000000000000000000000012524676037011447 5ustar debian/grub-extras/915resolution/0000775000000000000000000000000012524676037014111 5ustar debian/grub-extras/915resolution/915resolution.c0000664000000000000000000006524012524662415016721 0ustar /* 915resolution - Utility to change vbemodes on the intel * integrated video chipset */ /* * Based on Nathan Coulson's http://nathancoulson.com/proj/eee/grub-1.96-915resolution-0.5.2-3.patch * Oct 10, 2008, Released as 915 * Oct 10, 2008, Updated to include support for 945GM thanks to Scot Doyle */ /* Copied from 915 resolution created by steve tomjenovic * 915 resolution was in the public domain. * * All I have done, was make the above program run within * the grub2 environment. * * Some of the checks are still commented, as I did not find * easy replacement for memmem. * * Slightly edited by Nathan Coulson (conathan@gmail.com) */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2003,2007 Free Software Foundation, Inc. * Copyright (C) 2003 NIIBE Yutaka * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GRUB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ /* 915 resolution by steve tomljenovic * * This was tested only on Sony VGN-FS550. Use at your own risk * * This code is based on the techniques used in : * * - 855patch. Many thanks to Christian Zietz (czietz gmx net) * for demonstrating how to shadow the VBIOS into system RAM * and then modify it. * * - 1280patch by Andrew Tipton (andrewtipton null li). * * - 855resolution by Alain Poirier * * This source code is into the public domain. */ #include #include #include #include #include #include #include GRUB_MOD_LICENSE ("GPLv3+"); #define printf grub_printf #define malloc grub_malloc #define free grub_free #define strcmp grub_strcmp #define fprintf(stream, ...) grub_printf(__VA_ARGS__) #define strtol(x,y,z) grub_strtoul(x,y,z) #define atoi(x) grub_strtoul(x,NULL,10) #define assert(x) #define memset grub_memset #define outl grub_outl #define outb grub_outb #define inl grub_inl #define inb grub_inb #define NEW(a) ((a *)(malloc(sizeof(a)))) #define FREE(a) (free(a)) #define VBIOS_START 0xc0000 #define VBIOS_SIZE 0x10000 #define VBIOS_FILE "/dev/mem" #define FALSE 0 #define TRUE 1 #define MODE_TABLE_OFFSET_845G 617 #define RES915_VERSION "0.5.3" #define ATI_SIGNATURE1 "ATI MOBILITY RADEON" #define ATI_SIGNATURE2 "ATI Technologies Inc" #define NVIDIA_SIGNATURE "NVIDIA Corp" #define INTEL_SIGNATURE "Intel Corp" #define DEBUG 0 typedef unsigned char * address; typedef unsigned char byte; typedef unsigned short word; typedef unsigned char boolean; typedef unsigned int cardinal; typedef enum { CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, CT_915G, CT_915GM, CT_945G, CT_945GM, CT_945GME, CT_946GZ, CT_G965, CT_Q965, CT_965GM, CT_G33, CT_Q33, CT_Q35, CT_500GMA, CT_GM45, CT_GMA3150, CT_HD3000 } chipset_type; const char *const chipset_type_names[] = { "UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME", "946GZ", "G965", "Q965", "965GM", "G33", "Q33", "Q35", "500GMA", "GM45", "GMA3150", "HD3000" }; typedef enum { BT_UNKWN, BT_1, BT_2, BT_3 } bios_type; const char *const bios_type_names[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"}; int freqs[] = { 60, 75, 85 }; typedef struct { byte mode; byte bits_per_pixel; word resolution; byte unknown; } __attribute__((packed)) vbios_mode; typedef struct { byte unknow1[2]; byte x1; byte x_total; byte x2; byte y1; byte y_total; byte y2; } __attribute__((packed)) vbios_resolution_type1; typedef struct { unsigned long clock; word x1; word htotal; word x2; word hblank; word hsyncstart; word hsyncend; word y1; word vtotal; word y2; word vblank; word vsyncstart; word vsyncend; } __attribute__((packed)) vbios_modeline_type2; typedef struct { byte xchars; byte ychars; byte unknown[4]; vbios_modeline_type2 modelines[]; } __attribute__((packed)) vbios_resolution_type2; typedef struct { unsigned long clock; word x1; word htotal; word x2; word hblank; word hsyncstart; word hsyncend; word y1; word vtotal; word y2; word vblank; word vsyncstart; word vsyncend; word timing_h; word timing_v; byte unknown[6]; } __attribute__((packed)) vbios_modeline_type3; typedef struct { unsigned char unknown[6]; vbios_modeline_type3 modelines[]; } __attribute__((packed)) vbios_resolution_type3; typedef struct { cardinal chipset_id; chipset_type chipset; bios_type bios; int bios_fd; address bios_ptr; vbios_mode * mode_table; cardinal mode_table_size; byte b1, b2; boolean unlocked; } vbios_map; static cardinal get_chipset_id(void) { outl(0x80000000, 0xcf8); return inl(0xcfc); } static chipset_type get_chipset(cardinal id) { chipset_type type; switch (id) { case 0x35758086: type = CT_830; break; case 0x25608086: type = CT_845G; break; case 0x35808086: type = CT_855GM; break; case 0x25708086: type = CT_865G; break; case 0x25808086: type = CT_915G; break; case 0x25908086: type = CT_915GM; break; case 0x27708086: type = CT_945G; break; case 0x27a08086: type = CT_945GM; break; case 0x27ac8086: type = CT_945GME; break; case 0x29708086: type = CT_946GZ; break; case 0x29a08086: type = CT_G965; break; case 0x29908086: type = CT_Q965; break; case 0x2a008086: type = CT_965GM; break; case 0x29c08086: type = CT_G33; break; case 0x29b08086: type = CT_Q35; break; case 0x29d08086: type = CT_Q33; break; case 0x81008086: type = CT_500GMA; break; case 0xa0008086: type = CT_GMA3150; break; case 0xa0108086: type = CT_GMA3150; break; case 0x01048086: type = CT_HD3000; break; case 0x2a408086: type = CT_GM45; break; case 0x2a018086: type = CT_965GM; break; case 0x2a028086: type = CT_965GM; break; default: type = CT_UNKWN; break; } return type; } static vbios_resolution_type1 * map_type1_resolution(vbios_map * map, word res) { vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res)); return ptr; } static vbios_resolution_type2 * map_type2_resolution(vbios_map * map, word res) { vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res)); return ptr; } static vbios_resolution_type3 * map_type3_resolution(vbios_map * map, word res) { vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res)); return ptr; } static boolean detect_bios_type(vbios_map * map, int entry_size) { unsigned i; short int r1, r2; r1 = r2 = 32000; for (i=0; i < map->mode_table_size; i++) { if (map->mode_table[i].resolution <= r1) { r1 = map->mode_table[i].resolution; } else { if (map->mode_table[i].resolution <= r2) { r2 = map->mode_table[i].resolution; } } /*printf("r1 = %d r2 = %d\n", r1, r2);*/ } return (r2-r1-6) % entry_size == 0; } static void close_vbios(vbios_map * map); static vbios_map * open_vbios(chipset_type forced_chipset) { vbios_map * map = NEW(vbios_map); memset (map, 0, sizeof(vbios_map)); /* * Determine chipset */ if (forced_chipset == CT_UNKWN) { map->chipset_id = get_chipset_id(); map->chipset = get_chipset(map->chipset_id); } else if (forced_chipset != CT_UNKWN) { map->chipset = forced_chipset; } else { map->chipset = CT_915GM; } /* * Map the video bios to memory */ map->bios_ptr = (unsigned char *) VBIOS_START; #if 0 /* * check if we have ATI Radeon */ if (memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE1, strlen(ATI_SIGNATURE1)) || memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE2, strlen(ATI_SIGNATURE2)) ) { fprintf(stderr, "ATI chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\n"); close(map->bios_fd); exit(2); } /* * check if we have NVIDIA */ if (memmem(map->bios_ptr, VBIOS_SIZE, NVIDIA_SIGNATURE, strlen(NVIDIA_SIGNATURE))) { fprintf(stderr, "NVIDIA chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\n"); close(map->bios_fd); exit(2); } /* * check if we have Intel */ if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) { fprintf(stderr, "Intel chipset detected. However, 915resolution was unable to determine the chipset type.\n"); fprintf(stderr, "Chipset Id: %x\n", map->chipset_id); fprintf(stderr, "Please report this problem to stomljen@yahoo.com\n"); close_vbios(map); exit(2); } #endif /* * check for others */ if (map->chipset == CT_UNKWN) { fprintf(stderr, "Unknown chipset type and unrecognized bios.\n"); fprintf(stderr, "915resolution only works with Intel 800/900 series graphic chipsets.\n"); fprintf(stderr, "Chipset Id: %x\n", map->chipset_id); close_vbios(map); return 0; } /* * Figure out where the mode table is */ { address p = map->bios_ptr + 16; address limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode)); while (p < limit && map->mode_table == 0) { vbios_mode * mode_ptr = (vbios_mode *) p; if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) && ((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) { map->mode_table = mode_ptr; } p++; } if (map->mode_table == 0) { fprintf(stderr, "Unable to locate the mode table.\n"); fprintf(stderr, "Please run the program 'dump_bios' as root and\n"); fprintf(stderr, "email the file 'vbios.dmp' to stomljen@yahoo.com.\n"); fprintf(stderr, "Chipset: %s\n", chipset_type_names[map->chipset]); close_vbios(map); return 0; } } /* * Determine size of mode table */ { vbios_mode * mode_ptr = map->mode_table; while (mode_ptr->mode != 0xff) { map->mode_table_size++; mode_ptr++; } } /* * Figure out what type of bios we have * order of detection is important */ if (detect_bios_type(map, sizeof(vbios_modeline_type3))) { map->bios = BT_3; } else if (detect_bios_type(map, sizeof(vbios_modeline_type2))) { map->bios = BT_2; } else if (detect_bios_type(map, sizeof(vbios_resolution_type1))) { map->bios = BT_1; } else { fprintf(stderr, "Unable to determine bios type.\n"); fprintf(stderr, "Please run the program 'dump_bios' as root and\n"); fprintf(stderr, "email the file 'vbios.dmp' to stomljen@yahoo.com.\n"); fprintf(stderr, "Chipset: %s\n", chipset_type_names[map->chipset]); fprintf(stderr, "Mode Table Offset: $C0000 + $%x\n", ((cardinal)map->mode_table) - ((cardinal)map->bios_ptr)); fprintf(stderr, "Mode Table Entries: %u\n", map->mode_table_size); return 0; } return map; } static void close_vbios(vbios_map * map) { assert(!map->unlocked); FREE(map); } static void unlock_vbios(vbios_map * map) { assert(!map->unlocked); map->unlocked = TRUE; switch (map->chipset) { case CT_UNKWN: break; case CT_830: case CT_855GM: outl(0x8000005a, 0xcf8); map->b1 = inb(0xcfe); outl(0x8000005a, 0xcf8); outb(0x33, 0xcfe); break; case CT_845G: case CT_865G: case CT_915G: case CT_915GM: case CT_945G: case CT_945GM: case CT_945GME: case CT_946GZ: case CT_G965: case CT_Q965: case CT_965GM: case CT_G33: case CT_Q35: case CT_Q33: case CT_500GMA: case CT_GM45: case CT_GMA3150: case CT_HD3000: outl(0x80000090, 0xcf8); map->b1 = inb(0xcfd); map->b2 = inb(0xcfe); outl(0x80000090, 0xcf8); outb(0x33, 0xcfd); outb(0x33, 0xcfe); break; } #if DEBUG { cardinal t = inl(0xcfc); printf("unlock PAM: (0x%08x)\n", t); } #endif } static void relock_vbios(vbios_map * map) { assert(map->unlocked); map->unlocked = FALSE; switch (map->chipset) { case CT_UNKWN: break; case CT_830: case CT_855GM: outl(0x8000005a, 0xcf8); outb(map->b1, 0xcfe); break; case CT_845G: case CT_865G: case CT_915G: case CT_915GM: case CT_945G: case CT_945GM: case CT_945GME: case CT_946GZ: case CT_G965: case CT_Q965: case CT_965GM: case CT_G33: case CT_Q35: case CT_Q33: case CT_500GMA: case CT_GM45: case CT_GMA3150: case CT_HD3000: outl(0x80000090, 0xcf8); outb(map->b1, 0xcfd); outb(map->b2, 0xcfe); break; } #if DEBUG { cardinal t = inl(0xcfc); printf("relock PAM: (0x%08x)\n", t); } #endif } static void list_modes(vbios_map *map, cardinal raw) { cardinal i, x, y; for (i=0; i < map->mode_table_size; i++) { switch(map->bios) { case BT_1: { vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution); x = ((((cardinal) res->x2) & 0xf0) << 4) | res->x1; y = ((((cardinal) res->y2) & 0xf0) << 4) | res->y1; if (x != 0 && y != 0) { printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel); } if (raw) { printf("Mode %02x (raw) :\n\t%02x %02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2); } } break; case BT_2: { vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution); x = res->modelines[0].x1+1; y = res->modelines[0].y1+1; if (x != 0 && y != 0) { printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel); } } break; case BT_3: { vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution); x = res->modelines[0].x1+1; y = res->modelines[0].y1+1; if (x != 0 && y != 0) { printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel); } } break; case BT_UNKWN: break; } } } static void gtf_timings(int x, int y, int freq, unsigned long *clock, word *hsyncstart, word *hsyncend, word *hblank, word *vsyncstart, word *vsyncend, word *vblank) { int hbl, vbl, vfreq; vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5; vfreq = vbl * freq; hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) / (70.0 + 300000.0 / vfreq) / 16.0 + 0.5); *vsyncstart = y; *vsyncend = y + 3; *vblank = vbl - 1; *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1; *hsyncend = x + hbl / 2 - 1; *hblank = x + hbl - 1; *clock = (x + hbl) * vfreq / 1000; } static void set_mode(vbios_map * map, cardinal mode, cardinal x, cardinal y, cardinal bp, cardinal htotal, cardinal vtotal) { int xprev, yprev; cardinal i, j; for (i=0; i < map->mode_table_size; i++) { if (map->mode_table[i].mode == mode) { switch(map->bios) { case BT_1: { vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution); if (bp) { map->mode_table[i].bits_per_pixel = bp; } res->x2 = (htotal?(((htotal-x) >> 8) & 0x0f) : (res->x2 & 0x0f)) | ((x >> 4) & 0xf0); res->x1 = (x & 0xff); res->y2 = (vtotal?(((vtotal-y) >> 8) & 0x0f) : (res->y2 & 0x0f)) | ((y >> 4) & 0xf0); res->y1 = (y & 0xff); if (htotal) res->x_total = ((htotal-x) & 0xff); if (vtotal) res->y_total = ((vtotal-y) & 0xff); } break; case BT_2: { vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution); res->xchars = x / 8; res->ychars = y / 16 - 1; xprev = res->modelines[0].x1; yprev = res->modelines[0].y1; for(j=0; j < 3; j++) { vbios_modeline_type2 * modeline = &res->modelines[j]; if (modeline->x1 == xprev && modeline->y1 == yprev) { modeline->x1 = modeline->x2 = x-1; modeline->y1 = modeline->y2 = y-1; gtf_timings(x, y, freqs[j], &modeline->clock, &modeline->hsyncstart, &modeline->hsyncend, &modeline->hblank, &modeline->vsyncstart, &modeline->vsyncend, &modeline->vblank); if (htotal) modeline->htotal = htotal; else modeline->htotal = modeline->hblank; if (vtotal) modeline->vtotal = vtotal; else modeline->vtotal = modeline->vblank; } } } break; case BT_3: { vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution); xprev = res->modelines[0].x1; yprev = res->modelines[0].y1; for (j=0; j < 3; j++) { vbios_modeline_type3 * modeline = &res->modelines[j]; if (modeline->x1 == xprev && modeline->y1 == yprev) { modeline->x1 = modeline->x2 = x-1; modeline->y1 = modeline->y2 = y-1; gtf_timings(x, y, freqs[j], &modeline->clock, &modeline->hsyncstart, &modeline->hsyncend, &modeline->hblank, &modeline->vsyncstart, &modeline->vsyncend, &modeline->vblank); if (htotal) modeline->htotal = htotal; else modeline->htotal = modeline->hblank; if (vtotal) modeline->vtotal = vtotal; else modeline->vtotal = modeline->vblank; modeline->timing_h = y-1; modeline->timing_v = x-1; } } } break; case BT_UNKWN: break; } } } } static void display_map_info(vbios_map * map) { printf("Chipset: %s\n", chipset_type_names[map->chipset]); printf("BIOS: %s\n", bios_type_names[map->bios]); printf("Mode Table Offset: $C0000 + $%x\n", ((cardinal)map->mode_table) - ((cardinal)map->bios_ptr)); printf("Mode Table Entries: %u\n", map->mode_table_size); } static int parse_args(cardinal argc, char *argv[], chipset_type *forced_chipset, cardinal *list, cardinal *mode, cardinal *x, cardinal *y, cardinal *bp, cardinal *raw, cardinal *htotal, cardinal *vtotal, cardinal *quiet) { cardinal index = 0; *list = *mode = *x = *y = *raw = *htotal = *vtotal = 0; *bp = 0; *quiet = 0; *forced_chipset = CT_UNKWN; if ((argc > index) && !strcmp(argv[index], "-q")) { *quiet = 1; index++; if(argc<=index) { return 0; } } if ((argc > index) && !strcmp(argv[index], "-c")) { index++; if(argc<=index) { return 0; } if (!strcmp(argv[index], "845")) { *forced_chipset = CT_845G; } else if (!strcmp(argv[index], "855")) { *forced_chipset = CT_855GM; } else if (!strcmp(argv[index], "865")) { *forced_chipset = CT_865G; } else if (!strcmp(argv[index], "915G")) { *forced_chipset = CT_915G; } else if (!strcmp(argv[index], "915GM")) { *forced_chipset = CT_915GM; } else if (!strcmp(argv[index], "945G")) { *forced_chipset = CT_945G; } else if (!strcmp(argv[index], "945GM")) { *forced_chipset = CT_945GM; } else if (!strcmp(argv[index], "945GME")) { *forced_chipset = CT_945GME; } else if (!strcmp(argv[index], "946GZ")) { *forced_chipset = CT_946GZ; } else if (!strcmp(argv[index], "G965")) { *forced_chipset = CT_G965; } else if (!strcmp(argv[index], "Q965")) { *forced_chipset = CT_Q965; } else if (!strcmp(argv[index], "965GM")) { *forced_chipset = CT_965GM; } else if (!strcmp(argv[index], "G33")) { *forced_chipset = CT_G33; } else if (!strcmp(argv[index], "Q35")) { *forced_chipset = CT_Q35; } else if (!strcmp(argv[index], "Q33")) { *forced_chipset = CT_Q33; } else if (!strcmp(argv[index], "500GMA")) { *forced_chipset = CT_500GMA; } else if (!strcmp(argv[index], "GM45")) { *forced_chipset = CT_GM45; } else if (!strcmp(argv[index], "GMA3150")) { *forced_chipset = CT_GMA3150; } else if (!strcmp(argv[index], "HD3000")) { *forced_chipset = CT_HD3000; } else { *forced_chipset = CT_UNKWN; } index++; if (argc<=index) { return 0; } } if ((argc > index) && !strcmp(argv[index], "-l")) { *list = 1; index++; if(argc<=index) { return 0; } } if ((argc > index) && !strcmp(argv[index], "-r")) { *raw = 1; index++; if(argc<=index) { return 0; } } if (argc-index < 3 || argc-index > 6) { return -1; } *mode = (cardinal) strtol(argv[index], NULL, 16); *x = (cardinal)atoi(argv[index+1]); *y = (cardinal)atoi(argv[index+2]); if (argc-index > 3) { *bp = (cardinal)atoi(argv[index+3]); } else { *bp = 0; } if (argc-index > 4) { *htotal = (cardinal)atoi(argv[index+4]); } else { *htotal = 0; } if (argc-index > 5) { *vtotal = (cardinal)atoi(argv[index+5]); } else { *vtotal = 0; } return 0; } static void usage(void) { printf("Usage: 915resolution [-q] [-c chipset] [-l] [mode X Y] [bits/pixel] [htotal] [vtotal]\n"); printf(" Set the resolution to XxY for a video mode\n"); printf(" Bits per pixel are optional. htotal/vtotal settings are additionally optional.\n"); printf(" Options:\n"); printf(" -q don't show any normal messages\n"); printf(" -c force chipset type (THIS IS USED FOR DEBUG PURPOSES)\n"); printf(" -l display the modes found in the video BIOS\n"); printf(" -r display the modes found in the video BIOS in raw mode (THIS IS USED FOR DEBUG PURPOSES)\n"); } static int main_915 (int argc, char *argv[]) { vbios_map * map; cardinal list, mode, x, y, bp, raw, htotal, vtotal; cardinal quiet; chipset_type forced_chipset; if (parse_args(argc, argv, &forced_chipset, &list, &mode, &x, &y, &bp, &raw, &htotal, &vtotal, &quiet) == -1) { printf("Intel 800/900 Series VBIOS Hack : version %s\n\n", RES915_VERSION); usage(); return 2; } if (!quiet) printf("Intel 800/900 Series VBIOS Hack : version %s\n\n", RES915_VERSION); map = open_vbios(forced_chipset); if (!quiet) { display_map_info(map); printf("\n"); } if (list) { list_modes(map, raw); } if (mode!=0 && x!=0 && y!=0) { unlock_vbios(map); set_mode(map, mode, x, y, bp, htotal, vtotal); relock_vbios(map); printf("Patch mode %02x to resolution %dx%d complete\n", mode, x, y); if (list) { list_modes(map, raw); } } close_vbios(map); return 0; } static grub_err_t grub_cmd_915resolution (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { return main_915 (argc, argv); } static grub_command_t cmd; GRUB_MOD_INIT(915resolution) { cmd = grub_register_command ("915resolution", grub_cmd_915resolution, "915resolution", "Intel VBE editor"); } GRUB_MOD_FINI(915resolution) { grub_unregister_command (cmd); } debian/grub-extras/915resolution/README0000664000000000000000000000043612524662415014767 0ustar grub-extras is meant to be used as an overlay on grub2 source tree. Build instructions: - Copy grub-extras in a subdirectory of your grub2 checkout. For example, "grub-extras". - Export GRUB_CONTRIB environment variable to point to this directory. - Build GRUB as usual. debian/grub-extras/915resolution/COPYING0000664000000000000000000010451312524662415015143 0ustar GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . debian/grub-extras/915resolution/Makefile.core.def0000664000000000000000000000022212524662415017224 0ustar AutoGen definitions Makefile.tpl; module = { name = '915resolution'; i386_pc = contrib/915resolution/915resolution.c; enable = i386_pc; }; debian/grub-extras/disabled/0000775000000000000000000000000012524676037013216 5ustar debian/grub-extras/disabled/zfs/0000775000000000000000000000000012524676037014020 5ustar debian/grub-extras/disabled/zfs/Makefile.common0000664000000000000000000000006312524662415016741 0ustar ZFS_CPPFLAGS = -I$(top_srcdir)/contrib/zfs/include debian/grub-extras/disabled/zfs/zfs.c0000664000000000000000000020021112524662415014755 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * Copyright 2010 Sun Microsystems, Inc. * Copyright (C) 2009 Vladimir Serbinenko * Copyright (C) 2010 Robert Millan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * The zfs plug-in routines for GRUB are: * * zfs_mount() - locates a valid uberblock of the root pool and reads * in its MOS at the memory address MOS. * * zfs_open() - locates a plain file object by following the MOS * and places its dnode at the memory address DNODE. * * zfs_read() - read in the data blocks pointed by the DNODE. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ZPOOL_PROP_BOOTFS "bootfs" #define MIN(a,b) (((a) < (b)) ? (a) : (b)) /* * For nvlist manipulation. (from nvpair.h) */ #define NV_ENCODE_NATIVE 0 #define NV_ENCODE_XDR 1 #define NV_BIG_ENDIAN 0 #define NV_LITTLE_ENDIAN 1 #define DATA_TYPE_UINT64 8 #define DATA_TYPE_STRING 9 #define DATA_TYPE_NVLIST 19 #define DATA_TYPE_NVLIST_ARRAY 20 #ifndef GRUB_UTIL static grub_dl_t my_mod; #endif #define P2PHASE(x, align) ((x) & ((align) - 1)) #define DVA_OFFSET_TO_PHYS_SECTOR(offset) \ ((offset + VDEV_LABEL_START_SIZE) >> SPA_MINBLOCKSHIFT) /* * FAT ZAP data structures */ #define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */ #define ZAP_HASH_IDX(hash, n) (((n) == 0) ? 0 : ((hash) >> (64 - (n)))) #define CHAIN_END 0xffff /* end of the chunk chain */ /* * The amount of space within the chunk available for the array is: * chunk size - space for type (1) - space for next pointer (2) */ #define ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3) #define ZAP_LEAF_HASH_SHIFT(bs) (bs - 5) #define ZAP_LEAF_HASH_NUMENTRIES(bs) (1 << ZAP_LEAF_HASH_SHIFT(bs)) #define LEAF_HASH(bs, h) \ ((ZAP_LEAF_HASH_NUMENTRIES(bs)-1) & \ ((h) >> (64 - ZAP_LEAF_HASH_SHIFT(bs)-l->l_hdr.lh_prefix_len))) /* * The amount of space available for chunks is: * block size shift - hash entry size (2) * number of hash * entries - header space (2*chunksize) */ #define ZAP_LEAF_NUMCHUNKS(bs) \ (((1<l_hash + ZAP_LEAF_HASH_NUMENTRIES(bs)))[idx] #define ZAP_LEAF_ENTRY(l, bs, idx) (&ZAP_LEAF_CHUNK(l, bs, idx).l_entry) /* * Decompression Entry - lzjb */ #ifndef NBBY #define NBBY 8 #endif extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t); typedef grub_err_t zfs_decomp_func_t (void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len); typedef struct decomp_entry { char *name; zfs_decomp_func_t *decomp_func; } decomp_entry_t; typedef struct dnode_end { dnode_phys_t dn; grub_zfs_endian_t endian; } dnode_end_t; struct grub_zfs_data { /* cache for a file block of the currently zfs_open()-ed file */ char *file_buf; grub_uint64_t file_start; grub_uint64_t file_end; /* cache for a dnode block */ dnode_phys_t *dnode_buf; dnode_phys_t *dnode_mdn; grub_uint64_t dnode_start; grub_uint64_t dnode_end; grub_zfs_endian_t dnode_endian; uberblock_t current_uberblock; grub_disk_t disk; dnode_end_t mos; dnode_end_t mdn; dnode_end_t dnode; grub_disk_addr_t vdev_phys_sector; }; decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { {"inherit", NULL}, /* ZIO_COMPRESS_INHERIT */ {"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */ {"off", NULL}, /* ZIO_COMPRESS_OFF */ {"lzjb", lzjb_decompress}, /* ZIO_COMPRESS_LZJB */ {"empty", NULL}, /* ZIO_COMPRESS_EMPTY */ {"gzip", NULL}, /* ZIO_COMPRESS_GZIP */ }; static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, struct grub_zfs_data *data); /* * Our own version of log2(). Same thing as highbit()-1. */ static int zfs_log2 (grub_uint64_t num) { int i = 0; while (num > 1) { i++; num = num >> 1; } return (i); } /* Checksum Functions */ static void zio_checksum_off (const void *buf __attribute__ ((unused)), grub_uint64_t size __attribute__ ((unused)), grub_zfs_endian_t endian __attribute__ ((unused)), zio_cksum_t * zcp) { ZIO_SET_CHECKSUM (zcp, 0, 0, 0, 0); } /* Checksum Table and Values */ zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { {NULL, 0, 0, "inherit"}, {NULL, 0, 0, "on"}, {zio_checksum_off, 0, 0, "off"}, {zio_checksum_SHA256, 1, 1, "label"}, {zio_checksum_SHA256, 1, 1, "gang_header"}, {NULL, 0, 0, "zilog"}, {fletcher_2, 0, 0, "fletcher2"}, {fletcher_4, 1, 0, "fletcher4"}, {zio_checksum_SHA256, 1, 0, "SHA256"}, {NULL, 0, 0, "zilog2"}, }; /* * zio_checksum_verify: Provides support for checksum verification. * * Fletcher2, Fletcher4, and SHA256 are supported. * */ static grub_err_t zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, grub_zfs_endian_t endian, char *buf, int size) { zio_eck_t *zec = (zio_eck_t *) (buf + size) - 1; zio_checksum_info_t *ci = &zio_checksum_table[checksum]; zio_cksum_t actual_cksum, expected_cksum; if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func == NULL) { grub_dprintf ("zfs", "unknown checksum function %d\n", checksum); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "unknown checksum function %d", checksum); } if (ci->ci_eck) { expected_cksum = zec->zec_cksum; zec->zec_cksum = zc; ci->ci_func (buf, size, endian, &actual_cksum); zec->zec_cksum = expected_cksum; zc = expected_cksum; } else ci->ci_func (buf, size, endian, &actual_cksum); if ((actual_cksum.zc_word[0] != zc.zc_word[0]) || (actual_cksum.zc_word[1] != zc.zc_word[1]) || (actual_cksum.zc_word[2] != zc.zc_word[2]) || (actual_cksum.zc_word[3] != zc.zc_word[3])) { grub_dprintf ("zfs", "checksum %d verification failed\n", checksum); grub_dprintf ("zfs", "actual checksum %16llx %16llx %16llx %16llx\n", (unsigned long long) actual_cksum.zc_word[0], (unsigned long long) actual_cksum.zc_word[1], (unsigned long long) actual_cksum.zc_word[2], (unsigned long long) actual_cksum.zc_word[3]); grub_dprintf ("zfs", "expected checksum %16llx %16llx %16llx %16llx\n", (unsigned long long) zc.zc_word[0], (unsigned long long) zc.zc_word[1], (unsigned long long) zc.zc_word[2], (unsigned long long) zc.zc_word[3]); return grub_error (GRUB_ERR_BAD_FS, "checksum verification failed"); } return GRUB_ERR_NONE; } /* * vdev_uberblock_compare takes two uberblock structures and returns an integer * indicating the more recent of the two. * Return Value = 1 if ub2 is more recent * Return Value = -1 if ub1 is more recent * The most recent uberblock is determined using its transaction number and * timestamp. The uberblock with the highest transaction number is * considered "newer". If the transaction numbers of the two blocks match, the * timestamps are compared to determine the "newer" of the two. */ static int vdev_uberblock_compare (uberblock_t * ub1, uberblock_t * ub2) { grub_zfs_endian_t ub1_endian, ub2_endian; if (grub_zfs_to_cpu64 (ub1->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC) ub1_endian = LITTLE_ENDIAN; else ub1_endian = BIG_ENDIAN; if (grub_zfs_to_cpu64 (ub2->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC) ub2_endian = LITTLE_ENDIAN; else ub2_endian = BIG_ENDIAN; if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian) < grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian)) return (-1); if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian) > grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian)) return (1); if (grub_zfs_to_cpu64 (ub1->ub_timestamp, ub1_endian) < grub_zfs_to_cpu64 (ub2->ub_timestamp, ub2_endian)) return (-1); if (grub_zfs_to_cpu64 (ub1->ub_timestamp, ub1_endian) > grub_zfs_to_cpu64 (ub2->ub_timestamp, ub2_endian)) return (1); return (0); } /* * Three pieces of information are needed to verify an uberblock: the magic * number, the version number, and the checksum. * * Currently Implemented: version number, magic number * Need to Implement: checksum * */ static grub_err_t uberblock_verify (uberblock_phys_t * ub, int offset) { uberblock_t *uber = &ub->ubp_uberblock; grub_err_t err; grub_zfs_endian_t endian = UNKNOWN_ENDIAN; zio_cksum_t zc; if (grub_zfs_to_cpu64 (uber->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC && grub_zfs_to_cpu64 (uber->ub_version, LITTLE_ENDIAN) > 0 && grub_zfs_to_cpu64 (uber->ub_version, LITTLE_ENDIAN) <= SPA_VERSION) endian = LITTLE_ENDIAN; if (grub_zfs_to_cpu64 (uber->ub_magic, BIG_ENDIAN) == UBERBLOCK_MAGIC && grub_zfs_to_cpu64 (uber->ub_version, BIG_ENDIAN) > 0 && grub_zfs_to_cpu64 (uber->ub_version, BIG_ENDIAN) <= SPA_VERSION) endian = BIG_ENDIAN; if (endian == UNKNOWN_ENDIAN) return grub_error (GRUB_ERR_BAD_FS, "invalid uberblock magic"); grub_memset (&zc, 0, sizeof (zc)); zc.zc_word[0] = grub_cpu_to_zfs64 (offset, endian); err = zio_checksum_verify (zc, ZIO_CHECKSUM_LABEL, endian, (char *) ub, UBERBLOCK_SIZE); return err; } /* * Find the best uberblock. * Return: * Success - Pointer to the best uberblock. * Failure - NULL */ static uberblock_phys_t * find_bestub (uberblock_phys_t * ub_array, grub_disk_addr_t sector) { uberblock_phys_t *ubbest = NULL; int i; grub_disk_addr_t offset; grub_err_t err = GRUB_ERR_NONE; for (i = 0; i < (VDEV_UBERBLOCK_RING >> VDEV_UBERBLOCK_SHIFT); i++) { offset = (sector << SPA_MINBLOCKSHIFT) + VDEV_PHYS_SIZE + (i << VDEV_UBERBLOCK_SHIFT); err = uberblock_verify (&ub_array[i], offset); if (err) { grub_errno = GRUB_ERR_NONE; continue; } if (ubbest == NULL || vdev_uberblock_compare (&(ub_array[i].ubp_uberblock), &(ubbest->ubp_uberblock)) > 0) ubbest = &ub_array[i]; } if (!ubbest) grub_errno = err; return (ubbest); } static inline grub_size_t get_psize (blkptr_t * bp, grub_zfs_endian_t endian) { return ((((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) >> 16) & 0xffff) + 1) << SPA_MINBLOCKSHIFT); } static grub_uint64_t dva_get_offset (dva_t * dva, grub_zfs_endian_t endian) { grub_dprintf ("zfs", "dva=%llx, %llx\n", (unsigned long long) dva->dva_word[0], (unsigned long long) dva->dva_word[1]); return grub_zfs_to_cpu64 ((dva)->dva_word[1], endian) << SPA_MINBLOCKSHIFT; } /* * Read a block of data based on the gang block address dva, * and put its data in buf. * */ static grub_err_t zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf, struct grub_zfs_data *data) { zio_gbh_phys_t *zio_gb; grub_uint64_t offset, sector; unsigned i; grub_err_t err; zio_cksum_t zc; grub_memset (&zc, 0, sizeof (zc)); zio_gb = grub_malloc (SPA_GANGBLOCKSIZE); if (!zio_gb) return grub_errno; grub_dprintf ("zfs", endian == LITTLE_ENDIAN ? "little-endian gang\n" :"big-endian gang\n"); offset = dva_get_offset (dva, endian); sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); grub_dprintf ("zfs", "offset=%llx\n", (unsigned long long) offset); /* read in the gang block header */ err = grub_disk_read (data->disk, sector, 0, SPA_GANGBLOCKSIZE, (char *) zio_gb); if (err) { grub_free (zio_gb); return err; } /* XXX */ /* self checksuming the gang block header */ ZIO_SET_CHECKSUM (&zc, DVA_GET_VDEV (dva), dva_get_offset (dva, endian), bp->blk_birth, 0); err = zio_checksum_verify (zc, ZIO_CHECKSUM_GANG_HEADER, endian, (char *) zio_gb, SPA_GANGBLOCKSIZE); if (err) { grub_free (zio_gb); return err; } endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; for (i = 0; i < SPA_GBH_NBLKPTRS; i++) { if (zio_gb->zg_blkptr[i].blk_birth == 0) continue; err = zio_read_data (&zio_gb->zg_blkptr[i], endian, buf, data); if (err) { grub_free (zio_gb); return err; } buf = (char *) buf + get_psize (&zio_gb->zg_blkptr[i], endian); } grub_free (zio_gb); return GRUB_ERR_NONE; } /* * Read in a block of raw data to buf. */ static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, struct grub_zfs_data *data) { int i, psize; grub_err_t err = GRUB_ERR_NONE; psize = get_psize (bp, endian); /* pick a good dva from the block pointer */ for (i = 0; i < SPA_DVAS_PER_BP; i++) { grub_uint64_t offset, sector; if (bp->blk_dva[i].dva_word[0] == 0 && bp->blk_dva[i].dva_word[1] == 0) continue; if ((grub_zfs_to_cpu64 (bp->blk_dva[i].dva_word[1], endian)>>63) & 1) err = zio_read_gang (bp, endian, &bp->blk_dva[i], buf, data); else { /* read in a data block */ offset = dva_get_offset (&bp->blk_dva[i], endian); sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); err = grub_disk_read (data->disk, sector, 0, psize, buf); } if (!err) return GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE; } if (!err) err = grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid DVA"); grub_errno = err; return err; } /* * Read in a block of data, verify its checksum, decompress if needed, * and put the uncompressed data in buf. */ static grub_err_t zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, grub_size_t *size, struct grub_zfs_data *data) { grub_size_t lsize, psize; unsigned int comp; char *compbuf = NULL; grub_err_t err; zio_cksum_t zc = bp->blk_cksum; grub_uint32_t checksum; *buf = NULL; checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff; comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7; lsize = (BP_IS_HOLE(bp) ? 0 : (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1) << SPA_MINBLOCKSHIFT)); psize = get_psize (bp, endian); if (size) *size = lsize; if (comp >= ZIO_COMPRESS_FUNCTIONS) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "compression algorithm %u not supported\n", (unsigned int) comp); if (comp != ZIO_COMPRESS_OFF && decomp_table[comp].decomp_func == NULL) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "compression algorithm %s not supported\n", decomp_table[comp].name); if (comp != ZIO_COMPRESS_OFF) { compbuf = grub_malloc (psize); if (! compbuf) return grub_errno; } else compbuf = *buf = grub_malloc (lsize); grub_dprintf ("zfs", "endian = %d\n", endian); err = zio_read_data (bp, endian, compbuf, data); if (err) { grub_free (compbuf); *buf = NULL; return err; } err = zio_checksum_verify (zc, checksum, endian, compbuf, psize); if (err) { grub_dprintf ("zfs", "incorrect checksum\n"); grub_free (compbuf); *buf = NULL; return err; } if (comp != ZIO_COMPRESS_OFF) { *buf = grub_malloc (lsize); if (!*buf) { grub_free (compbuf); return grub_errno; } err = decomp_table[comp].decomp_func (compbuf, *buf, psize, lsize); grub_free (compbuf); if (err) { grub_free (*buf); *buf = NULL; return err; } } return GRUB_ERR_NONE; } /* * Get the block from a block id. * push the block onto the stack. * */ static grub_err_t dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, grub_zfs_endian_t *endian_out, struct grub_zfs_data *data) { int idx, level; blkptr_t *bp_array = dn->dn.dn_blkptr; int epbs = dn->dn.dn_indblkshift - SPA_BLKPTRSHIFT; blkptr_t *bp, *tmpbuf = 0; grub_zfs_endian_t endian; grub_err_t err = GRUB_ERR_NONE; bp = grub_malloc (sizeof (blkptr_t)); if (!bp) return grub_errno; endian = dn->endian; for (level = dn->dn.dn_nlevels - 1; level >= 0; level--) { grub_dprintf ("zfs", "endian = %d\n", endian); idx = (blkid >> (epbs * level)) & ((1 << epbs) - 1); *bp = bp_array[idx]; if (bp_array != dn->dn.dn_blkptr) { grub_free (bp_array); bp_array = 0; } if (BP_IS_HOLE (bp)) { grub_size_t size = grub_zfs_to_cpu16 (dn->dn.dn_datablkszsec, dn->endian) << SPA_MINBLOCKSHIFT; *buf = grub_malloc (size); if (*buf) { err = grub_errno; break; } grub_memset (*buf, 0, size); endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; break; } if (level == 0) { grub_dprintf ("zfs", "endian = %d\n", endian); err = zio_read (bp, endian, buf, 0, data); endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; break; } grub_dprintf ("zfs", "endian = %d\n", endian); err = zio_read (bp, endian, (void **) &tmpbuf, 0, data); endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; if (err) break; bp_array = tmpbuf; } if (bp_array != dn->dn.dn_blkptr) grub_free (bp_array); if (endian_out) *endian_out = endian; grub_free (bp); return err; } /* * mzap_lookup: Looks up property described by "name" and returns the value * in "value". */ static grub_err_t mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize, char *name, grub_uint64_t * value) { int i, chunks; mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk; chunks = objsize / MZAP_ENT_LEN - 1; for (i = 0; i < chunks; i++) { if (grub_strcmp (mzap_ent[i].mze_name, name) == 0) { *value = grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian); return GRUB_ERR_NONE; } } return grub_error (GRUB_ERR_FILE_NOT_FOUND, "couldn't find %s", name); } static int mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize, int NESTED_FUNC_ATTR (*hook) (const char *name, grub_uint64_t val)) { int i, chunks; mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk; chunks = objsize / MZAP_ENT_LEN - 1; for (i = 0; i < chunks; i++) { grub_dprintf ("zfs", "zap: name = %s, value = %llx, cd = %x\n", mzap_ent[i].mze_name, (long long)mzap_ent[i].mze_value, (int)mzap_ent[i].mze_cd); if (hook (mzap_ent[i].mze_name, grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian))) return 1; } return 0; } static grub_uint64_t zap_hash (grub_uint64_t salt, const char *name) { static grub_uint64_t table[256]; const grub_uint8_t *cp; grub_uint8_t c; grub_uint64_t crc = salt; if (table[128] == 0) { grub_uint64_t *ct; int i, j; for (i = 0; i < 256; i++) { for (ct = table + i, *ct = i, j = 8; j > 0; j--) *ct = (*ct >> 1) ^ (-(*ct & 1) & ZFS_CRC64_POLY); } } for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++) crc = (crc >> 8) ^ table[(crc ^ c) & 0xFF]; /* * Only use 28 bits, since we need 4 bits in the cookie for the * collision differentiator. We MUST use the high bits, since * those are the onces that we first pay attention to when * chosing the bucket. */ crc &= ~((1ULL << (64 - ZAP_HASHBITS)) - 1); return (crc); } /* * Only to be used on 8-bit arrays. * array_len is actual len in bytes (not encoded le_value_length). * buf is null-terminated. */ /* XXX */ static int zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, int chunk, int array_len, const char *buf) { int bseen = 0; while (bseen < array_len) { struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk).l_array; int toread = MIN (array_len - bseen, ZAP_LEAF_ARRAY_BYTES); if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) return (0); if (grub_memcmp (la->la_array, buf + bseen, toread) != 0) break; chunk = grub_zfs_to_cpu16 (la->la_next, endian); bseen += toread; } return (bseen == array_len); } /* XXX */ static grub_err_t zap_leaf_array_get (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, int chunk, int array_len, char *buf) { int bseen = 0; while (bseen < array_len) { struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk).l_array; int toread = MIN (array_len - bseen, ZAP_LEAF_ARRAY_BYTES); if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) /* Don't use grub_error because this error is to be ignored. */ return GRUB_ERR_BAD_FS; grub_memcpy (buf + bseen,la->la_array, toread); chunk = grub_zfs_to_cpu16 (la->la_next, endian); bseen += toread; } return GRUB_ERR_NONE; } /* * Given a zap_leaf_phys_t, walk thru the zap leaf chunks to get the * value for the property "name". * */ /* XXX */ static grub_err_t zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, grub_uint64_t h, const char *name, grub_uint64_t * value) { grub_uint16_t chunk; struct zap_leaf_entry *le; /* Verify if this is a valid leaf block */ if (grub_zfs_to_cpu64 (l->l_hdr.lh_block_type, endian) != ZBT_LEAF) return grub_error (GRUB_ERR_BAD_FS, "invalid leaf type"); if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC) return grub_error (GRUB_ERR_BAD_FS, "invalid leaf magic"); for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h)], endian); chunk != CHAIN_END; chunk = le->le_next) { if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) return grub_error (GRUB_ERR_BAD_FS, "invalid chunk number"); le = ZAP_LEAF_ENTRY (l, blksft, chunk); /* Verify the chunk entry */ if (le->le_type != ZAP_CHUNK_ENTRY) return grub_error (GRUB_ERR_BAD_FS, "invalid chunk entry"); if (grub_zfs_to_cpu64 (le->le_hash,endian) != h) continue; grub_dprintf ("zfs", "fzap: length %d\n", (int) le->le_name_length); if (zap_leaf_array_equal (l, endian, blksft, grub_zfs_to_cpu16 (le->le_name_chunk,endian), grub_zfs_to_cpu16 (le->le_name_length, endian), name)) { struct zap_leaf_array *la; grub_uint8_t *ip; if (le->le_int_size != 8 || le->le_value_length != 1) return grub_error (GRUB_ERR_BAD_FS, "invalid leaf chunk entry"); /* get the uint64_t property value */ la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk).l_array; ip = la->la_array; *value = grub_be_to_cpu64 (la->la_array64); return GRUB_ERR_NONE; } } return grub_error (GRUB_ERR_FILE_NOT_FOUND, "couldn't find %s", name); } /* Verify if this is a fat zap header block */ static grub_err_t zap_verify (zap_phys_t *zap) { if (zap->zap_magic != (grub_uint64_t) ZAP_MAGIC) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP magic"); if (zap->zap_flags != 0) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP flags"); if (zap->zap_salt == 0) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP salt"); return GRUB_ERR_NONE; } /* * Fat ZAP lookup * */ /* XXX */ static grub_err_t fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, char *name, grub_uint64_t * value, struct grub_zfs_data *data) { zap_leaf_phys_t *l; grub_uint64_t hash, idx, blkid; int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << DNODE_SHIFT); grub_err_t err; grub_zfs_endian_t leafendian; err = zap_verify (zap); if (err) return err; hash = zap_hash (zap->zap_salt, name); /* get block id from index */ if (zap->zap_ptrtbl.zt_numblks != 0) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "external pointer tables not supported"); idx = ZAP_HASH_IDX (hash, zap->zap_ptrtbl.zt_shift); blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; /* Get the leaf block */ if ((1U << blksft) < sizeof (zap_leaf_phys_t)) return grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small"); err = dmu_read (zap_dnode, blkid, (void **) &l, &leafendian, data); if (err) return err; err = zap_leaf_lookup (l, leafendian, blksft, hash, name, value); grub_free (l); return err; } /* XXX */ static int fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, int NESTED_FUNC_ATTR (*hook) (const char *name, grub_uint64_t val), struct grub_zfs_data *data) { zap_leaf_phys_t *l; grub_uint64_t idx, blkid; grub_uint16_t chunk; int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << DNODE_SHIFT); grub_err_t err; grub_zfs_endian_t endian; if (zap_verify (zap)) return 0; /* get block id from index */ if (zap->zap_ptrtbl.zt_numblks != 0) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "external pointer tables not supported"); return 0; } /* Get the leaf block */ if ((1U << blksft) < sizeof (zap_leaf_phys_t)) { grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small"); return 0; } for (idx = 0; idx < zap->zap_ptrtbl.zt_numblks; idx++) { blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; err = dmu_read (zap_dnode, blkid, (void **) &l, &endian, data); if (err) { grub_errno = GRUB_ERR_NONE; continue; } /* Verify if this is a valid leaf block */ if (grub_zfs_to_cpu64 (l->l_hdr.lh_block_type, endian) != ZBT_LEAF) { grub_free (l); continue; } if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC) { grub_free (l); continue; } for (chunk = 0; chunk < ZAP_LEAF_NUMCHUNKS (blksft); chunk++) { char *buf; struct zap_leaf_array *la; struct zap_leaf_entry *le; grub_uint64_t val; le = ZAP_LEAF_ENTRY (l, blksft, chunk); /* Verify the chunk entry */ if (le->le_type != ZAP_CHUNK_ENTRY) continue; buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian) + 1); if (zap_leaf_array_get (l, endian, blksft, le->le_name_chunk, le->le_name_length, buf)) { grub_free (buf); continue; } buf[le->le_name_length] = 0; if (le->le_int_size != 8 || grub_zfs_to_cpu16 (le->le_value_length, endian) != 1) continue; /* get the uint64_t property value */ la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk).l_array; val = grub_be_to_cpu64 (la->la_array64); if (hook (buf, val)) return 1; grub_free (buf); } } return 0; } /* * Read in the data of a zap object and find the value for a matching * property name. * */ static grub_err_t zap_lookup (dnode_end_t * zap_dnode, char *name, grub_uint64_t * val, struct grub_zfs_data *data) { grub_uint64_t block_type; int size; void *zapbuf; grub_err_t err; grub_zfs_endian_t endian; grub_dprintf ("zfs", "looking for '%s'\n", name); /* Read in the first block of the zap object data. */ size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << SPA_MINBLOCKSHIFT; err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); if (err) return err; block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian); grub_dprintf ("zfs", "zap read\n"); if (block_type == ZBT_MICRO) { grub_dprintf ("zfs", "micro zap\n"); err = (mzap_lookup (zapbuf, endian, size, name, val)); grub_dprintf ("zfs", "returned %d\n", err); grub_free (zapbuf); return err; } else if (block_type == ZBT_HEADER) { grub_dprintf ("zfs", "fat zap\n"); /* this is a fat zap */ err = (fzap_lookup (zap_dnode, zapbuf, name, val, data)); grub_dprintf ("zfs", "returned %d\n", err); grub_free (zapbuf); return err; } return grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); } static int zap_iterate (dnode_end_t * zap_dnode, int NESTED_FUNC_ATTR (*hook) (const char *name, grub_uint64_t val), struct grub_zfs_data *data) { grub_uint64_t block_type; int size; void *zapbuf; grub_err_t err; int ret; grub_zfs_endian_t endian; /* Read in the first block of the zap object data. */ size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << SPA_MINBLOCKSHIFT; err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); if (err) return 0; block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian); grub_dprintf ("zfs", "zap read\n"); if (block_type == ZBT_MICRO) { grub_dprintf ("zfs", "micro zap\n"); ret = mzap_iterate (zapbuf, endian, size, hook); grub_free (zapbuf); return ret; } else if (block_type == ZBT_HEADER) { grub_dprintf ("zfs", "fat zap\n"); /* this is a fat zap */ ret = fzap_iterate (zap_dnode, zapbuf, hook, data); grub_free (zapbuf); return ret; } grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); return 0; } /* * Get the dnode of an object number from the metadnode of an object set. * * Input * mdn - metadnode to get the object dnode * objnum - object number for the object dnode * buf - data buffer that holds the returning dnode */ static grub_err_t dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, dnode_end_t * buf, struct grub_zfs_data *data) { grub_uint64_t blkid, blksz; /* the block id this object dnode is in */ int epbs; /* shift of number of dnodes in a block */ int idx; /* index within a block */ dnode_phys_t *dnbuf; grub_err_t err; grub_zfs_endian_t endian; blksz = grub_zfs_to_cpu16 (mdn->dn.dn_datablkszsec, mdn->endian) << SPA_MINBLOCKSHIFT; epbs = zfs_log2 (blksz) - DNODE_SHIFT; blkid = objnum >> epbs; idx = objnum & ((1 << epbs) - 1); if (data->dnode_buf != NULL && grub_memcmp (data->dnode_mdn, mdn, sizeof (*mdn)) == 0 && objnum >= data->dnode_start && objnum < data->dnode_end) { grub_memmove (&(buf->dn), &(data->dnode_buf)[idx], DNODE_SIZE); buf->endian = data->dnode_endian; if (type && buf->dn.dn_type != type) return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); return GRUB_ERR_NONE; } grub_dprintf ("zfs", "endian = %d, blkid=%llx\n", mdn->endian, (unsigned long long) blkid); err = dmu_read (mdn, blkid, (void **) &dnbuf, &endian, data); if (err) return err; grub_dprintf ("zfs", "alive\n"); grub_free (data->dnode_buf); grub_free (data->dnode_mdn); data->dnode_mdn = grub_malloc (sizeof (*mdn)); if (! data->dnode_mdn) { grub_errno = GRUB_ERR_NONE; data->dnode_buf = 0; } else { grub_memcpy (data->dnode_mdn, mdn, sizeof (*mdn)); data->dnode_buf = dnbuf; data->dnode_start = blkid << epbs; data->dnode_end = (blkid + 1) << epbs; data->dnode_endian = endian; } grub_memmove (&(buf->dn), &dnbuf[idx], DNODE_SIZE); buf->endian = endian; if (type && buf->dn.dn_type != type) return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); return GRUB_ERR_NONE; } /* * Get the file dnode for a given file name where mdn is the meta dnode * for this ZFS object set. When found, place the file dnode in dn. * The 'path' argument will be mangled. * */ static grub_err_t dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, struct grub_zfs_data *data) { grub_uint64_t objnum, version; char *cname, ch; grub_err_t err = GRUB_ERR_NONE; char *path, *path_buf; struct dnode_chain { struct dnode_chain *next; dnode_end_t dn; }; struct dnode_chain *dnode_path = 0, *dn_new, *root; dn_new = grub_malloc (sizeof (*dn_new)); if (! dn_new) return grub_errno; dn_new->next = 0; dnode_path = root = dn_new; err = dnode_get (mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, &(dnode_path->dn), data); if (err) { grub_free (dn_new); return err; } err = zap_lookup (&(dnode_path->dn), ZPL_VERSION_STR, &version, data); if (err) { grub_free (dn_new); return err; } if (version > ZPL_VERSION) { grub_free (dn_new); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "too new ZPL version"); } err = zap_lookup (&(dnode_path->dn), ZFS_ROOT_OBJ, &objnum, data); if (err) { grub_free (dn_new); return err; } err = dnode_get (mdn, objnum, 0, &(dnode_path->dn), data); if (err) { grub_free (dn_new); return err; } path = path_buf = grub_strdup (path_in); if (!path_buf) { grub_free (dn_new); return grub_errno; } while (1) { /* skip leading slashes */ while (*path == '/') path++; if (!*path) break; /* get the next component name */ cname = path; while (*path && *path != '/') path++; /* Skip dot. */ if (cname + 1 == path && cname[0] == '.') continue; /* Handle double dot. */ if (cname + 2 == path && cname[0] == '.' && cname[1] == '.') { if (dn_new->next) { dn_new = dnode_path; dnode_path = dn_new->next; grub_free (dn_new); } else { err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "can't resolve .."); break; } continue; } ch = *path; *path = 0; /* ensure null termination */ if (dnode_path->dn.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS) { grub_free (path_buf); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); } err = zap_lookup (&(dnode_path->dn), cname, &objnum, data); if (err) break; dn_new = grub_malloc (sizeof (*dn_new)); if (! dn_new) { err = grub_errno; break; } dn_new->next = dnode_path; dnode_path = dn_new; objnum = ZFS_DIRENT_OBJ (objnum); err = dnode_get (mdn, objnum, 0, &(dnode_path->dn), data); if (err) break; *path = ch; #if 0 if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa && ch) { char *oldpath = path, *oldpathbuf = path_buf; path = path_buf = grub_malloc (sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t) + grub_strlen (oldpath) + 1); if (!path_buf) { grub_free (oldpathbuf); return grub_errno; } grub_memcpy (path, (char *) DN_BONUS(&dnode_path->dn.dn) + sizeof (znode_phys_t), sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)); path [sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)] = 0; grub_memcpy (path + grub_strlen (path), oldpath, grub_strlen (oldpath) + 1); grub_free (oldpathbuf); if (path[0] != '/') { dn_new = dnode_path; dnode_path = dn_new->next; grub_free (dn_new); } else while (dnode_path != root) { dn_new = dnode_path; dnode_path = dn_new->next; grub_free (dn_new); } } #endif } if (!err) grub_memcpy (dn, &(dnode_path->dn), sizeof (*dn)); while (dnode_path) { dn_new = dnode_path->next; grub_free (dnode_path); dnode_path = dn_new; } grub_free (path_buf); return err; } #if 0 /* * Get the default 'bootfs' property value from the rootpool. * */ static grub_err_t get_default_bootfsobj (dnode_phys_t * mosmdn, grub_uint64_t * obj, struct grub_zfs_data *data) { grub_uint64_t objnum = 0; dnode_phys_t *dn; if (!dn) return grub_errno; if ((grub_errno = dnode_get (mosmdn, DMU_POOL_DIRECTORY_OBJECT, DMU_OT_OBJECT_DIRECTORY, dn, data))) { grub_free (dn); return (grub_errno); } /* * find the object number for 'pool_props', and get the dnode * of the 'pool_props'. */ if (zap_lookup (dn, DMU_POOL_PROPS, &objnum, data)) { grub_free (dn); return (GRUB_ERR_BAD_FS); } if ((grub_errno = dnode_get (mosmdn, objnum, DMU_OT_POOL_PROPS, dn, data))) { grub_free (dn); return (grub_errno); } if (zap_lookup (dn, ZPOOL_PROP_BOOTFS, &objnum, data)) { grub_free (dn); return (GRUB_ERR_BAD_FS); } if (!objnum) { grub_free (dn); return (GRUB_ERR_BAD_FS); } *obj = objnum; return (0); } #endif /* * Given a MOS metadnode, get the metadnode of a given filesystem name (fsname), * e.g. pool/rootfs, or a given object number (obj), e.g. the object number * of pool/rootfs. * * If no fsname and no obj are given, return the DSL_DIR metadnode. * If fsname is given, return its metadnode and its matching object number. * If only obj is given, return the metadnode for this object number. * */ static grub_err_t get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname, dnode_end_t * mdn, struct grub_zfs_data *data) { grub_uint64_t objnum; grub_err_t err; grub_dprintf ("zfs", "endian = %d\n", mosmdn->endian); err = dnode_get (mosmdn, DMU_POOL_DIRECTORY_OBJECT, DMU_OT_OBJECT_DIRECTORY, mdn, data); if (err) return err; grub_dprintf ("zfs", "alive\n"); err = zap_lookup (mdn, DMU_POOL_ROOT_DATASET, &objnum, data); if (err) return err; grub_dprintf ("zfs", "alive\n"); err = dnode_get (mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data); if (err) return err; grub_dprintf ("zfs", "alive\n"); while (*fsname) { grub_uint64_t childobj; char *cname, ch; while (*fsname == '/') fsname++; if (! *fsname || *fsname == '@') break; cname = fsname; while (*fsname && !grub_isspace (*fsname) && *fsname != '/') fsname++; ch = *fsname; *fsname = 0; childobj = grub_zfs_to_cpu64 ((((dsl_dir_phys_t *) DN_BONUS (&mdn->dn)))->dd_child_dir_zapobj, mdn->endian); err = dnode_get (mosmdn, childobj, DMU_OT_DSL_DIR_CHILD_MAP, mdn, data); if (err) return err; err = zap_lookup (mdn, cname, &objnum, data); if (err) return err; err = dnode_get (mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data); if (err) return err; *fsname = ch; } return GRUB_ERR_NONE; } static grub_err_t make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) { objset_phys_t *osp; blkptr_t *bp; grub_size_t ospsize; grub_err_t err; grub_dprintf ("zfs", "endian = %d\n", mdn->endian); bp = &(((dsl_dataset_phys_t *) DN_BONUS (&mdn->dn))->ds_bp); err = zio_read (bp, mdn->endian, (void **) &osp, &ospsize, data); if (err) return err; if (ospsize < OBJSET_PHYS_SIZE_V14) { grub_free (osp); return grub_error (GRUB_ERR_BAD_FS, "too small osp"); } mdn->endian = (grub_zfs_to_cpu64 (bp->blk_prop, mdn->endian)>>63) & 1; grub_memmove ((char *) &(mdn->dn), (char *) &osp->os_meta_dnode, DNODE_SIZE); grub_free (osp); return GRUB_ERR_NONE; } static grub_err_t dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, grub_uint64_t *mdnobj, dnode_end_t * dn, int *isfs, struct grub_zfs_data *data) { char *fsname, *snapname; const char *ptr_at, *filename; grub_uint64_t headobj; grub_err_t err; ptr_at = grub_strchr (fullpath, '@'); if (! ptr_at) { *isfs = 1; filename = 0; snapname = 0; fsname = grub_strdup (fullpath); } else { const char *ptr_slash = grub_strchr (ptr_at, '/'); *isfs = 0; fsname = grub_malloc (ptr_at - fullpath + 1); if (!fsname) return grub_errno; grub_memcpy (fsname, fullpath, ptr_at - fullpath); fsname[ptr_at - fullpath] = 0; if (ptr_at[1] && ptr_at[1] != '/') { snapname = grub_malloc (ptr_slash - ptr_at); if (!snapname) { grub_free (fsname); return grub_errno; } grub_memcpy (snapname, ptr_at + 1, ptr_slash - ptr_at - 1); snapname[ptr_slash - ptr_at - 1] = 0; } else snapname = 0; if (ptr_slash) filename = ptr_slash; else filename = "/"; grub_dprintf ("zfs", "fsname = '%s' snapname='%s' filename = '%s'\n", fsname, snapname, filename); } grub_dprintf ("zfs", "alive\n"); err = get_filesystem_dnode (&(data->mos), fsname, dn, data); if (err) { grub_free (fsname); grub_free (snapname); return err; } grub_dprintf ("zfs", "alive\n"); headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_head_dataset_obj, dn->endian); grub_dprintf ("zfs", "endian = %d\n", mdn->endian); err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, mdn, data); if (err) { grub_free (fsname); grub_free (snapname); return err; } grub_dprintf ("zfs", "endian = %d\n", mdn->endian); if (snapname) { grub_uint64_t snapobj; snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&mdn->dn))->ds_snapnames_zapobj, mdn->endian); err = dnode_get (&(data->mos), snapobj, DMU_OT_DSL_DS_SNAP_MAP, mdn, data); if (!err) err = zap_lookup (mdn, snapname, &headobj, data); if (!err) err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, mdn, data); if (err) { grub_free (fsname); grub_free (snapname); return err; } } if (mdnobj) *mdnobj = headobj; make_mdn (mdn, data); grub_dprintf ("zfs", "endian = %d\n", mdn->endian); if (*isfs) { grub_free (fsname); grub_free (snapname); return GRUB_ERR_NONE; } err = dnode_get_path (mdn, filename, dn, data); grub_free (fsname); grub_free (snapname); return err; } /* * For a given XDR packed nvlist, verify the first 4 bytes and move on. * * An XDR packed nvlist is encoded as (comments from nvs_xdr_create) : * * encoding method/host endian (4 bytes) * nvl_version (4 bytes) * nvl_nvflag (4 bytes) * encoded nvpairs: * encoded size of the nvpair (4 bytes) * decoded size of the nvpair (4 bytes) * name string size (4 bytes) * name string data (sizeof(NV_ALIGN4(string)) * data type (4 bytes) * # of elements in the nvpair (4 bytes) * data * 2 zero's for the last nvpair * (end of the entire list) (8 bytes) * */ static int nvlist_find_value (char *nvlist, char *name, int valtype, char **val, grub_size_t *size_out, grub_size_t *nelm_out) { int name_len, type, encode_size; char *nvpair, *nvp_name; /* Verify if the 1st and 2nd byte in the nvlist are valid. */ /* NOTE: independently of what endianness header announces all subsequent values are big-endian. */ if (nvlist[0] != NV_ENCODE_XDR || (nvlist[1] != NV_LITTLE_ENDIAN && nvlist[1] != NV_BIG_ENDIAN)) { grub_dprintf ("zfs", "incorrect nvlist header\n"); grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist"); return 0; } /* skip the header, nvl_version, and nvl_nvflag */ nvlist = nvlist + 4 * 3; /* * Loop thru the nvpair list * The XDR representation of an integer is in big-endian byte order. */ while ((encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) nvlist))) { int nelm; nvpair = nvlist + 4 * 2; /* skip the encode/decode size */ name_len = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); nvpair += 4; nvp_name = nvpair; nvpair = nvpair + ((name_len + 3) & ~3); /* align */ type = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); nvpair += 4; nelm = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); if (nelm < 1) return grub_error (GRUB_ERR_BAD_FS, "empty nvpair"); nvpair += 4; if ((grub_strncmp (nvp_name, name, name_len) == 0) && type == valtype) { *val = nvpair; *size_out = encode_size; if (nelm_out) *nelm_out = nelm; return 1; } nvlist += encode_size; /* goto the next nvpair */ } return 0; } int grub_zfs_nvlist_lookup_uint64 (char *nvlist, char *name, grub_uint64_t * out) { char *nvpair; grub_size_t size; int found; found = nvlist_find_value (nvlist, name, DATA_TYPE_UINT64, &nvpair, &size, 0); if (!found) return 0; if (size < sizeof (grub_uint64_t)) { grub_error (GRUB_ERR_BAD_FS, "invalid uint64"); return 0; } *out = grub_be_to_cpu64 (*(grub_uint64_t *) nvpair); return 1; } char * grub_zfs_nvlist_lookup_string (char *nvlist, char *name) { char *nvpair; char *ret; grub_size_t slen; grub_size_t size; int found; found = nvlist_find_value (nvlist, name, DATA_TYPE_STRING, &nvpair, &size, 0); if (!found) return 0; if (size < 4) { grub_error (GRUB_ERR_BAD_FS, "invalid string"); return 0; } slen = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); if (slen > size - 4) slen = size - 4; ret = grub_malloc (slen + 1); if (!ret) return 0; grub_memcpy (ret, nvpair + 4, slen); ret[slen] = 0; return ret; } char * grub_zfs_nvlist_lookup_nvlist (char *nvlist, char *name) { char *nvpair; char *ret; grub_size_t size; int found; found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, &size, 0); if (!found) return 0; ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t)); if (!ret) return 0; grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); grub_memcpy (ret + sizeof (grub_uint32_t), nvpair, size); return ret; } int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name) { char *nvpair; grub_size_t nelm, size; int found; found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, &size, &nelm); if (! found) return -1; return nelm; } char * grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, grub_size_t index) { char *nvpair, *nvpairptr; int found; char *ret; grub_size_t size; unsigned i; grub_size_t nelm; found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, &size, &nelm); if (!found) return 0; if (index >= nelm) { grub_error (GRUB_ERR_OUT_OF_RANGE, "trying to lookup past nvlist array"); return 0; } nvpairptr = nvpair; for (i = 0; i < index; i++) { grub_uint32_t encode_size; /* skip the header, nvl_version, and nvl_nvflag */ nvpairptr = nvpairptr + 4 * 2; while (nvpairptr < nvpair + size && (encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) nvpairptr))) nvlist += encode_size; /* goto the next nvpair */ nvlist = nvlist + 4 * 2; /* skip the ending 2 zeros - 8 bytes */ } if (nvpairptr >= nvpair + size || nvpairptr + grub_be_to_cpu32 (*(grub_uint32_t *) (nvpairptr + 4 * 2)) >= nvpair + size) { grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array"); return 0; } ret = grub_zalloc (grub_be_to_cpu32 (*(grub_uint32_t *) (nvpairptr + 4 * 2)) + 3 * sizeof (grub_uint32_t)); if (!ret) return 0; grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); grub_memcpy (ret + sizeof (grub_uint32_t), nvpairptr, size); return ret; } static grub_err_t zfs_fetch_nvlist (struct grub_zfs_data * data, char **nvlist) { grub_err_t err; *nvlist = grub_malloc (VDEV_PHYS_SIZE); /* Read in the vdev name-value pair list (112K). */ err = grub_disk_read (data->disk, data->vdev_phys_sector, 0, VDEV_PHYS_SIZE, *nvlist); if (err) { grub_free (*nvlist); *nvlist = 0; return err; } return GRUB_ERR_NONE; } /* * Check the disk label information and retrieve needed vdev name-value pairs. * */ static grub_err_t check_pool_label (struct grub_zfs_data *data) { grub_uint64_t pool_state, txg = 0; char *nvlist; #if 0 char *nv; #endif grub_uint64_t diskguid; grub_uint64_t version; int found; grub_err_t err; err = zfs_fetch_nvlist (data, &nvlist); if (err) return err; grub_dprintf ("zfs", "check 2 passed\n"); found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, &pool_state); if (! found) { grub_free (nvlist); if (! grub_errno) grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_STATE " not found"); return grub_errno; } grub_dprintf ("zfs", "check 3 passed\n"); if (pool_state == POOL_STATE_DESTROYED) { grub_free (nvlist); return grub_error (GRUB_ERR_BAD_FS, "zpool is marked as destroyed"); } grub_dprintf ("zfs", "check 4 passed\n"); found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_TXG, &txg); if (!found) { grub_free (nvlist); if (! grub_errno) grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_TXG " not found"); return grub_errno; } grub_dprintf ("zfs", "check 6 passed\n"); /* not an active device */ if (txg == 0) { grub_free (nvlist); return grub_error (GRUB_ERR_BAD_FS, "zpool isn't active"); } grub_dprintf ("zfs", "check 7 passed\n"); found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_VERSION, &version); if (! found) { grub_free (nvlist); if (! grub_errno) grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_VERSION " not found"); return grub_errno; } grub_dprintf ("zfs", "check 8 passed\n"); if (version > SPA_VERSION) { grub_free (nvlist); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "too new version %llu > %llu", (unsigned long long) version, (unsigned long long) SPA_VERSION); } grub_dprintf ("zfs", "check 9 passed\n"); #if 0 if (nvlist_lookup_value (nvlist, ZPOOL_CONFIG_VDEV_TREE, &nv, DATA_TYPE_NVLIST, NULL)) { grub_free (vdev); return (GRUB_ERR_BAD_FS); } grub_dprintf ("zfs", "check 10 passed\n"); #endif found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID, &diskguid); if (! found) { grub_free (nvlist); if (! grub_errno) grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_GUID " not found"); return grub_errno; } grub_dprintf ("zfs", "check 11 passed\n"); grub_free (nvlist); return GRUB_ERR_NONE; } static void zfs_unmount (struct grub_zfs_data *data) { grub_free (data->dnode_buf); grub_free (data->dnode_mdn); grub_free (data->file_buf); grub_free (data); } /* * zfs_mount() locates a valid uberblock of the root pool and read in its MOS * to the memory address MOS. * */ static struct grub_zfs_data * zfs_mount (grub_device_t dev) { struct grub_zfs_data *data = 0; int label = 0; uberblock_phys_t *ub_array, *ubbest = NULL; vdev_boot_header_t *bh; objset_phys_t *osp = 0; grub_size_t ospsize; grub_err_t err; int vdevnum; if (! dev->disk) { grub_error (GRUB_ERR_BAD_DEVICE, "not a disk"); return 0; } data = grub_malloc (sizeof (*data)); if (!data) return 0; grub_memset (data, 0, sizeof (*data)); #if 0 /* if it's our first time here, zero the best uberblock out */ if (data->best_drive == 0 && data->best_part == 0 && find_best_root) grub_memset (¤t_uberblock, 0, sizeof (uberblock_t)); #endif data->disk = dev->disk; ub_array = grub_malloc (VDEV_UBERBLOCK_RING); if (!ub_array) { zfs_unmount (data); return 0; } bh = grub_malloc (VDEV_BOOT_HEADER_SIZE); if (!bh) { zfs_unmount (data); grub_free (ub_array); return 0; } vdevnum = VDEV_LABELS; /* Don't check back labels on CDROM. */ if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) vdevnum = VDEV_LABELS / 2; for (label = 0; ubbest == NULL && label < vdevnum; label++) { grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; grub_dprintf ("zfs", "label %d\n", label); data->vdev_phys_sector = label * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT) + ((VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT) + (label < VDEV_LABELS / 2 ? 0 : grub_disk_get_size (dev->disk) - VDEV_LABELS * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT)); /* Read in the uberblock ring (128K). */ err = grub_disk_read (data->disk, data->vdev_phys_sector + (VDEV_PHYS_SIZE >> SPA_MINBLOCKSHIFT), 0, VDEV_UBERBLOCK_RING, (char *) ub_array); if (err) { grub_errno = GRUB_ERR_NONE; continue; } grub_dprintf ("zfs", "label ok %d\n", label); ubbest = find_bestub (ub_array, data->vdev_phys_sector); if (!ubbest) { grub_dprintf ("zfs", "No uberblock found\n"); grub_errno = GRUB_ERR_NONE; continue; } ub_endian = (grub_zfs_to_cpu64 (ubbest->ubp_uberblock.ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC ? LITTLE_ENDIAN : BIG_ENDIAN); err = zio_read (&ubbest->ubp_uberblock.ub_rootbp, ub_endian, (void **) &osp, &ospsize, data); if (err) { grub_dprintf ("zfs", "couldn't zio_read\n"); grub_errno = GRUB_ERR_NONE; continue; } if (ospsize < OBJSET_PHYS_SIZE_V14) { grub_dprintf ("zfs", "osp too small\n"); grub_free (osp); continue; } grub_dprintf ("zfs", "ubbest %p\n", ubbest); err = check_pool_label (data); if (err) { grub_errno = GRUB_ERR_NONE; continue; } #if 0 if (find_best_root && vdev_uberblock_compare (&ubbest->ubp_uberblock, &(current_uberblock)) <= 0) continue; #endif /* Got the MOS. Save it at the memory addr MOS. */ grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE); data->mos.endian = (grub_zfs_to_cpu64 (ubbest->ubp_uberblock.ub_rootbp.blk_prop, ub_endian) >> 63) & 1; grub_memmove (&(data->current_uberblock), &ubbest->ubp_uberblock, sizeof (uberblock_t)); grub_free (ub_array); grub_free (bh); grub_free (osp); return data; } grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label"); zfs_unmount (data); grub_free (ub_array); grub_free (bh); grub_free (osp); return 0; } grub_err_t grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist) { struct grub_zfs_data *zfs; grub_err_t err; zfs = zfs_mount (dev); if (!zfs) return grub_errno; err = zfs_fetch_nvlist (zfs, nvlist); zfs_unmount (zfs); return err; } static grub_err_t zfs_label (grub_device_t device, char **label) { char *nvlist; grub_err_t err; struct grub_zfs_data *data; data = zfs_mount (device); if (! data) return grub_errno; err = zfs_fetch_nvlist (data, &nvlist); if (err) { zfs_unmount (data); return err; } *label = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); grub_free (nvlist); zfs_unmount (data); return grub_errno; } static grub_err_t zfs_uuid (grub_device_t device, char **uuid) { char *nvlist; int found; struct grub_zfs_data *data; grub_uint64_t guid; grub_err_t err; *uuid = 0; data = zfs_mount (device); if (! data) return grub_errno; err = zfs_fetch_nvlist (data, &nvlist); if (err) { zfs_unmount (data); return err; } found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, &guid); if (! found) return grub_errno; grub_free (nvlist); *uuid = grub_xasprintf ("%016llx", (long long unsigned) guid); zfs_unmount (data); if (! *uuid) return grub_errno; return GRUB_ERR_NONE; } /* * zfs_open() locates a file in the rootpool by following the * MOS and places the dnode of the file in the memory address DNODE. */ static grub_err_t grub_zfs_open (struct grub_file *file, const char *fsfilename) { struct grub_zfs_data *data; grub_err_t err; int isfs; data = zfs_mount (file->device); if (! data) return grub_errno; err = dnode_get_fullpath (fsfilename, &(data->mdn), 0, &(data->dnode), &isfs, data); if (err) { zfs_unmount (data); return err; } if (isfs) { zfs_unmount (data); return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Missing @ or / separator"); } /* We found the dnode for this file. Verify if it is a plain file. */ if (data->dnode.dn.dn_type != DMU_OT_PLAIN_FILE_CONTENTS) { zfs_unmount (data); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a file"); } /* get the file size and set the file position to 0 */ /* * For DMU_OT_SA we will need to locate the SIZE attribute * attribute, which could be either in the bonus buffer * or the "spill" block. */ if (data->dnode.dn.dn_bonustype == DMU_OT_SA) { sa_hdr_phys_t *sahdrp; int hdrsize; if (data->dnode.dn.dn_bonuslen != 0) { sahdrp = (sa_hdr_phys_t *) DN_BONUS (&data->dnode.dn); } else if (data->dnode.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) { blkptr_t *bp = &data->dnode.dn.dn_spill; err = zio_read (bp, data->dnode.endian, (void **) &sahdrp, NULL, data); if (err) return err; } else { return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); } hdrsize = SA_HDR_SIZE (sahdrp); file->size = *(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET); } else { file->size = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&data->dnode.dn))->zp_size, data->dnode.endian); } file->data = data; file->offset = 0; #ifndef GRUB_UTIL grub_dl_ref (my_mod); #endif return GRUB_ERR_NONE; } static grub_ssize_t grub_zfs_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_zfs_data *data = (struct grub_zfs_data *) file->data; int blksz, movesize; grub_size_t length; grub_size_t read; grub_err_t err; if (data->file_buf == NULL) { data->file_buf = grub_malloc (SPA_MAXBLOCKSIZE); if (!data->file_buf) return -1; data->file_start = data->file_end = 0; } /* * If offset is in memory, move it into the buffer provided and return. */ if (file->offset >= data->file_start && file->offset + len <= data->file_end) { grub_memmove (buf, data->file_buf + file->offset - data->file_start, len); return len; } blksz = grub_zfs_to_cpu16 (data->dnode.dn.dn_datablkszsec, data->dnode.endian) << SPA_MINBLOCKSHIFT; /* * Entire Dnode is too big to fit into the space available. We * will need to read it in chunks. This could be optimized to * read in as large a chunk as there is space available, but for * now, this only reads in one data block at a time. */ length = len; read = 0; while (length) { /* * Find requested blkid and the offset within that block. */ grub_uint64_t blkid = grub_divmod64 (file->offset + read, blksz, 0); grub_free (data->file_buf); data->file_buf = 0; err = dmu_read (&(data->dnode), blkid, (void **) &(data->file_buf), 0, data); if (err) return -1; data->file_start = blkid * blksz; data->file_end = data->file_start + blksz; movesize = MIN (length, data->file_end - (int) file->offset - read); grub_memmove (buf, data->file_buf + file->offset + read - data->file_start, movesize); buf += movesize; length -= movesize; read += movesize; } return len; } static grub_err_t grub_zfs_close (grub_file_t file) { zfs_unmount ((struct grub_zfs_data *) file->data); #ifndef GRUB_UTIL grub_dl_unref (my_mod); #endif return GRUB_ERR_NONE; } grub_err_t grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, grub_uint64_t *mdnobj) { struct grub_zfs_data *data; grub_err_t err; int isfs; data = zfs_mount (dev); if (! data) return grub_errno; err = dnode_get_fullpath (fsfilename, &(data->mdn), mdnobj, &(data->dnode), &isfs, data); zfs_unmount (data); return err; } static void fill_fs_info (struct grub_dirhook_info *info, dnode_end_t mdn, struct grub_zfs_data *data) { grub_err_t err; dnode_end_t dn; grub_uint64_t objnum; grub_uint64_t headobj; grub_memset (info, 0, sizeof (*info)); info->dir = 1; if (mdn.dn.dn_type == DMU_OT_DSL_DIR) { headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&mdn.dn))->dd_head_dataset_obj, mdn.endian); err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &mdn, data); if (err) { grub_dprintf ("zfs", "failed here\n"); return; } } make_mdn (&mdn, data); err = dnode_get (&mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, &dn, data); if (err) { grub_dprintf ("zfs", "failed here\n"); return; } err = zap_lookup (&dn, ZFS_ROOT_OBJ, &objnum, data); if (err) { grub_dprintf ("zfs", "failed here\n"); return; } err = dnode_get (&mdn, objnum, 0, &dn, data); if (err) { grub_dprintf ("zfs", "failed here\n"); return; } info->mtimeset = 1; info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); return; } static grub_err_t grub_zfs_dir (grub_device_t device, const char *path, int (*hook) (const char *, const struct grub_dirhook_info *)) { struct grub_zfs_data *data; grub_err_t err; int isfs; auto int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val); auto int NESTED_FUNC_ATTR iterate_zap_fs (const char *name, grub_uint64_t val); auto int NESTED_FUNC_ATTR iterate_zap_snap (const char *name, grub_uint64_t val); int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val) { struct grub_dirhook_info info; dnode_end_t dn; grub_memset (&info, 0, sizeof (info)); dnode_get (&(data->mdn), val, 0, &dn, data); info.mtimeset = 1; info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS); grub_dprintf ("zfs", "type=%d, name=%s\n", (int)dn.dn.dn_type, (char *)name); return hook (name, &info); } int NESTED_FUNC_ATTR iterate_zap_fs (const char *name, grub_uint64_t val) { struct grub_dirhook_info info; dnode_end_t mdn; err = dnode_get (&(data->mos), val, 0, &mdn, data); if (err) return 0; if (mdn.dn.dn_type != DMU_OT_DSL_DIR) return 0; fill_fs_info (&info, mdn, data); return hook (name, &info); } int NESTED_FUNC_ATTR iterate_zap_snap (const char *name, grub_uint64_t val) { struct grub_dirhook_info info; char *name2; int ret; dnode_end_t mdn; err = dnode_get (&(data->mos), val, 0, &mdn, data); if (err) return 0; if (mdn.dn.dn_type != DMU_OT_DSL_DATASET) return 0; fill_fs_info (&info, mdn, data); name2 = grub_malloc (grub_strlen (name) + 2); name2[0] = '@'; grub_memcpy (name2 + 1, name, grub_strlen (name) + 1); ret = hook (name2, &info); grub_free (name2); return ret; } data = zfs_mount (device); if (! data) return grub_errno; err = dnode_get_fullpath (path, &(data->mdn), 0, &(data->dnode), &isfs, data); if (err) { zfs_unmount (data); return err; } if (isfs) { grub_uint64_t childobj, headobj; grub_uint64_t snapobj; dnode_end_t dn; struct grub_dirhook_info info; fill_fs_info (&info, data->dnode, data); hook ("@", &info); childobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_child_dir_zapobj, data->dnode.endian); headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_head_dataset_obj, data->dnode.endian); err = dnode_get (&(data->mos), childobj, DMU_OT_DSL_DIR_CHILD_MAP, &dn, data); if (err) { zfs_unmount (data); return err; } zap_iterate (&dn, iterate_zap_fs, data); err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &dn, data); if (err) { zfs_unmount (data); return err; } snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&dn.dn))->ds_snapnames_zapobj, dn.endian); err = dnode_get (&(data->mos), snapobj, DMU_OT_DSL_DS_SNAP_MAP, &dn, data); if (err) { zfs_unmount (data); return err; } zap_iterate (&dn, iterate_zap_snap, data); } else { if (data->dnode.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS) { zfs_unmount (data); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); } zap_iterate (&(data->dnode), iterate_zap, data); } zfs_unmount (data); return grub_errno; } static struct grub_fs grub_zfs_fs = { .name = "zfs", .dir = grub_zfs_dir, .open = grub_zfs_open, .read = grub_zfs_read, .close = grub_zfs_close, .label = zfs_label, .uuid = zfs_uuid, .mtime = 0, .next = 0 }; GRUB_MOD_INIT (zfs) { grub_fs_register (&grub_zfs_fs); #ifndef GRUB_UTIL my_mod = mod; #endif } GRUB_MOD_FINI (zfs) { grub_fs_unregister (&grub_zfs_fs); } debian/grub-extras/disabled/zfs/zfs_lzjb.c0000664000000000000000000000546012524662415016007 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * Copyright 2007 Sun Microsystems, Inc. * Copyright (C) 2009 Vladimir Serbinenko * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MATCH_BITS 6 #define MATCH_MIN 3 #define OFFSET_MASK ((1 << (16 - MATCH_BITS)) - 1) /* * Decompression Entry - lzjb */ #ifndef NBBY #define NBBY 8 #endif grub_err_t lzjb_decompress (void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len); grub_err_t lzjb_decompress (void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len) { grub_uint8_t *src = s_start; grub_uint8_t *dst = d_start; grub_uint8_t *d_end = (grub_uint8_t *) d_start + d_len; grub_uint8_t *s_end = (grub_uint8_t *) s_start + s_len; grub_uint8_t *cpy, copymap = 0; int copymask = 1 << (NBBY - 1); while (dst < d_end && src < s_end) { if ((copymask <<= 1) == (1 << NBBY)) { copymask = 1; copymap = *src++; } if (src >= s_end) return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed"); if (copymap & copymask) { int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN; int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK; src += 2; cpy = dst - offset; if (src > s_end || cpy < (grub_uint8_t *) d_start) return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed"); while (--mlen >= 0 && dst < d_end) *dst++ = *cpy++; } else *dst++ = *src++; } if (dst < d_end) return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed"); return GRUB_ERR_NONE; } debian/grub-extras/disabled/zfs/include/0000775000000000000000000000000012524676037015443 5ustar debian/grub-extras/disabled/zfs/include/grub/0000775000000000000000000000000012524676037016402 5ustar debian/grub-extras/disabled/zfs/include/grub/zfs/0000775000000000000000000000000012524676037017204 5ustar debian/grub-extras/disabled/zfs/include/grub/zfs/spa.h0000664000000000000000000002641312524662415020141 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * Copyright 2010 Sun Microsystems, Inc. * Copyright (C) 2009 Vladimir Serbinenko * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef GRUB_ZFS_SPA_HEADER #define GRUB_ZFS_SPA_HEADER 1 typedef enum grub_zfs_endian { UNKNOWN_ENDIAN = -2, LITTLE_ENDIAN = -1, BIG_ENDIAN = 0 } grub_zfs_endian_t; #define grub_zfs_to_cpu16(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu16(x) \ : grub_le_to_cpu16(x)) #define grub_cpu_to_zfs16(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be16(x) \ : grub_cpu_to_le16(x)) #define grub_zfs_to_cpu32(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu32(x) \ : grub_le_to_cpu32(x)) #define grub_cpu_to_zfs32(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be32(x) \ : grub_cpu_to_le32(x)) #define grub_zfs_to_cpu64(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu64(x) \ : grub_le_to_cpu64(x)) #define grub_cpu_to_zfs64(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be64(x) \ : grub_cpu_to_le64(x)) /* * General-purpose 32-bit and 64-bit bitfield encodings. */ #define BF32_DECODE(x, low, len) P2PHASE((x) >> (low), 1U << (len)) #define BF64_DECODE(x, low, len) P2PHASE((x) >> (low), 1ULL << (len)) #define BF32_ENCODE(x, low, len) (P2PHASE((x), 1U << (len)) << (low)) #define BF64_ENCODE(x, low, len) (P2PHASE((x), 1ULL << (len)) << (low)) #define BF32_GET(x, low, len) BF32_DECODE(x, low, len) #define BF64_GET(x, low, len) BF64_DECODE(x, low, len) #define BF32_SET(x, low, len, val) \ ((x) ^= BF32_ENCODE((x >> low) ^ (val), low, len)) #define BF64_SET(x, low, len, val) \ ((x) ^= BF64_ENCODE((x >> low) ^ (val), low, len)) #define BF32_GET_SB(x, low, len, shift, bias) \ ((BF32_GET(x, low, len) + (bias)) << (shift)) #define BF64_GET_SB(x, low, len, shift, bias) \ ((BF64_GET(x, low, len) + (bias)) << (shift)) #define BF32_SET_SB(x, low, len, shift, bias, val) \ BF32_SET(x, low, len, ((val) >> (shift)) - (bias)) #define BF64_SET_SB(x, low, len, shift, bias, val) \ BF64_SET(x, low, len, ((val) >> (shift)) - (bias)) /* * We currently support nine block sizes, from 512 bytes to 128K. * We could go higher, but the benefits are near-zero and the cost * of COWing a giant block to modify one byte would become excessive. */ #define SPA_MINBLOCKSHIFT 9 #define SPA_MAXBLOCKSHIFT 17 #define SPA_MINBLOCKSIZE (1ULL << SPA_MINBLOCKSHIFT) #define SPA_MAXBLOCKSIZE (1ULL << SPA_MAXBLOCKSHIFT) #define SPA_BLOCKSIZES (SPA_MAXBLOCKSHIFT - SPA_MINBLOCKSHIFT + 1) /* * Size of block to hold the configuration data (a packed nvlist) */ #define SPA_CONFIG_BLOCKSIZE (1 << 14) /* * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB. * The ASIZE encoding should be at least 64 times larger (6 more bits) * to support up to 4-way RAID-Z mirror mode with worst-case gang block * overhead, three DVAs per bp, plus one more bit in case we do anything * else that expands the ASIZE. */ #define SPA_LSIZEBITS 16 /* LSIZE up to 32M (2^16 * 512) */ #define SPA_PSIZEBITS 16 /* PSIZE up to 32M (2^16 * 512) */ #define SPA_ASIZEBITS 24 /* ASIZE up to 64 times larger */ /* * All SPA data is represented by 128-bit data virtual addresses (DVAs). * The members of the dva_t should be considered opaque outside the SPA. */ typedef struct dva { grub_uint64_t dva_word[2]; } dva_t; /* * Each block has a 256-bit checksum -- strong enough for cryptographic hashes. */ typedef struct zio_cksum { grub_uint64_t zc_word[4]; } zio_cksum_t; /* * Each block is described by its DVAs, time of birth, checksum, etc. * The word-by-word, bit-by-bit layout of the blkptr is as follows: * * 64 56 48 40 32 24 16 8 0 * +-------+-------+-------+-------+-------+-------+-------+-------+ * 0 | vdev1 | GRID | ASIZE | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 1 |G| offset1 | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 2 | vdev2 | GRID | ASIZE | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 3 |G| offset2 | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 4 | vdev3 | GRID | ASIZE | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 5 |G| offset3 | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 6 |BDX|lvl| type | cksum | comp | PSIZE | LSIZE | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 7 | padding | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 8 | padding | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 9 | physical birth txg | * +-------+-------+-------+-------+-------+-------+-------+-------+ * a | logical birth txg | * +-------+-------+-------+-------+-------+-------+-------+-------+ * b | fill count | * +-------+-------+-------+-------+-------+-------+-------+-------+ * c | checksum[0] | * +-------+-------+-------+-------+-------+-------+-------+-------+ * d | checksum[1] | * +-------+-------+-------+-------+-------+-------+-------+-------+ * e | checksum[2] | * +-------+-------+-------+-------+-------+-------+-------+-------+ * f | checksum[3] | * +-------+-------+-------+-------+-------+-------+-------+-------+ * * Legend: * * vdev virtual device ID * offset offset into virtual device * LSIZE logical size * PSIZE physical size (after compression) * ASIZE allocated size (including RAID-Z parity and gang block headers) * GRID RAID-Z layout information (reserved for future use) * cksum checksum function * comp compression function * G gang block indicator * B byteorder (endianness) * D dedup * X unused * lvl level of indirection * type DMU object type * phys birth txg of block allocation; zero if same as logical birth txg * log. birth transaction group in which the block was logically born * fill count number of non-zero blocks under this bp * checksum[4] 256-bit checksum of the data this bp describes */ #define SPA_BLKPTRSHIFT 7 /* blkptr_t is 128 bytes */ #define SPA_DVAS_PER_BP 3 /* Number of DVAs in a bp */ typedef struct blkptr { dva_t blk_dva[SPA_DVAS_PER_BP]; /* Data Virtual Addresses */ grub_uint64_t blk_prop; /* size, compression, type, etc */ grub_uint64_t blk_pad[2]; /* Extra space for the future */ grub_uint64_t blk_phys_birth; /* txg when block was allocated */ grub_uint64_t blk_birth; /* transaction group at birth */ grub_uint64_t blk_fill; /* fill count */ zio_cksum_t blk_cksum; /* 256-bit checksum */ } blkptr_t; /* * Macros to get and set fields in a bp or DVA. */ #define DVA_GET_ASIZE(dva) \ BF64_GET_SB((dva)->dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0) #define DVA_SET_ASIZE(dva, x) \ BF64_SET_SB((dva)->dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0, x) #define DVA_GET_GRID(dva) BF64_GET((dva)->dva_word[0], 24, 8) #define DVA_SET_GRID(dva, x) BF64_SET((dva)->dva_word[0], 24, 8, x) #define DVA_GET_VDEV(dva) BF64_GET((dva)->dva_word[0], 32, 32) #define DVA_SET_VDEV(dva, x) BF64_SET((dva)->dva_word[0], 32, 32, x) #define DVA_GET_GANG(dva) BF64_GET((dva)->dva_word[1], 63, 1) #define DVA_SET_GANG(dva, x) BF64_SET((dva)->dva_word[1], 63, 1, x) #define BP_GET_LSIZE(bp) \ BF64_GET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1) #define BP_SET_LSIZE(bp, x) \ BF64_SET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x) #define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 8) #define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 8, x) #define BP_GET_CHECKSUM(bp) BF64_GET((bp)->blk_prop, 40, 8) #define BP_SET_CHECKSUM(bp, x) BF64_SET((bp)->blk_prop, 40, 8, x) #define BP_GET_TYPE(bp) BF64_GET((bp)->blk_prop, 48, 8) #define BP_SET_TYPE(bp, x) BF64_SET((bp)->blk_prop, 48, 8, x) #define BP_GET_LEVEL(bp) BF64_GET((bp)->blk_prop, 56, 5) #define BP_SET_LEVEL(bp, x) BF64_SET((bp)->blk_prop, 56, 5, x) #define BP_GET_PROP_BIT_61(bp) BF64_GET((bp)->blk_prop, 61, 1) #define BP_SET_PROP_BIT_61(bp, x) BF64_SET((bp)->blk_prop, 61, 1, x) #define BP_GET_DEDUP(bp) BF64_GET((bp)->blk_prop, 62, 1) #define BP_SET_DEDUP(bp, x) BF64_SET((bp)->blk_prop, 62, 1, x) #define BP_GET_BYTEORDER(bp) (0 - BF64_GET((bp)->blk_prop, 63, 1)) #define BP_SET_BYTEORDER(bp, x) BF64_SET((bp)->blk_prop, 63, 1, x) #define BP_PHYSICAL_BIRTH(bp) \ ((bp)->blk_phys_birth ? (bp)->blk_phys_birth : (bp)->blk_birth) #define BP_SET_BIRTH(bp, logical, physical) \ { \ (bp)->blk_birth = (logical); \ (bp)->blk_phys_birth = ((logical) == (physical) ? 0 : (physical)); \ } #define BP_GET_ASIZE(bp) \ (DVA_GET_ASIZE(&(bp)->blk_dva[0]) + DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \ DVA_GET_ASIZE(&(bp)->blk_dva[2])) #define BP_GET_UCSIZE(bp) \ ((BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata) ? \ BP_GET_PSIZE(bp) : BP_GET_LSIZE(bp)); #define BP_GET_NDVAS(bp) \ (!!DVA_GET_ASIZE(&(bp)->blk_dva[0]) + \ !!DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \ !!DVA_GET_ASIZE(&(bp)->blk_dva[2])) #define BP_COUNT_GANG(bp) \ (DVA_GET_GANG(&(bp)->blk_dva[0]) + \ DVA_GET_GANG(&(bp)->blk_dva[1]) + \ DVA_GET_GANG(&(bp)->blk_dva[2])) #define DVA_EQUAL(dva1, dva2) \ ((dva1)->dva_word[1] == (dva2)->dva_word[1] && \ (dva1)->dva_word[0] == (dva2)->dva_word[0]) #define BP_EQUAL(bp1, bp2) \ (BP_PHYSICAL_BIRTH(bp1) == BP_PHYSICAL_BIRTH(bp2) && \ DVA_EQUAL(&(bp1)->blk_dva[0], &(bp2)->blk_dva[0]) && \ DVA_EQUAL(&(bp1)->blk_dva[1], &(bp2)->blk_dva[1]) && \ DVA_EQUAL(&(bp1)->blk_dva[2], &(bp2)->blk_dva[2])) #define ZIO_CHECKSUM_EQUAL(zc1, zc2) \ (0 == (((zc1).zc_word[0] - (zc2).zc_word[0]) | \ ((zc1).zc_word[1] - (zc2).zc_word[1]) | \ ((zc1).zc_word[2] - (zc2).zc_word[2]) | \ ((zc1).zc_word[3] - (zc2).zc_word[3]))) #define DVA_IS_VALID(dva) (DVA_GET_ASIZE(dva) != 0) #define ZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3) \ { \ (zcp)->zc_word[0] = w0; \ (zcp)->zc_word[1] = w1; \ (zcp)->zc_word[2] = w2; \ (zcp)->zc_word[3] = w3; \ } #define BP_IDENTITY(bp) (&(bp)->blk_dva[0]) #define BP_IS_GANG(bp) DVA_GET_GANG(BP_IDENTITY(bp)) #define BP_IS_HOLE(bp) ((bp)->blk_birth == 0) /* BP_IS_RAIDZ(bp) assumes no block compression */ #define BP_IS_RAIDZ(bp) (DVA_GET_ASIZE(&(bp)->blk_dva[0]) > \ BP_GET_PSIZE(bp)) #define BP_ZERO(bp) \ { \ (bp)->blk_dva[0].dva_word[0] = 0; \ (bp)->blk_dva[0].dva_word[1] = 0; \ (bp)->blk_dva[1].dva_word[0] = 0; \ (bp)->blk_dva[1].dva_word[1] = 0; \ (bp)->blk_dva[2].dva_word[0] = 0; \ (bp)->blk_dva[2].dva_word[1] = 0; \ (bp)->blk_prop = 0; \ (bp)->blk_pad[0] = 0; \ (bp)->blk_pad[1] = 0; \ (bp)->blk_phys_birth = 0; \ (bp)->blk_birth = 0; \ (bp)->blk_fill = 0; \ ZIO_SET_CHECKSUM(&(bp)->blk_cksum, 0, 0, 0, 0); \ } #define BP_SPRINTF_LEN 320 #endif /* ! GRUB_ZFS_SPA_HEADER */ debian/grub-extras/disabled/zfs/include/grub/zfs/uberblock_impl.h0000664000000000000000000000437712524662415022354 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_UBERBLOCK_IMPL_H #define _SYS_UBERBLOCK_IMPL_H /* * The uberblock version is incremented whenever an incompatible on-disk * format change is made to the SPA, DMU, or ZAP. * * Note: the first two fields should never be moved. When a storage pool * is opened, the uberblock must be read off the disk before the version * can be checked. If the ub_version field is moved, we may not detect * version mismatch. If the ub_magic field is moved, applications that * expect the magic number in the first word won't work. */ #define UBERBLOCK_MAGIC 0x00bab10c /* oo-ba-bloc! */ #define UBERBLOCK_SHIFT 10 /* up to 1K */ typedef struct uberblock { grub_uint64_t ub_magic; /* UBERBLOCK_MAGIC */ grub_uint64_t ub_version; /* ZFS_VERSION */ grub_uint64_t ub_txg; /* txg of last sync */ grub_uint64_t ub_guid_sum; /* sum of all vdev guids */ grub_uint64_t ub_timestamp; /* UTC time of last sync */ blkptr_t ub_rootbp; /* MOS objset_phys_t */ } uberblock_t; #define UBERBLOCK_SIZE (1ULL << UBERBLOCK_SHIFT) #define VDEV_UBERBLOCK_SHIFT UBERBLOCK_SHIFT /* XXX Uberblock_phys_t is no longer in the kernel zfs */ typedef struct uberblock_phys { uberblock_t ubp_uberblock; char ubp_pad[UBERBLOCK_SIZE - sizeof (uberblock_t) - sizeof (zio_eck_t)]; zio_eck_t ubp_zec; } uberblock_phys_t; #endif /* _SYS_UBERBLOCK_IMPL_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/zio.h0000664000000000000000000000455412524662415020161 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _ZIO_H #define _ZIO_H #include #define ZEC_MAGIC 0x210da7ab10c7a11ULL /* zio data bloc tail */ typedef struct zio_eck { grub_uint64_t zec_magic; /* for validation, endianness */ zio_cksum_t zec_cksum; /* 256-bit checksum */ } zio_eck_t; /* * Gang block headers are self-checksumming and contain an array * of block pointers. */ #define SPA_GANGBLOCKSIZE SPA_MINBLOCKSIZE #define SPA_GBH_NBLKPTRS ((SPA_GANGBLOCKSIZE - \ sizeof (zio_eck_t)) / sizeof (blkptr_t)) #define SPA_GBH_FILLER ((SPA_GANGBLOCKSIZE - \ sizeof (zio_eck_t) - \ (SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\ sizeof (grub_uint64_t)) #define ZIO_GET_IOSIZE(zio) \ (BP_IS_GANG((zio)->io_bp) ? \ SPA_GANGBLOCKSIZE : BP_GET_PSIZE((zio)->io_bp)) typedef struct zio_gbh { blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS]; grub_uint64_t zg_filler[SPA_GBH_FILLER]; zio_eck_t zg_tail; } zio_gbh_phys_t; enum zio_checksum { ZIO_CHECKSUM_INHERIT = 0, ZIO_CHECKSUM_ON, ZIO_CHECKSUM_OFF, ZIO_CHECKSUM_LABEL, ZIO_CHECKSUM_GANG_HEADER, ZIO_CHECKSUM_ZILOG, ZIO_CHECKSUM_FLETCHER_2, ZIO_CHECKSUM_FLETCHER_4, ZIO_CHECKSUM_SHA256, ZIO_CHECKSUM_ZILOG2, ZIO_CHECKSUM_FUNCTIONS }; #define ZIO_CHECKSUM_ON_VALUE ZIO_CHECKSUM_FLETCHER_2 #define ZIO_CHECKSUM_DEFAULT ZIO_CHECKSUM_ON enum zio_compress { ZIO_COMPRESS_INHERIT = 0, ZIO_COMPRESS_ON, ZIO_COMPRESS_OFF, ZIO_COMPRESS_LZJB, ZIO_COMPRESS_EMPTY, ZIO_COMPRESS_GZIP, ZIO_COMPRESS_FUNCTIONS }; #endif /* _ZIO_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/sa_impl.h0000664000000000000000000000234312524662415020776 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_SA_IMPL_H #define _SYS_SA_IMPL_H typedef struct sa_hdr_phys { grub_uint32_t sa_magic; grub_uint16_t sa_layout_info; grub_uint16_t sa_lengths[1]; } sa_hdr_phys_t; #define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0) #define SA_SIZE_OFFSET 0x8 #endif /* _SYS_SA_IMPL_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/zil.h0000664000000000000000000000412512524662415020150 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_ZIL_H #define _SYS_ZIL_H /* * Intent log format: * * Each objset has its own intent log. The log header (zil_header_t) * for objset N's intent log is kept in the Nth object of the SPA's * intent_log objset. The log header points to a chain of log blocks, * each of which contains log records (i.e., transactions) followed by * a log block trailer (zil_trailer_t). The format of a log record * depends on the record (or transaction) type, but all records begin * with a common structure that defines the type, length, and txg. */ /* * Intent log header - this on disk structure holds fields to manage * the log. All fields are 64 bit to easily handle cross architectures. */ typedef struct zil_header { grub_uint64_t zh_claim_txg; /* txg in which log blocks were claimed */ grub_uint64_t zh_replay_seq; /* highest replayed sequence number */ blkptr_t zh_log; /* log chain */ grub_uint64_t zh_claim_seq; /* highest claimed sequence number */ grub_uint64_t zh_flags; /* header flags */ grub_uint64_t zh_pad[4]; } zil_header_t; /* * zh_flags bit settings */ #define ZIL_REPLAY_NEEDED 0x1 /* replay needed - internal only */ #endif /* _SYS_ZIL_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/dmu.h0000664000000000000000000000726612524662415020150 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DMU_H #define _SYS_DMU_H /* * This file describes the interface that the DMU provides for its * consumers. * * The DMU also interacts with the SPA. That interface is described in * dmu_spa.h. */ typedef enum dmu_object_type { DMU_OT_NONE, /* general: */ DMU_OT_OBJECT_DIRECTORY, /* ZAP */ DMU_OT_OBJECT_ARRAY, /* UINT64 */ DMU_OT_PACKED_NVLIST, /* UINT8 (XDR by nvlist_pack/unpack) */ DMU_OT_PACKED_NVLIST_SIZE, /* UINT64 */ DMU_OT_BPLIST, /* UINT64 */ DMU_OT_BPLIST_HDR, /* UINT64 */ /* spa: */ DMU_OT_SPACE_MAP_HEADER, /* UINT64 */ DMU_OT_SPACE_MAP, /* UINT64 */ /* zil: */ DMU_OT_INTENT_LOG, /* UINT64 */ /* dmu: */ DMU_OT_DNODE, /* DNODE */ DMU_OT_OBJSET, /* OBJSET */ /* dsl: */ DMU_OT_DSL_DIR, /* UINT64 */ DMU_OT_DSL_DIR_CHILD_MAP, /* ZAP */ DMU_OT_DSL_DS_SNAP_MAP, /* ZAP */ DMU_OT_DSL_PROPS, /* ZAP */ DMU_OT_DSL_DATASET, /* UINT64 */ /* zpl: */ DMU_OT_ZNODE, /* ZNODE */ DMU_OT_OLDACL, /* OLD ACL */ DMU_OT_PLAIN_FILE_CONTENTS, /* UINT8 */ DMU_OT_DIRECTORY_CONTENTS, /* ZAP */ DMU_OT_MASTER_NODE, /* ZAP */ DMU_OT_UNLINKED_SET, /* ZAP */ /* zvol: */ DMU_OT_ZVOL, /* UINT8 */ DMU_OT_ZVOL_PROP, /* ZAP */ /* other; for testing only! */ DMU_OT_PLAIN_OTHER, /* UINT8 */ DMU_OT_UINT64_OTHER, /* UINT64 */ DMU_OT_ZAP_OTHER, /* ZAP */ /* new object types: */ DMU_OT_ERROR_LOG, /* ZAP */ DMU_OT_SPA_HISTORY, /* UINT8 */ DMU_OT_SPA_HISTORY_OFFSETS, /* spa_his_phys_t */ DMU_OT_POOL_PROPS, /* ZAP */ DMU_OT_DSL_PERMS, /* ZAP */ DMU_OT_ACL, /* ACL */ DMU_OT_SYSACL, /* SYSACL */ DMU_OT_FUID, /* FUID table (Packed NVLIST UINT8) */ DMU_OT_FUID_SIZE, /* FUID table size UINT64 */ DMU_OT_NEXT_CLONES, /* ZAP */ DMU_OT_SCRUB_QUEUE, /* ZAP */ DMU_OT_USERGROUP_USED, /* ZAP */ DMU_OT_USERGROUP_QUOTA, /* ZAP */ DMU_OT_USERREFS, /* ZAP */ DMU_OT_DDT_ZAP, /* ZAP */ DMU_OT_DDT_STATS, /* ZAP */ DMU_OT_SA, /* System attr */ DMU_OT_SA_MASTER_NODE, /* ZAP */ DMU_OT_SA_ATTR_REGISTRATION, /* ZAP */ DMU_OT_SA_ATTR_LAYOUTS, /* ZAP */ DMU_OT_NUMTYPES } dmu_object_type_t; typedef enum dmu_objset_type { DMU_OST_NONE, DMU_OST_META, DMU_OST_ZFS, DMU_OST_ZVOL, DMU_OST_OTHER, /* For testing only! */ DMU_OST_ANY, /* Be careful! */ DMU_OST_NUMTYPES } dmu_objset_type_t; /* * The names of zap entries in the DIRECTORY_OBJECT of the MOS. */ #define DMU_POOL_DIRECTORY_OBJECT 1 #define DMU_POOL_CONFIG "config" #define DMU_POOL_ROOT_DATASET "root_dataset" #define DMU_POOL_SYNC_BPLIST "sync_bplist" #define DMU_POOL_ERRLOG_SCRUB "errlog_scrub" #define DMU_POOL_ERRLOG_LAST "errlog_last" #define DMU_POOL_SPARES "spares" #define DMU_POOL_DEFLATE "deflate" #define DMU_POOL_HISTORY "history" #define DMU_POOL_PROPS "pool_props" #define DMU_POOL_L2CACHE "l2cache" #endif /* _SYS_DMU_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/dsl_dir.h0000664000000000000000000000336412524662415020776 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DSL_DIR_H #define _SYS_DSL_DIR_H typedef struct dsl_dir_phys { grub_uint64_t dd_creation_time; /* not actually used */ grub_uint64_t dd_head_dataset_obj; grub_uint64_t dd_parent_obj; grub_uint64_t dd_clone_parent_obj; grub_uint64_t dd_child_dir_zapobj; /* * how much space our children are accounting for; for leaf * datasets, == physical space used by fs + snaps */ grub_uint64_t dd_used_bytes; grub_uint64_t dd_compressed_bytes; grub_uint64_t dd_uncompressed_bytes; /* Administrative quota setting */ grub_uint64_t dd_quota; /* Administrative reservation setting */ grub_uint64_t dd_reserved; grub_uint64_t dd_props_zapobj; grub_uint64_t dd_deleg_zapobj; /* dataset permissions */ grub_uint64_t dd_pad[20]; /* pad out to 256 bytes for good measure */ } dsl_dir_phys_t; #endif /* _SYS_DSL_DIR_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/dsl_dataset.h0000664000000000000000000000373412524662415021646 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DSL_DATASET_H #define _SYS_DSL_DATASET_H typedef struct dsl_dataset_phys { grub_uint64_t ds_dir_obj; grub_uint64_t ds_prev_snap_obj; grub_uint64_t ds_prev_snap_txg; grub_uint64_t ds_next_snap_obj; grub_uint64_t ds_snapnames_zapobj; /* zap obj of snaps; ==0 for snaps */ grub_uint64_t ds_num_children; /* clone/snap children; ==0 for head */ grub_uint64_t ds_creation_time; /* seconds since 1970 */ grub_uint64_t ds_creation_txg; grub_uint64_t ds_deadlist_obj; grub_uint64_t ds_used_bytes; grub_uint64_t ds_compressed_bytes; grub_uint64_t ds_uncompressed_bytes; grub_uint64_t ds_unique_bytes; /* only relevant to snapshots */ /* * The ds_fsid_guid is a 56-bit ID that can change to avoid * collisions. The ds_guid is a 64-bit ID that will never * change, so there is a small probability that it will collide. */ grub_uint64_t ds_fsid_guid; grub_uint64_t ds_guid; grub_uint64_t ds_flags; blkptr_t ds_bp; grub_uint64_t ds_pad[8]; /* pad out to 320 bytes for good measure */ } dsl_dataset_phys_t; #endif /* _SYS_DSL_DATASET_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/vdev_impl.h0000664000000000000000000000463312524662415021343 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_VDEV_IMPL_H #define _SYS_VDEV_IMPL_H #define VDEV_SKIP_SIZE (8 << 10) #define VDEV_BOOT_HEADER_SIZE (8 << 10) #define VDEV_PHYS_SIZE (112 << 10) #define VDEV_UBERBLOCK_RING (128 << 10) /* ZFS boot block */ #define VDEV_BOOT_MAGIC 0x2f5b007b10cULL #define VDEV_BOOT_VERSION 1 /* version number */ typedef struct vdev_boot_header { grub_uint64_t vb_magic; /* VDEV_BOOT_MAGIC */ grub_uint64_t vb_version; /* VDEV_BOOT_VERSION */ grub_uint64_t vb_offset; /* start offset (bytes) */ grub_uint64_t vb_size; /* size (bytes) */ char vb_pad[VDEV_BOOT_HEADER_SIZE - 4 * sizeof (grub_uint64_t)]; } vdev_boot_header_t; typedef struct vdev_phys { char vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_eck_t)]; zio_eck_t vp_zbt; } vdev_phys_t; typedef struct vdev_label { char vl_pad[VDEV_SKIP_SIZE]; /* 8K */ vdev_boot_header_t vl_boot_header; /* 8K */ vdev_phys_t vl_vdev_phys; /* 112K */ char vl_uberblock[VDEV_UBERBLOCK_RING]; /* 128K */ } vdev_label_t; /* 256K total */ /* * Size and offset of embedded boot loader region on each label. * The total size of the first two labels plus the boot area is 4MB. */ #define VDEV_BOOT_OFFSET (2 * sizeof (vdev_label_t)) #define VDEV_BOOT_SIZE (7ULL << 19) /* 3.5M */ /* * Size of label regions at the start and end of each leaf device. */ #define VDEV_LABEL_START_SIZE (2 * sizeof (vdev_label_t) + VDEV_BOOT_SIZE) #define VDEV_LABEL_END_SIZE (2 * sizeof (vdev_label_t)) #define VDEV_LABELS 4 #endif /* _SYS_VDEV_IMPL_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/zfs_znode.h0000664000000000000000000000524612524662415021360 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_FS_ZFS_ZNODE_H #define _SYS_FS_ZFS_ZNODE_H #include #define MASTER_NODE_OBJ 1 #define ZFS_ROOT_OBJ "ROOT" #define ZPL_VERSION_STR "VERSION" #define ZFS_SA_ATTRS "SA_ATTRS" #define ZPL_VERSION 5ULL #define ZFS_DIRENT_OBJ(de) BF64_GET(de, 0, 48) /* * This is the persistent portion of the znode. It is stored * in the "bonus buffer" of the file. Short symbolic links * are also stored in the bonus buffer. */ typedef struct znode_phys { grub_uint64_t zp_atime[2]; /* 0 - last file access time */ grub_uint64_t zp_mtime[2]; /* 16 - last file modification time */ grub_uint64_t zp_ctime[2]; /* 32 - last file change time */ grub_uint64_t zp_crtime[2]; /* 48 - creation time */ grub_uint64_t zp_gen; /* 64 - generation (txg of creation) */ grub_uint64_t zp_mode; /* 72 - file mode bits */ grub_uint64_t zp_size; /* 80 - size of file */ grub_uint64_t zp_parent; /* 88 - directory parent (`..') */ grub_uint64_t zp_links; /* 96 - number of links to file */ grub_uint64_t zp_xattr; /* 104 - DMU object for xattrs */ grub_uint64_t zp_rdev; /* 112 - dev_t for VBLK & VCHR files */ grub_uint64_t zp_flags; /* 120 - persistent flags */ grub_uint64_t zp_uid; /* 128 - file owner */ grub_uint64_t zp_gid; /* 136 - owning group */ grub_uint64_t zp_pad[4]; /* 144 - future */ zfs_znode_acl_t zp_acl; /* 176 - 263 ACL */ /* * Data may pad out any remaining bytes in the znode buffer, eg: * * |<---------------------- dnode_phys (512) ------------------------>| * |<-- dnode (192) --->|<----------- "bonus" buffer (320) ---------->| * |<---- znode (264) ---->|<---- data (56) ---->| * * At present, we only use this space to store symbolic links. */ } znode_phys_t; #endif /* _SYS_FS_ZFS_ZNODE_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/zio_checksum.h0000664000000000000000000000344412524662415022040 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_ZIO_CHECKSUM_H #define _SYS_ZIO_CHECKSUM_H /* * Signature for checksum functions. */ typedef void zio_checksum_t(const void *data, grub_uint64_t size, grub_zfs_endian_t endian, zio_cksum_t *zcp); /* * Information about each checksum function. */ typedef struct zio_checksum_info { zio_checksum_t *ci_func; /* checksum function for each byteorder */ int ci_correctable; /* number of correctable bits */ int ci_eck; /* uses zio embedded checksum? */ char *ci_name; /* descriptive name */ } zio_checksum_info_t; extern void zio_checksum_SHA256 (const void *, grub_uint64_t, grub_zfs_endian_t endian, zio_cksum_t *); extern void fletcher_2 (const void *, grub_uint64_t, grub_zfs_endian_t endian, zio_cksum_t *); extern void fletcher_4 (const void *, grub_uint64_t, grub_zfs_endian_t endian, zio_cksum_t *); #endif /* _SYS_ZIO_CHECKSUM_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/zap_impl.h0000664000000000000000000000726312524662415021173 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_ZAP_IMPL_H #define _SYS_ZAP_IMPL_H #define ZAP_MAGIC 0x2F52AB2ABULL #define ZAP_HASHBITS 28 #define MZAP_ENT_LEN 64 #define MZAP_NAME_LEN (MZAP_ENT_LEN - 8 - 4 - 2) #define MZAP_MAX_BLKSHIFT SPA_MAXBLOCKSHIFT #define MZAP_MAX_BLKSZ (1 << MZAP_MAX_BLKSHIFT) typedef struct mzap_ent_phys { grub_uint64_t mze_value; grub_uint32_t mze_cd; grub_uint16_t mze_pad; /* in case we want to chain them someday */ char mze_name[MZAP_NAME_LEN]; } mzap_ent_phys_t; typedef struct mzap_phys { grub_uint64_t mz_block_type; /* ZBT_MICRO */ grub_uint64_t mz_salt; grub_uint64_t mz_pad[6]; mzap_ent_phys_t mz_chunk[1]; /* actually variable size depending on block size */ } mzap_phys_t; /* * The (fat) zap is stored in one object. It is an array of * 1<= 6] [zap_leaf_t] [ptrtbl] ... * */ #define ZBT_LEAF ((1ULL << 63) + 0) #define ZBT_HEADER ((1ULL << 63) + 1) #define ZBT_MICRO ((1ULL << 63) + 3) /* any other values are ptrtbl blocks */ /* * the embedded pointer table takes up half a block: * block size / entry size (2^3) / 2 */ #define ZAP_EMBEDDED_PTRTBL_SHIFT(zap) (FZAP_BLOCK_SHIFT(zap) - 3 - 1) /* * The embedded pointer table starts half-way through the block. Since * the pointer table itself is half the block, it starts at (64-bit) * word number (1<zap_f.zap_phys) \ [(idx) + (1< * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef GRUB_ZFS_HEADER #define GRUB_ZFS_HEADER 1 #include #include /* * On-disk version number. */ #define SPA_VERSION 28ULL /* * The following are configuration names used in the nvlist describing a pool's * configuration. */ #define ZPOOL_CONFIG_VERSION "version" #define ZPOOL_CONFIG_POOL_NAME "name" #define ZPOOL_CONFIG_POOL_STATE "state" #define ZPOOL_CONFIG_POOL_TXG "txg" #define ZPOOL_CONFIG_POOL_GUID "pool_guid" #define ZPOOL_CONFIG_CREATE_TXG "create_txg" #define ZPOOL_CONFIG_TOP_GUID "top_guid" #define ZPOOL_CONFIG_VDEV_TREE "vdev_tree" #define ZPOOL_CONFIG_TYPE "type" #define ZPOOL_CONFIG_CHILDREN "children" #define ZPOOL_CONFIG_ID "id" #define ZPOOL_CONFIG_GUID "guid" #define ZPOOL_CONFIG_PATH "path" #define ZPOOL_CONFIG_DEVID "devid" #define ZPOOL_CONFIG_METASLAB_ARRAY "metaslab_array" #define ZPOOL_CONFIG_METASLAB_SHIFT "metaslab_shift" #define ZPOOL_CONFIG_ASHIFT "ashift" #define ZPOOL_CONFIG_ASIZE "asize" #define ZPOOL_CONFIG_DTL "DTL" #define ZPOOL_CONFIG_STATS "stats" #define ZPOOL_CONFIG_WHOLE_DISK "whole_disk" #define ZPOOL_CONFIG_ERRCOUNT "error_count" #define ZPOOL_CONFIG_NOT_PRESENT "not_present" #define ZPOOL_CONFIG_SPARES "spares" #define ZPOOL_CONFIG_IS_SPARE "is_spare" #define ZPOOL_CONFIG_NPARITY "nparity" #define ZPOOL_CONFIG_PHYS_PATH "phys_path" #define ZPOOL_CONFIG_L2CACHE "l2cache" #define ZPOOL_CONFIG_HOLE_ARRAY "hole_array" #define ZPOOL_CONFIG_VDEV_CHILDREN "vdev_children" #define ZPOOL_CONFIG_IS_HOLE "is_hole" #define ZPOOL_CONFIG_DDT_HISTOGRAM "ddt_histogram" #define ZPOOL_CONFIG_DDT_OBJ_STATS "ddt_object_stats" #define ZPOOL_CONFIG_DDT_STATS "ddt_stats" /* * The persistent vdev state is stored as separate values rather than a single * 'vdev_state' entry. This is because a device can be in multiple states, such * as offline and degraded. */ #define ZPOOL_CONFIG_OFFLINE "offline" #define ZPOOL_CONFIG_FAULTED "faulted" #define ZPOOL_CONFIG_DEGRADED "degraded" #define ZPOOL_CONFIG_REMOVED "removed" #define VDEV_TYPE_ROOT "root" #define VDEV_TYPE_MIRROR "mirror" #define VDEV_TYPE_REPLACING "replacing" #define VDEV_TYPE_RAIDZ "raidz" #define VDEV_TYPE_DISK "disk" #define VDEV_TYPE_FILE "file" #define VDEV_TYPE_MISSING "missing" #define VDEV_TYPE_HOLE "hole" #define VDEV_TYPE_SPARE "spare" #define VDEV_TYPE_L2CACHE "l2cache" /* * pool state. The following states are written to disk as part of the normal * SPA lifecycle: ACTIVE, EXPORTED, DESTROYED, SPARE, L2CACHE. The remaining * states are software abstractions used at various levels to communicate pool * state. */ typedef enum pool_state { POOL_STATE_ACTIVE = 0, /* In active use */ POOL_STATE_EXPORTED, /* Explicitly exported */ POOL_STATE_DESTROYED, /* Explicitly destroyed */ POOL_STATE_SPARE, /* Reserved for hot spare use */ POOL_STATE_L2CACHE, /* Level 2 ARC device */ POOL_STATE_UNINITIALIZED, /* Internal spa_t state */ POOL_STATE_UNAVAIL, /* Internal libzfs state */ POOL_STATE_POTENTIALLY_ACTIVE /* Internal libzfs state */ } pool_state_t; struct grub_zfs_data; grub_err_t grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist); grub_err_t grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, grub_uint64_t *mdnobj); char *grub_zfs_nvlist_lookup_string (char *nvlist, char *name); char *grub_zfs_nvlist_lookup_nvlist (char *nvlist, char *name); int grub_zfs_nvlist_lookup_uint64 (char *nvlist, char *name, grub_uint64_t *out); char *grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, grub_size_t index); int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name); #endif /* ! GRUB_ZFS_HEADER */ debian/grub-extras/disabled/zfs/include/grub/zfs/dnode.h0000664000000000000000000000562412524662415020450 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DNODE_H #define _SYS_DNODE_H #include /* * Fixed constants. */ #define DNODE_SHIFT 9 /* 512 bytes */ #define DN_MIN_INDBLKSHIFT 10 /* 1k */ #define DN_MAX_INDBLKSHIFT 14 /* 16k */ #define DNODE_BLOCK_SHIFT 14 /* 16k */ #define DNODE_CORE_SIZE 64 /* 64 bytes for dnode sans blkptrs */ #define DN_MAX_OBJECT_SHIFT 48 /* 256 trillion (zfs_fid_t limit) */ #define DN_MAX_OFFSET_SHIFT 64 /* 2^64 bytes in a dnode */ /* * Derived constants. */ #define DNODE_SIZE (1 << DNODE_SHIFT) #define DN_MAX_NBLKPTR ((DNODE_SIZE - DNODE_CORE_SIZE) >> SPA_BLKPTRSHIFT) #define DN_MAX_BONUSLEN (DNODE_SIZE - DNODE_CORE_SIZE - (1 << SPA_BLKPTRSHIFT)) #define DN_MAX_OBJECT (1ULL << DN_MAX_OBJECT_SHIFT) #define DNODES_PER_BLOCK_SHIFT (DNODE_BLOCK_SHIFT - DNODE_SHIFT) #define DNODES_PER_BLOCK (1ULL << DNODES_PER_BLOCK_SHIFT) #define DNODES_PER_LEVEL_SHIFT (DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT) #define DNODE_FLAG_SPILL_BLKPTR (1<<2) #define DN_BONUS(dnp) ((void*)((dnp)->dn_bonus + \ (((dnp)->dn_nblkptr - 1) * sizeof (blkptr_t)))) typedef struct dnode_phys { grub_uint8_t dn_type; /* dmu_object_type_t */ grub_uint8_t dn_indblkshift; /* ln2(indirect block size) */ grub_uint8_t dn_nlevels; /* 1=dn_blkptr->data blocks */ grub_uint8_t dn_nblkptr; /* length of dn_blkptr */ grub_uint8_t dn_bonustype; /* type of data in bonus buffer */ grub_uint8_t dn_checksum; /* ZIO_CHECKSUM type */ grub_uint8_t dn_compress; /* ZIO_COMPRESS type */ grub_uint8_t dn_flags; /* DNODE_FLAG_* */ grub_uint16_t dn_datablkszsec; /* data block size in 512b sectors */ grub_uint16_t dn_bonuslen; /* length of dn_bonus */ grub_uint8_t dn_pad2[4]; /* accounting is protected by dn_dirty_mtx */ grub_uint64_t dn_maxblkid; /* largest allocated block ID */ grub_uint64_t dn_used; /* bytes (or sectors) of disk space */ grub_uint64_t dn_pad3[4]; blkptr_t dn_blkptr[1]; grub_uint8_t dn_bonus[DN_MAX_BONUSLEN - sizeof (blkptr_t)]; blkptr_t dn_spill; } dnode_phys_t; #endif /* _SYS_DNODE_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/dmu_objset.h0000664000000000000000000000274312524662415021511 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * Copyright (C) 2010 Robert Millan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DMU_OBJSET_H #define _SYS_DMU_OBJSET_H #include #define OBJSET_PHYS_SIZE 2048 #define OBJSET_PHYS_SIZE_V14 1024 typedef struct objset_phys { dnode_phys_t os_meta_dnode; zil_header_t os_zil_header; grub_uint64_t os_type; grub_uint64_t os_flags; char os_pad[OBJSET_PHYS_SIZE - sizeof (dnode_phys_t)*3 - sizeof (zil_header_t) - sizeof (grub_uint64_t)*2]; dnode_phys_t os_userused_dnode; dnode_phys_t os_groupused_dnode; } objset_phys_t; #endif /* _SYS_DMU_OBJSET_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/zap_leaf.h0000664000000000000000000000665312524662415021143 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_ZAP_LEAF_H #define _SYS_ZAP_LEAF_H #define ZAP_LEAF_MAGIC 0x2AB1EAF /* chunk size = 24 bytes */ #define ZAP_LEAF_CHUNKSIZE 24 /* * The amount of space within the chunk available for the array is: * chunk size - space for type (1) - space for next pointer (2) */ #define ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3) typedef enum zap_chunk_type { ZAP_CHUNK_FREE = 253, ZAP_CHUNK_ENTRY = 252, ZAP_CHUNK_ARRAY = 251, ZAP_CHUNK_TYPE_MAX = 250 } zap_chunk_type_t; /* * TAKE NOTE: * If zap_leaf_phys_t is modified, zap_leaf_byteswap() must be modified. */ typedef struct zap_leaf_phys { struct zap_leaf_header { grub_uint64_t lh_block_type; /* ZBT_LEAF */ grub_uint64_t lh_pad1; grub_uint64_t lh_prefix; /* hash prefix of this leaf */ grub_uint32_t lh_magic; /* ZAP_LEAF_MAGIC */ grub_uint16_t lh_nfree; /* number free chunks */ grub_uint16_t lh_nentries; /* number of entries */ grub_uint16_t lh_prefix_len; /* num bits used to id this */ /* above is accessable to zap, below is zap_leaf private */ grub_uint16_t lh_freelist; /* chunk head of free list */ grub_uint8_t lh_pad2[12]; } l_hdr; /* 2 24-byte chunks */ /* * The header is followed by a hash table with * ZAP_LEAF_HASH_NUMENTRIES(zap) entries. The hash table is * followed by an array of ZAP_LEAF_NUMCHUNKS(zap) * zap_leaf_chunk structures. These structures are accessed * with the ZAP_LEAF_CHUNK() macro. */ grub_uint16_t l_hash[1]; } zap_leaf_phys_t; typedef union zap_leaf_chunk { struct zap_leaf_entry { grub_uint8_t le_type; /* always ZAP_CHUNK_ENTRY */ grub_uint8_t le_int_size; /* size of ints */ grub_uint16_t le_next; /* next entry in hash chain */ grub_uint16_t le_name_chunk; /* first chunk of the name */ grub_uint16_t le_name_length; /* bytes in name, incl null */ grub_uint16_t le_value_chunk; /* first chunk of the value */ grub_uint16_t le_value_length; /* value length in ints */ grub_uint32_t le_cd; /* collision differentiator */ grub_uint64_t le_hash; /* hash value of the name */ } l_entry; struct zap_leaf_array { grub_uint8_t la_type; /* always ZAP_CHUNK_ARRAY */ union { grub_uint8_t la_array[ZAP_LEAF_ARRAY_BYTES]; grub_uint64_t la_array64; }; grub_uint16_t la_next; /* next blk or CHAIN_END */ } l_array; struct zap_leaf_free { grub_uint8_t lf_type; /* always ZAP_CHUNK_FREE */ grub_uint8_t lf_pad[ZAP_LEAF_ARRAY_BYTES]; grub_uint16_t lf_next; /* next in free list, or CHAIN_END */ } l_free; } zap_leaf_chunk_t; #endif /* _SYS_ZAP_LEAF_H */ debian/grub-extras/disabled/zfs/include/grub/zfs/zfs_acl.h0000664000000000000000000000406512524662415020776 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_FS_ZFS_ACL_H #define _SYS_FS_ZFS_ACL_H #ifndef _UID_T #define _UID_T typedef unsigned int uid_t; /* UID type */ #endif /* _UID_T */ typedef struct zfs_oldace { grub_uint32_t z_fuid; /* "who" */ grub_uint32_t z_access_mask; /* access mask */ grub_uint16_t z_flags; /* flags, i.e inheritance */ grub_uint16_t z_type; /* type of entry allow/deny */ } zfs_oldace_t; #define ACE_SLOT_CNT 6 typedef struct zfs_znode_acl_v0 { grub_uint64_t z_acl_extern_obj; /* ext acl pieces */ grub_uint32_t z_acl_count; /* Number of ACEs */ grub_uint16_t z_acl_version; /* acl version */ grub_uint16_t z_acl_pad; /* pad */ zfs_oldace_t z_ace_data[ACE_SLOT_CNT]; /* 6 standard ACEs */ } zfs_znode_acl_v0_t; #define ZFS_ACE_SPACE (sizeof (zfs_oldace_t) * ACE_SLOT_CNT) typedef struct zfs_znode_acl { grub_uint64_t z_acl_extern_obj; /* ext acl pieces */ grub_uint32_t z_acl_size; /* Number of bytes in ACL */ grub_uint16_t z_acl_version; /* acl version */ grub_uint16_t z_acl_count; /* ace count */ grub_uint8_t z_ace_data[ZFS_ACE_SPACE]; /* space for embedded ACEs */ } zfs_znode_acl_t; #endif /* _SYS_FS_ZFS_ACL_H */ debian/grub-extras/disabled/zfs/zfs_fletcher.c0000664000000000000000000000526312524662415016643 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * Copyright 2007 Sun Microsystems, Inc. * Copyright (C) 2009 Vladimir Serbinenko * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void fletcher_2(const void *buf, grub_uint64_t size, grub_zfs_endian_t endian, zio_cksum_t *zcp) { const grub_uint64_t *ip = buf; const grub_uint64_t *ipend = ip + (size / sizeof (grub_uint64_t)); grub_uint64_t a0, b0, a1, b1; for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) { a0 += grub_zfs_to_cpu64 (ip[0], endian); a1 += grub_zfs_to_cpu64 (ip[1], endian); b0 += a0; b1 += a1; } zcp->zc_word[0] = grub_cpu_to_zfs64 (a0, endian); zcp->zc_word[1] = grub_cpu_to_zfs64 (a1, endian); zcp->zc_word[2] = grub_cpu_to_zfs64 (b0, endian); zcp->zc_word[3] = grub_cpu_to_zfs64 (b1, endian); } void fletcher_4 (const void *buf, grub_uint64_t size, grub_zfs_endian_t endian, zio_cksum_t *zcp) { const grub_uint32_t *ip = buf; const grub_uint32_t *ipend = ip + (size / sizeof (grub_uint32_t)); grub_uint64_t a, b, c, d; for (a = b = c = d = 0; ip < ipend; ip++) { a += grub_zfs_to_cpu32 (ip[0], endian);; b += a; c += b; d += c; } zcp->zc_word[0] = grub_cpu_to_zfs64 (a, endian); zcp->zc_word[1] = grub_cpu_to_zfs64 (b, endian); zcp->zc_word[2] = grub_cpu_to_zfs64 (c, endian); zcp->zc_word[3] = grub_cpu_to_zfs64 (d, endian); } debian/grub-extras/disabled/zfs/zfs_sha256.c0000664000000000000000000001161312524662415016053 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * Copyright 2007 Sun Microsystems, Inc. * Copyright (C) 2009 Vladimir Serbinenko * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * SHA-256 checksum, as specified in FIPS 180-2, available at: * http://csrc.nist.gov/cryptval * * This is a very compact implementation of SHA-256. * It is designed to be simple and portable, not to be fast. */ /* * The literal definitions according to FIPS180-2 would be: * * Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) * Maj(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) * * We use logical equivalents which require one less op. */ #define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) #define Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y)))) #define Rot32(x, s) (((x) >> s) | ((x) << (32 - s))) #define SIGMA0(x) (Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22)) #define SIGMA1(x) (Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25)) #define sigma0(x) (Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) >> 3)) #define sigma1(x) (Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) >> 10)) static const grub_uint32_t SHA256_K[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; static void SHA256Transform(grub_uint32_t *H, const grub_uint8_t *cp) { grub_uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64]; for (t = 0; t < 16; t++, cp += 4) W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3]; for (t = 16; t < 64; t++) W[t] = sigma1(W[t - 2]) + W[t - 7] + sigma0(W[t - 15]) + W[t - 16]; a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7]; for (t = 0; t < 64; t++) { T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t]; T2 = SIGMA0(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; } H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; H[5] += f; H[6] += g; H[7] += h; } void zio_checksum_SHA256(const void *buf, grub_uint64_t size, grub_zfs_endian_t endian, zio_cksum_t *zcp) { grub_uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; grub_uint8_t pad[128]; unsigned padsize = size & 63; unsigned i; for (i = 0; i < size - padsize; i += 64) SHA256Transform(H, (grub_uint8_t *)buf + i); for (i = 0; i < padsize; i++) pad[i] = ((grub_uint8_t *)buf)[i]; for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++) pad[padsize] = 0; for (i = 0; i < 8; i++) pad[padsize++] = (size << 3) >> (56 - 8 * i); for (i = 0; i < padsize; i += 64) SHA256Transform(H, pad + i); zcp->zc_word[0] = grub_cpu_to_zfs64 ((grub_uint64_t)H[0] << 32 | H[1], endian); zcp->zc_word[1] = grub_cpu_to_zfs64 ((grub_uint64_t)H[2] << 32 | H[3], endian); zcp->zc_word[2] = grub_cpu_to_zfs64 ((grub_uint64_t)H[4] << 32 | H[5], endian); zcp->zc_word[3] = grub_cpu_to_zfs64 ((grub_uint64_t)H[6] << 32 | H[7], endian); } debian/grub-extras/disabled/zfs/Makefile.util.def0000664000000000000000000000036712524662415017172 0ustar AutoGen definitions Makefile.tpl; library = { name = libgrubmods.a; common = contrib/zfs/zfs.c; common = contrib/zfs/zfs_lzjb.c; common = contrib/zfs/zfs_sha256.c; common = contrib/zfs/zfs_fletcher.c; cppflags = '$(ZFS_CPPFLAGS)'; }; debian/grub-extras/disabled/zfs/zfsinfo.c0000664000000000000000000002272312524662415015643 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * Copyright 2008 Sun Microsystems, Inc. * Copyright (C) 2009 Vladimir Serbinenko * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include static inline void print_tabs (int n) { int i; for (i = 0; i < n; i++) grub_printf (" "); } static grub_err_t print_state (char *nvlist, int tab) { grub_uint64_t ival; int isok = 1; print_tabs (tab); grub_printf ("State: "); if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_REMOVED, &ival)) { grub_printf ("removed "); isok = 0; } if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival)) { grub_printf ("faulted "); isok = 0; } if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_OFFLINE, &ival)) { grub_printf ("offline "); isok = 0; } if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival)) grub_printf ("degraded "); if (isok) grub_printf ("online"); grub_printf ("\n"); return GRUB_ERR_NONE; } static grub_err_t print_vdev_info (char *nvlist, int tab) { char *type = 0; type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE); if (!type) { print_tabs (tab); grub_printf ("Incorrect VDEV: no type available\n"); return grub_errno; } if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) { char *bootpath = 0; char *path = 0; char *devid = 0; print_tabs (tab); grub_printf ("Leaf VDEV\n"); print_state (nvlist, tab); bootpath = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_PHYS_PATH); print_tabs (tab); if (!bootpath) grub_printf ("Bootpath: unavailable\n"); else grub_printf ("Bootpath: %s\n", bootpath); path = grub_zfs_nvlist_lookup_string (nvlist, "path"); print_tabs (tab); if (!path) grub_printf ("Path: unavailable\n"); else grub_printf ("Path: %s\n", path); devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID); print_tabs (tab); if (!devid) grub_printf ("Devid: unavailable\n"); else grub_printf ("Devid: %s\n", devid); grub_free (bootpath); grub_free (devid); grub_free (path); return GRUB_ERR_NONE; } if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) { int nelm, i; nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, ZPOOL_CONFIG_CHILDREN); print_tabs (tab); if (nelm <= 0) { grub_printf ("Incorrect mirror VDEV\n"); return GRUB_ERR_NONE; } grub_printf ("Mirror VDEV with %d children\n", nelm); print_state (nvlist, tab); for (i = 0; i < nelm; i++) { char *child; child = grub_zfs_nvlist_lookup_nvlist_array (nvlist, ZPOOL_CONFIG_CHILDREN, i); print_tabs (tab); if (!child) { grub_printf ("Mirror VDEV element %d isn't correct\n", i); continue; } grub_printf ("Mirror VDEV element %d:\n", i); print_vdev_info (child, tab + 1); grub_free (child); } } print_tabs (tab); grub_printf ("Unknown VDEV type: %s\n", type); return GRUB_ERR_NONE; } static grub_err_t get_bootpath (char *nvlist, char **bootpath, char **devid) { char *type = 0; type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE); if (!type) return grub_errno; if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) { *bootpath = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_PHYS_PATH); *devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID); if (!*bootpath || !*devid) { grub_free (*bootpath); grub_free (*devid); *bootpath = 0; *devid = 0; } return GRUB_ERR_NONE; } if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) { int nelm, i; nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, ZPOOL_CONFIG_CHILDREN); for (i = 0; i < nelm; i++) { char *child; child = grub_zfs_nvlist_lookup_nvlist_array (nvlist, ZPOOL_CONFIG_CHILDREN, i); get_bootpath (child, bootpath, devid); grub_free (child); if (*bootpath && *devid) return GRUB_ERR_NONE; } } return GRUB_ERR_NONE; } static char *poolstates[] = { [POOL_STATE_ACTIVE] = "active", [POOL_STATE_EXPORTED] = "exported", [POOL_STATE_DESTROYED] = "destroyed", [POOL_STATE_SPARE] = "reserved for hot spare", [POOL_STATE_L2CACHE] = "level 2 ARC device", [POOL_STATE_UNINITIALIZED] = "uninitialized", [POOL_STATE_UNAVAIL] = "unavailable", [POOL_STATE_POTENTIALLY_ACTIVE] = "potentially active" }; static grub_err_t grub_cmd_zfsinfo (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_device_t dev; char *devname; grub_err_t err; char *nvlist = 0; char *nv = 0; char *poolname; grub_uint64_t guid; grub_uint64_t pool_state; int found; if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')') { devname = grub_strdup (args[0] + 1); if (devname) devname[grub_strlen (devname) - 1] = 0; } else devname = grub_strdup (args[0]); if (!devname) return grub_errno; dev = grub_device_open (devname); grub_free (devname); if (!dev) return grub_errno; err = grub_zfs_fetch_nvlist (dev, &nvlist); grub_device_close (dev); if (err) return err; poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); if (!poolname) grub_printf ("Pool name: unavailable\n"); else grub_printf ("Pool name: %s\n", poolname); found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, &guid); if (!found) grub_printf ("Pool GUID: unavailable\n"); else grub_printf ("Pool GUID: %016llx\n", (long long unsigned) guid); found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, &pool_state); if (!found) grub_printf ("Unable to retrieve pool state\n"); else if (pool_state >= ARRAY_SIZE (poolstates)) grub_printf ("Unrecognized pool state\n"); else grub_printf ("Pool state: %s\n", poolstates[pool_state]); nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); if (!nv) grub_printf ("No vdev tree available\n"); else print_vdev_info (nv, 1); grub_free (nv); grub_free (nvlist); return GRUB_ERR_NONE; } static grub_err_t grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_device_t dev; char *devname; grub_err_t err; char *nvlist = 0; char *nv = 0; char *bootpath = 0, *devid = 0; char *fsname; char *bootfs; char *poolname; grub_uint64_t mdnobj; if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "filesystem name required"); devname = grub_file_get_device_name (args[0]); if (grub_errno) return grub_errno; dev = grub_device_open (devname); grub_free (devname); if (!dev) return grub_errno; err = grub_zfs_fetch_nvlist (dev, &nvlist); fsname = grub_strchr (args[0], ')'); if (fsname) fsname++; else fsname = args[0]; if (!err) err = grub_zfs_getmdnobj (dev, fsname, &mdnobj); grub_device_close (dev); if (err) return err; poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); if (!poolname) { if (!grub_errno) grub_error (GRUB_ERR_BAD_FS, "No poolname found"); return grub_errno; } nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); if (nv) get_bootpath (nv, &bootpath, &devid); grub_free (nv); grub_free (nvlist); if (bootpath && devid) { bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu bootpath=%s diskdevid=%s", poolname, (unsigned long long) mdnobj, bootpath, devid); if (!bootfs) return grub_errno; } else { bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu", poolname, (unsigned long long) mdnobj); if (!bootfs) return grub_errno; } if (argc >= 2) grub_env_set (args[1], bootfs); else grub_printf ("%s\n", bootfs); grub_free (bootfs); grub_free (poolname); grub_free (bootpath); grub_free (devid); return GRUB_ERR_NONE; } static grub_command_t cmd_info, cmd_bootfs; GRUB_MOD_INIT (zfsinfo) { cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo, "zfsinfo DEVICE", "Print ZFS info about DEVICE."); cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs, "zfs-bootfs FILESYSTEM [VARIABLE]", "Print ZFS-BOOTFSOBJ or set it to VARIABLE"); } GRUB_MOD_FINI (zfsinfo) { grub_unregister_command (cmd_info); grub_unregister_command (cmd_bootfs); } debian/grub-extras/disabled/zfs/README0000664000000000000000000000043612524662415014676 0ustar grub-extras is meant to be used as an overlay on grub2 source tree. Build instructions: - Copy grub-extras in a subdirectory of your grub2 checkout. For example, "grub-extras". - Export GRUB_CONTRIB environment variable to point to this directory. - Build GRUB as usual. debian/grub-extras/disabled/zfs/COPYING0000664000000000000000000010451312524662415015052 0ustar GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . debian/grub-extras/disabled/zfs/Makefile.core.def0000664000000000000000000000051712524662415017142 0ustar AutoGen definitions Makefile.tpl; module = { name = zfs; common = contrib/zfs/zfs.c; common = contrib/zfs/zfs_lzjb.c; common = contrib/zfs/zfs_sha256.c; common = contrib/zfs/zfs_fletcher.c; cppflags = '$(ZFS_CPPFLAGS)'; }; module = { name = zfsinfo; common = contrib/zfs/zfsinfo.c; cppflags = '$(ZFS_CPPFLAGS)'; }; debian/grub-extras/disabled/gpxe/0000775000000000000000000000000012524676037014161 5ustar debian/grub-extras/disabled/gpxe/include_wrap/0000775000000000000000000000000012524676037016635 5ustar debian/grub-extras/disabled/gpxe/include_wrap/config/0000775000000000000000000000000012524676037020102 5ustar debian/grub-extras/disabled/gpxe/include_wrap/config/ioapi.h0000664000000000000000000000002712524662415021346 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/ctype.h0000664000000000000000000000002712524662415020124 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/limits.h0000664000000000000000000000002712524662415020301 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/stdlib.h0000664000000000000000000000002712524662415020261 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/string.h0000664000000000000000000000002712524662415020306 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/libgen.h0000664000000000000000000000002712524662415020240 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/strings.h0000664000000000000000000000002712524662415020471 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/stdio.h0000664000000000000000000000002712524662415020122 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/console.h0000664000000000000000000000002712524662415020442 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/stddef.h0000664000000000000000000000002712524662415020251 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/bits/0000775000000000000000000000000012524676037017576 5ustar debian/grub-extras/disabled/gpxe/include_wrap/bits/uaccess.h0000664000000000000000000000002712524662415021367 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/bits/errfile.h0000664000000000000000000000002712524662415021371 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/assert.h0000664000000000000000000000002712524662415020301 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/errno.h0000664000000000000000000004177012524662415020137 0ustar #ifndef ERRNO_H #define ERRNO_H FILE_LICENCE ( GPL2_OR_LATER ); /** @file * * Error codes * * Return status codes as used within gPXE are designed to allow for * maximum visibility into the source of an error even in an end-user * build with no debugging. They are constructed as follows: * * Bits 7-0 : PXE error code * * This is the closest equivalent PXE error code * (e.g. PXENV_STATUS_OUT_OF_RESOURCES), and is the only part of the * error that will be returned via the PXE API, since PXE has * predefined error codes. * * Bits 12-8 : Per-file disambiguator * * When the same error number can be generated from multiple points * within a file, this field can be used to identify the unique * instance. * * Bits 23-13 : File identifier * * This is a unique identifier for the file generating the error * (e.g. ERRFILE_tcp for tcp.c). * * Bits 30-24 : POSIX error code * * This is the closest equivalent POSIX error code (e.g. ENOMEM). * * Bit 31 : Reserved * * Errors are usually return as negative error numbers (e.g. -EINVAL); * bit 31 is therefore unusable. * * * The convention within the code is that errors are negative and * expressed using the POSIX error code and (optionally) a per-file * disambiguator, e.g. * * return -EINVAL; * * or * * #define ETCP_BAD_CHECKSUM EUNIQ_02 * return -( EINVAL | ETCP_BAD_CHECKSUM ) * * By various bits of preprocessor magic, the PXE error code and file * identifier are already incorporated into the definition of the * POSIX error code, which keeps the code relatively clean. * * * Functions that wish to return failures should be declared as * returning an integer @c rc "Return status code". A return value of * zero indicates success, a non-zero value indicates failure. The * return value can be passed directly to strerror() in order to * generate a human-readable error message, e.g. * * if ( ( rc = some_function ( ... ) ) != 0 ) { * DBG ( "Whatever I was trying to do failed: %s\n", strerror ( rc ) ); * return rc; * } * * As illustrated in the above example, error returns should generally * be directly propagated upward to the calling function. * */ /* Get definitions for file identifiers */ #include /* If we do not have a valid file identifier, generate a compiler * warning upon usage of any error codes. (Don't just use a #warning, * because some files include errno.h but don't ever actually use any * error codes.) */ extern char missing_errfile_declaration[] __attribute__ (( deprecated )); #undef ERRFILE #define ERRFILE ( 0 * ( ( int ) missing_errfile_declaration ) ) /** Derive PXENV_STATUS code from gPXE error number */ #define PXENV_STATUS( rc ) ( (-(rc)) & 0x00ff ) /** * @defgroup pxeerrors PXE error codes * * The names, meanings and values of these error codes are defined by * the PXE specification. * * @{ */ /* Generic errors */ #define PXENV_STATUS_SUCCESS 0x0000 #define PXENV_STATUS_FAILURE 0x0001 #define PXENV_STATUS_BAD_FUNC 0x0002 #define PXENV_STATUS_UNSUPPORTED 0x0003 #define PXENV_STATUS_KEEP_UNDI 0x0004 #define PXENV_STATUS_KEEP_ALL 0x0005 #define PXENV_STATUS_OUT_OF_RESOURCES 0x0006 /* ARP errors (0x0010 to 0x001f) */ #define PXENV_STATUS_ARP_TIMEOUT 0x0011 /* Base-Code state errors */ #define PXENV_STATUS_UDP_CLOSED 0x0018 #define PXENV_STATUS_UDP_OPEN 0x0019 #define PXENV_STATUS_TFTP_CLOSED 0x001a #define PXENV_STATUS_TFTP_OPEN 0x001b /* BIOS/system errors (0x0020 to 0x002f) */ #define PXENV_STATUS_MCOPY_PROBLEM 0x0020 #define PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x0021 #define PXENV_STATUS_BIS_VALIDATE_FAILURE 0x0022 #define PXENV_STATUS_BIS_INIT_FAILURE 0x0023 #define PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x0024 #define PXENV_STATUS_BIS_GBOA_FAILURE 0x0025 #define PXENV_STATUS_BIS_FREE_FAILURE 0x0026 #define PXENV_STATUS_BIS_GSI_FAILURE 0x0027 #define PXENV_STATUS_BIS_BAD_CKSUM 0x0028 /* TFTP/MTFTP errors (0x0030 to 0x003f) */ #define PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x0030 #define PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x0032 #define PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x0033 #define PXENV_STATUS_TFTP_READ_TIMEOUT 0x0035 #define PXENV_STATUS_TFTP_ERROR_OPCODE 0x0036 #define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x0038 #define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x0039 #define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x003a #define PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x003b #define PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x003c #define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x003d #define PXENV_STATUS_TFTP_NO_FILESIZE 0x003e #define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x003f /* Reserved errors 0x0040 to 0x004f) */ /* DHCP/BOOTP errors (0x0050 to 0x005f) */ #define PXENV_STATUS_DHCP_TIMEOUT 0x0051 #define PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x0052 #define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x0053 #define PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x0054 /* Driver errors (0x0060 to 0x006f) */ #define PXENV_STATUS_UNDI_INVALID_FUNCTION 0x0060 #define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x0061 #define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x0062 #define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x0063 #define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x0064 #define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x0065 #define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x0066 #define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x0067 #define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x0068 #define PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x0069 #define PXENV_STATUS_UNDI_INVALID_STATE 0x006a #define PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x006b #define PXENV_STATUS_UNDI_INVALID_PARAMETER 0x006c /* ROM and NBP bootstrap errors (0x0070 to 0x007f) */ #define PXENV_STATUS_BSTRAP_PROMPT_MENU 0x0074 #define PXENV_STATUS_BSTRAP_MCAST_ADDR 0x0076 #define PXENV_STATUS_BSTRAP_MISSING_LIST 0x0077 #define PXENV_STATUS_BSTRAP_NO_RESPONSE 0x0078 #define PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x0079 /* Environment NBP errors (0x0080 to 0x008f) */ /* Reserved errors (0x0090 to 0x009f) */ /* Miscellaneous errors (0x00a0 to 0x00af) */ #define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0x00a0 #define PXENV_STATUS_BINL_NO_PXE_SERVER 0x00a1 #define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0x00a2 #define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0x00a3 /* BUSD errors (0x00b0 to 0x00bf) */ #define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0x00b0 /* Loader errors (0x00c0 to 0x00cf) */ #define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0x00c0 #define PXENV_STATUS_LOADER_NO_BC_ROMID 0x00c1 #define PXENV_STATUS_LOADER_BAD_BC_ROMID 0x00c2 #define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0x00c3 #define PXENV_STATUS_LOADER_NO_UNDI_ROMID 0x00c4 #define PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0x00c5 #define PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0x00c6 #define PXENV_STATUS_LOADER_NO_PXE_STRUCT 0x00c8 #define PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0x00c9 #define PXENV_STATUS_LOADER_UNDI_START 0x00ca #define PXENV_STATUS_LOADER_BC_START 0x00cb /** @} */ /** * @defgroup posixerrors POSIX error codes * * The names and meanings (but not the values) of these error codes * are defined by POSIX. We choose to assign unique values which * incorporate the closest equivalent PXE error code, so that code may * simply use ENOMEM, rather than having to use the cumbersome * (ENOMEM|PXENV_STATUS_OUT_OF_RESOURCES). * * @{ */ /** Operation completed successfully */ #define ENOERR ( ERRFILE | PXENV_STATUS_SUCCESS | 0x00000000 ) /** Arg list too long */ #define E2BIG ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x01000000 ) /** Permission denied */ #define EACCES ( ERRFILE | PXENV_STATUS_TFTP_ACCESS_VIOLATION | 0x02000000 ) /** Address in use */ #define EADDRINUSE ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x03000000 ) /** Address not available */ #define EADDRNOTAVAIL ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x04000000 ) /** Address family not supported */ #define EAFNOSUPPORT ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x05000000 ) /** Resource temporarily unavailable */ #define EAGAIN ( ERRFILE | PXENV_STATUS_FAILURE | 0x06000000 ) /** Connection already in progress */ #define EALREADY ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x07000000 ) /** Bad file descriptor */ #define EBADF ( ERRFILE | PXENV_STATUS_TFTP_CLOSED | 0x08000000 ) /** Bad message */ #define EBADMSG ( ERRFILE | PXENV_STATUS_FAILURE | 0x09000000 ) /** Resource busy */ #define EBUSY ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x0a000000 ) /** Operation canceled */ #define ECANCELED \ ( ERRFILE | PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE | 0x0b000000 ) /** No child processes */ #define ECHILD ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x0c000000 ) /** Connection aborted */ #define ECONNABORTED \ ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION | 0x0d000000 ) /** Connection refused */ #define ECONNREFUSED \ ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION | 0x0e000000 ) /** Connection reset */ #define ECONNRESET \ ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION | 0x0f000000 ) /** Resource deadlock avoided */ #define EDEADLK ( ERRFILE | PXENV_STATUS_FAILURE | 0x10000000 ) /** Destination address required */ #define EDESTADDRREQ ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x11000000 ) /** Domain error */ #define EDOM ( ERRFILE | PXENV_STATUS_FAILURE | 0x12000000 ) /** Reserved */ #define EDQUOT ( ERRFILE | PXENV_STATUS_FAILURE | 0x13000000 ) /** File exists */ #define EEXIST ( ERRFILE | PXENV_STATUS_FAILURE | 0x14000000 ) /** Bad address */ #define EFAULT ( ERRFILE | PXENV_STATUS_MCOPY_PROBLEM | 0x15000000 ) /** File too large */ #define EFBIG ( ERRFILE | PXENV_STATUS_MCOPY_PROBLEM | 0x16000000 ) /** Host is unreachable */ #define EHOSTUNREACH ( ERRFILE | PXENV_STATUS_ARP_TIMEOUT | 0x17000000 ) /** Identifier removed */ #define EIDRM ( ERRFILE | PXENV_STATUS_FAILURE | 0x18000000 ) /** Illegal byte sequence */ #define EILSEQ ( ERRFILE | PXENV_STATUS_FAILURE | 0x19000000 ) /** Operation in progress */ #define EINPROGRESS ( ERRFILE | PXENV_STATUS_FAILURE | 0x1a000000 ) /** Interrupted function call */ #define EINTR ( ERRFILE | PXENV_STATUS_FAILURE | 0x1b000000 ) /** Invalid argument */ #define EINVAL ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x1c000000 ) /** Input/output error */ #define EIO \ ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION | 0x1d000000 ) /** Socket is connected */ #define EISCONN ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x1e000000 ) /** Is a directory */ #define EISDIR ( ERRFILE | PXENV_STATUS_FAILURE | 0x1f000000 ) /** Too many levels of symbolic links */ #define ELOOP ( ERRFILE | PXENV_STATUS_FAILURE | 0x20000000 ) /** Too many open files */ #define EMFILE ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x21000000 ) /** Too many links */ #define EMLINK ( ERRFILE | PXENV_STATUS_FAILURE | 0x22000000 ) /** Inappropriate message buffer length */ #define EMSGSIZE ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x23000000 ) /** Reserved */ #define EMULTIHOP ( ERRFILE | PXENV_STATUS_FAILURE | 0x24000000 ) /** Filename too long */ #define ENAMETOOLONG ( ERRFILE | PXENV_STATUS_FAILURE | 0x25000000 ) /** Network is down */ #define ENETDOWN ( ERRFILE | PXENV_STATUS_ARP_TIMEOUT | 0x26000000 ) /** Connection aborted by network */ #define ENETRESET ( ERRFILE | PXENV_STATUS_FAILURE | 0x27000000 ) /** Network unreachable */ #define ENETUNREACH ( ERRFILE | PXENV_STATUS_ARP_TIMEOUT | 0x28000000 ) /** Too many open files in system */ #define ENFILE ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x29000000 ) /** No buffer space available */ #define ENOBUFS ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x2a000000 ) /** No message is available on the STREAM head read queue */ #define ENODATA ( ERRFILE | PXENV_STATUS_FAILURE | 0x2b000000 ) /** No such device */ #define ENODEV ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x2c000000 ) /** No such file or directory */ #define ENOENT ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x2d000000 ) /** Exec format error */ #define ENOEXEC ( ERRFILE | PXENV_STATUS_FAILURE | 0x2e000000 ) /** No locks available */ #define ENOLCK ( ERRFILE | PXENV_STATUS_FAILURE | 0x2f000000 ) /** Reserved */ #define ENOLINK ( ERRFILE | PXENV_STATUS_FAILURE | 0x30000000 ) /** Not enough space */ #define ENOMEM ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x31000000 ) /** No message of the desired type */ #define ENOMSG ( ERRFILE | PXENV_STATUS_FAILURE | 0x32000000 ) /** Protocol not available */ #define ENOPROTOOPT ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x33000000 ) /** No space left on device */ #define ENOSPC ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x34000000 ) /** No STREAM resources */ #define ENOSR ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x35000000 ) /** Not a STREAM */ #define ENOSTR ( ERRFILE | PXENV_STATUS_FAILURE | 0x36000000 ) /** Function not implemented */ #define ENOSYS ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x37000000 ) /** The socket is not connected */ #define ENOTCONN ( ERRFILE | PXENV_STATUS_FAILURE | 0x38000000 ) /** Not a directory */ #define ENOTDIR ( ERRFILE | PXENV_STATUS_FAILURE | 0x39000000 ) /** Directory not empty */ #define ENOTEMPTY ( ERRFILE | PXENV_STATUS_FAILURE | 0x3a000000 ) /** Not a socket */ #define ENOTSOCK ( ERRFILE | PXENV_STATUS_FAILURE | 0x3b000000 ) /** Not supported */ #define ENOTSUP ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x3c000000 ) /** Inappropriate I/O control operation */ #define ENOTTY ( ERRFILE | PXENV_STATUS_FAILURE | 0x3d000000 ) /** No such device or address */ #define ENXIO ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x3e000000 ) /** Operation not supported on socket */ #define EOPNOTSUPP ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x3f000000 ) /** Value too large to be stored in data type */ #define EOVERFLOW ( ERRFILE | PXENV_STATUS_FAILURE | 0x40000000 ) /** Operation not permitted */ #define EPERM ( ERRFILE | PXENV_STATUS_TFTP_ACCESS_VIOLATION | 0x41000000 ) /** Broken pipe */ #define EPIPE ( ERRFILE | PXENV_STATUS_FAILURE | 0x42000000 ) /** Protocol error */ #define EPROTO ( ERRFILE | PXENV_STATUS_FAILURE | 0x43000000 ) /** Protocol not supported */ #define EPROTONOSUPPORT ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x44000000 ) /** Protocol wrong type for socket */ #define EPROTOTYPE ( ERRFILE | PXENV_STATUS_FAILURE | 0x45000000 ) /** Result too large */ #define ERANGE ( ERRFILE | PXENV_STATUS_FAILURE | 0x46000000 ) /** Read-only file system */ #define EROFS ( ERRFILE | PXENV_STATUS_FAILURE | 0x47000000 ) /** Invalid seek */ #define ESPIPE ( ERRFILE | PXENV_STATUS_FAILURE | 0x48000000 ) /** No such process */ #define ESRCH ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x49000000 ) /** Stale file handle */ #define ESTALE ( ERRFILE | PXENV_STATUS_FAILURE | 0x4a000000 ) /** STREAM ioctl() timeout */ #define ETIME ( ERRFILE | PXENV_STATUS_FAILURE | 0x4b000000 ) /** Operation timed out */ #define ETIMEDOUT ( ERRFILE | PXENV_STATUS_TFTP_READ_TIMEOUT | 0x4c000000 ) /** Text file busy */ #define ETXTBSY ( ERRFILE | PXENV_STATUS_FAILURE | 0x4d000000 ) /** Operation would block (different from EAGAIN!) */ #define EWOULDBLOCK ( ERRFILE | PXENV_STATUS_TFTP_OPEN | 0x4e000000 ) /** Improper link */ #define EXDEV ( ERRFILE | PXENV_STATUS_FAILURE | 0x4f000000 ) /** @} */ /** * @defgroup euniq Per-file error disambiguators * * Files which use the same error number multiple times should * probably define their own error subspace using these * disambiguators. For example: * * #define ETCP_HEADER_TOO_SHORT EUNIQ_01 * #define ETCP_BAD_CHECKSUM EUNIQ_02 * * @{ */ #define EUNIQ_01 0x00000100 #define EUNIQ_02 0x00000200 #define EUNIQ_03 0x00000300 #define EUNIQ_04 0x00000400 #define EUNIQ_05 0x00000500 #define EUNIQ_06 0x00000600 #define EUNIQ_07 0x00000700 #define EUNIQ_08 0x00000800 #define EUNIQ_09 0x00000900 #define EUNIQ_0A 0x00000a00 #define EUNIQ_0B 0x00000b00 #define EUNIQ_0C 0x00000c00 #define EUNIQ_0D 0x00000d00 #define EUNIQ_0E 0x00000e00 #define EUNIQ_0F 0x00000f00 #define EUNIQ_10 0x00001000 #define EUNIQ_11 0x00001100 #define EUNIQ_12 0x00001200 #define EUNIQ_13 0x00001300 #define EUNIQ_14 0x00001400 #define EUNIQ_15 0x00001500 #define EUNIQ_16 0x00001600 #define EUNIQ_17 0x00001700 #define EUNIQ_18 0x00001800 #define EUNIQ_19 0x00001900 #define EUNIQ_1A 0x00001a00 #define EUNIQ_1B 0x00001b00 #define EUNIQ_1C 0x00001c00 #define EUNIQ_1D 0x00001d00 #define EUNIQ_1E 0x00001e00 #define EUNIQ_1F 0x00001f00 /** @} */ extern int errno; #endif /* ERRNO_H */ debian/grub-extras/disabled/gpxe/include_wrap/unistd.h0000664000000000000000000000002712524662415020306 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/gpxe/0000775000000000000000000000000012524676037017600 5ustar debian/grub-extras/disabled/gpxe/include_wrap/gpxe/features.h0000664000000000000000000000356012524662415021566 0ustar #ifndef _GPXE_FEATURES_H #define _GPXE_FEATURES_H #include #include #include /** @file * * Feature list * */ FILE_LICENCE ( GPL2_OR_LATER ); /** * @defgroup featurecat Feature categories * @{ */ #define FEATURE_PROTOCOL 01 /**< Network protocols */ #define FEATURE_IMAGE 02 /**< Image formats */ #define FEATURE_MISC 03 /**< Miscellaneous */ /** @} */ /** * @defgroup dhcpfeatures DHCP feature option tags * * DHCP feature option tags are Etherboot encapsulated options in the * range 0x10-0x7f. * * @{ */ #define DHCP_EB_FEATURE_PXE_EXT 0x10 /**< PXE API extensions */ #define DHCP_EB_FEATURE_ISCSI 0x11 /**< iSCSI protocol */ #define DHCP_EB_FEATURE_AOE 0x12 /**< AoE protocol */ #define DHCP_EB_FEATURE_HTTP 0x13 /**< HTTP protocol */ #define DHCP_EB_FEATURE_HTTPS 0x14 /**< HTTPS protocol */ #define DHCP_EB_FEATURE_TFTP 0x15 /**< TFTP protocol */ #define DHCP_EB_FEATURE_FTP 0x16 /**< FTP protocol */ #define DHCP_EB_FEATURE_DNS 0x17 /**< DNS protocol */ #define DHCP_EB_FEATURE_BZIMAGE 0x18 /**< bzImage format */ #define DHCP_EB_FEATURE_MULTIBOOT 0x19 /**< Multiboot format */ #define DHCP_EB_FEATURE_SLAM 0x1a /**< SLAM protocol */ #define DHCP_EB_FEATURE_SRP 0x1b /**< SRP protocol */ #define DHCP_EB_FEATURE_NBI 0x20 /**< NBI format */ #define DHCP_EB_FEATURE_PXE 0x21 /**< PXE format */ #define DHCP_EB_FEATURE_ELF 0x22 /**< ELF format */ #define DHCP_EB_FEATURE_COMBOOT 0x23 /**< COMBOOT format */ #define DHCP_EB_FEATURE_EFI 0x24 /**< EFI format */ /** @} */ /** Construct a DHCP feature table entry */ #define DHCP_FEATURE( feature_opt, ... ) /** Construct a named feature */ #define FEATURE_NAME( category, text ) /** Declare a feature */ #define FEATURE( category, text, feature_opt, version ) /** Declare the version number feature */ #define FEATURE_VERSION( ... ) #endif /* _GPXE_FEATURES_H */ debian/grub-extras/disabled/gpxe/include_wrap/gpxe/timer.h0000664000000000000000000000363212524662415021070 0ustar /* * Copyright © 2009 Vladimir 'phcoder' Serbinenko * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ FILE_LICENCE ( BSD2 ); #ifndef _GPXE_TIMER_H #define _GPXE_TIMER_H #include static inline void udelay ( unsigned long usecs ) { grub_millisleep ((usecs + 999) / 1000); } static inline void mdelay (unsigned delay) { grub_millisleep (delay); } static inline void sleep (unsigned delay) { grub_millisleep (1000 * delay); } static inline unsigned long currticks ( void ) { return grub_get_time_ms (); } #define TICKS_PER_SEC (1000) #define ticks_per_sec() TICKS_PER_SEC #endif /* _GPXE_TIMER_H */ debian/grub-extras/disabled/gpxe/include_wrap/gpxe/pci.h0000664000000000000000000001600412524662415020520 0ustar /* * Copyright © 2009 Vladimir 'phcoder' Serbinenko * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ FILE_LICENCE ( BSD2 ); #ifndef _GPXE_PCI_H #define _GPXE_PCI_H #include #include #include static inline grub_uint8_t inb (grub_uint16_t port) { return grub_inb (GRUB_MACHINE_PCI_IO_BASE + port); } static inline void outb (grub_uint8_t data, grub_uint16_t port) { return grub_outb (data, GRUB_MACHINE_PCI_IO_BASE + port); } static inline void outw (grub_uint16_t data, grub_uint16_t port) { return grub_outw (data, GRUB_MACHINE_PCI_IO_BASE + port); } static inline grub_uint16_t inw (grub_uint16_t port) { return grub_inw (GRUB_MACHINE_PCI_IO_BASE + port); } static inline void insw (grub_uint16_t port, grub_uint16_t *data, int count) { while (count--) *data++ = grub_inw (GRUB_MACHINE_PCI_IO_BASE + port); } static inline void outsw (grub_uint16_t port, grub_uint16_t *data, int count) { while (count--) grub_outw (*data++, GRUB_MACHINE_PCI_IO_BASE + port); } static inline void outsb (grub_uint16_t port, grub_uint8_t *data, int count) { while (count--) grub_outb (*data++, GRUB_MACHINE_PCI_IO_BASE + port); } static inline void insb (grub_uint16_t port, grub_uint8_t *data, int count) { while (count--) *data++ = grub_inb (GRUB_MACHINE_PCI_IO_BASE + port); } static inline void outl (grub_uint32_t data, grub_uint16_t port) { return grub_outw (data, GRUB_MACHINE_PCI_IO_BASE + port); } static inline grub_uint16_t inl (grub_uint32_t port) { return grub_inw (GRUB_MACHINE_PCI_IO_BASE + port); } struct device_description { enum {BUS_TYPE_PCI, BUS_TYPE_ISA} bus_type; int bus; int location; grub_uint16_t vendor; grub_uint16_t device; }; struct device { struct device_description desc; char *name; union { grub_pci_device_t pci_dev; }; }; struct pci_device { struct device dev; grub_uint16_t ioaddr; grub_uint16_t vendor; grub_uint16_t device; int irq; void *priv; void *drvdata; }; struct pci_device_id { grub_pci_id_t devid; }; #define PCI_ROM(vendor, model, short_name, long_name, num) {.devid = ((vendor) | ((model) << 16))} #define __pci_driver struct nic; struct pci_driver { struct pci_device_id *ids; grub_size_t id_count; int (*probe) (struct pci_device *pci, const struct pci_device_id *id); void (*remove) (struct pci_device *pci); void (*irq) (struct nic *nic, int action); }; static inline void pci_read_config_byte (struct pci_device *dev, grub_uint32_t reg, grub_uint8_t *val) { grub_pci_address_t addr; addr = grub_pci_make_address (dev->dev.pci_dev, reg); *val = grub_pci_read_byte (addr); } static inline void pci_read_config_word (struct pci_device *dev, grub_uint32_t reg, grub_uint16_t *val) { grub_pci_address_t addr; addr = grub_pci_make_address (dev->dev.pci_dev, reg); *val = grub_pci_read_word (addr); } static inline void pci_read_config_dword (struct pci_device *dev, grub_uint32_t reg, grub_uint32_t *val) { grub_pci_address_t addr; addr = grub_pci_make_address (dev->dev.pci_dev, reg); *val = grub_pci_read (addr); } static inline void pci_write_config_byte (struct pci_device *dev, grub_uint32_t reg, grub_uint8_t val) { grub_pci_address_t addr; addr = grub_pci_make_address (dev->dev.pci_dev, reg); grub_pci_write_byte (addr, val); } static inline void pci_write_config_word (struct pci_device *dev, grub_uint32_t reg, grub_uint16_t val) { grub_pci_address_t addr; addr = grub_pci_make_address (dev->dev.pci_dev, reg); grub_pci_write_word (addr, val); } static inline void pci_write_config_dword (struct pci_device *dev, grub_uint32_t reg, grub_uint32_t val) { grub_pci_address_t addr; addr = grub_pci_make_address (dev->dev.pci_dev, reg); grub_pci_write (addr, val); } static inline void * pci_get_drvdata (struct pci_device *dev) { return dev->drvdata; } static inline void pci_set_drvdata (struct pci_device *dev, void *data) { dev->drvdata = data; } static inline grub_uint32_t readl (volatile void *ptr) { return *(volatile grub_uint32_t *) ptr; } static inline void writel (grub_uint32_t data, volatile void *ptr) { *(volatile grub_uint32_t *) ptr = data; } static inline grub_addr_t pci_bar_start (struct pci_device *dev, grub_uint32_t reg) { grub_pci_address_t addr; grub_uint64_t space; addr = grub_pci_make_address (dev->dev.pci_dev, reg >> 2); space = grub_pci_read (addr); if ((space & GRUB_PCI_ADDR_SPACE_MASK) == GRUB_PCI_ADDR_SPACE_IO) return space & GRUB_PCI_ADDR_IO_MASK; if ((space & GRUB_PCI_ADDR_MEM_TYPE_MASK) == GRUB_PCI_ADDR_MEM_TYPE_64) { addr = grub_pci_make_address (dev->dev.pci_dev, (reg >> 2) + 1); space |= ((grub_uint64_t) grub_pci_read (addr)) << 32; } return space & GRUB_PCI_ADDR_MEM_MASK; } /* XXX: make it use grub_pci_device_map_range. */ static inline void * bus_to_virt (grub_uint32_t bus) { return (void *) bus; } static inline void * ioremap (grub_uint32_t bus, grub_size_t size __attribute__ ((unused))) { return (void *) bus; } static inline grub_uint32_t virt_to_bus (void *virt) { return (grub_addr_t) virt; } void grub_gpxe_register_pci_nic (struct pci_driver *nic); void grub_gpxe_unregister_pci_nic (struct pci_driver *nic); void adjust_pci_device ( struct pci_device *pci ); #define PCI_VENDOR_ID_DAVICOM 0x0291 #define PCI_VENDOR_ID_WINBOND2 0x1050 #define PCI_VENDOR_ID_COMPEX 0x11f6 #define PCI_COMMAND GRUB_PCI_REG_COMMAND #define PCI_REVISION_ID GRUB_PCI_REG_REVISION #define PCI_REVISION PCI_REVISION_ID #define PCI_LATENCY_TIMER GRUB_PCI_REG_LAT_TIMER #define PCI_BASE_ADDRESS_0 GRUB_PCI_REG_ADDRESS_REG0 #define PCI_BASE_ADDRESS_1 GRUB_PCI_REG_ADDRESS_REG1 #define PCI_COMMAND_IO 0x1 #define PCI_COMMAND_MEM 0x2 #define PCI_COMMAND_MASTER 0x4 #endif debian/grub-extras/disabled/gpxe/include_wrap/gpxe/wrap.h0000664000000000000000000001406712524662415020725 0ustar /* * Copyright © 2009 Vladimir 'phcoder' Serbinenko * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ FILE_LICENCE ( BSD2 ); #ifndef _GPXE_WRAP_H #define _GPXE_WRAP_H #include #include #include #include #include #include #include void * memchr (void *s, grub_uint8_t c, grub_size_t size); #define be64_to_cpu grub_be_to_cpu64 #define cpu_to_be64 grub_cpu_to_be64 #define cpu_to_be32 grub_cpu_to_be32 #define cpu_to_be16 grub_cpu_to_be16 #define le16_to_cpu grub_le_to_cpu16 #define be16_to_cpu grub_be_to_cpu16 #define be32_to_cpu grub_be_to_cpu32 #define cpu_to_le16 grub_cpu_to_le16 #define cpu_to_le32 grub_cpu_to_le32 #define le32_to_cpu grub_le_to_cpu32 /* In gPXE codebase following has to be a macro. So grub_cpu_to_be isn't usable. */ #define bswap_16(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) #define swap16 bswap_16 #ifdef GRUB_CPU_WORDS_BIGENDIAN #define htons(x) (x) #define htonl(x) (x) #else #define htons(x) (bswap_16(x)) #define htonl(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24)) #endif #define ntohl(x) htonl(x) #define ntohs(x) htons(x) typedef grub_uint64_t u64; typedef grub_uint64_t uint64_t; typedef grub_uint32_t u32; typedef grub_int32_t s32; typedef grub_uint32_t uint32_t; typedef grub_int32_t int32_t; typedef grub_uint16_t u16; typedef grub_int16_t s16; typedef grub_uint16_t uint16_t; typedef grub_int16_t int16_t; typedef grub_uint8_t u8; typedef grub_uint8_t uint8_t; typedef grub_int8_t int8_t; typedef grub_size_t size_t; #define __malloc #define __shared #define __unused __attribute__ ((unused)) #define off_t grub_off_t #define strcpy grub_strcpy #if 0 typedef void *userptr_t; static inline void memcpy_user ( userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len ) { grub_memcpy ((void *) (dest + dest_off), (void *) (src + src_off), len); } #endif #define memcpy grub_memcpy #define zalloc grub_zalloc #define strdup grub_strdup #define strncmp grub_strncmp #define strchr grub_strchr #define strcasecmp grub_strcasecmp #define printf grub_printf #define intptr_t grub_addr_t static inline void * malloc (grub_size_t size) { return grub_malloc (size); } static inline void * realloc (void *ptr, grub_size_t size) { return grub_realloc (ptr, size); } static inline grub_size_t strlen (const char *s) { return grub_strlen (s); } static inline int strcmp (const char *s1, const char *s2) { return grub_strcmp (s1, s2); } static inline int toupper (int c) { return grub_toupper (c); } static inline int tolower (int c) { return grub_tolower (c); } unsigned long strtoul ( const char *p, char **endp, int base ); static inline int isspace (int c) { return grub_isspace (c); } static inline int isdigit (int c) { return grub_isdigit (c); } static inline int isalpha (int c) { return grub_isalpha (c); } static inline int islower (int c) { return (c >= 'a' && c <= 'z'); } static inline int isupper (int c) { return (c >= 'A' && c <= 'Z'); } typedef grub_ssize_t ssize_t; static inline void free (void *ptr) { grub_free (ptr); } #define assert(x) assert_real(__FILE__, __LINE__, x) static inline void assert_real (const char *file, int line, int cond) { if (!cond) grub_fatal ("Assertion failed at %s:%d\n", file, line); } #define __assert_fail grub_abort #define __always_inline #define VERSION_MAJOR 1 #define VERSION_MINOR 97 #define VERSION_PATCH 1 #define strstr grub_strstr #define alloc_memblock(size,align) grub_memalign(align,size) #define DBG(fmt,args...) grub_dprintf("net", fmt, ## args) #define DBG2(fmt,args...) grub_dprintf("net", fmt, ## args) #define DBG_HD(data,len) #define DBGP(fmt,args...) grub_dprintf("net", fmt, ## args) #define DBGP_HD(data,len) #define DBGC(ptr, fmt,args...) grub_dprintf("net", fmt, ## args) #define DBGCP(ptr, fmt,args...) grub_dprintf("net", fmt, ## args) #define DBGC2(ptr, fmt,args...) grub_dprintf("net", fmt, ## args) #define DBGC_HD(ptr,data,len) #define DBGCP_HD(ptr,data,len) #define DBGC_HDA(ptr,s,data,len) #define DBGC2_HDA(ptr,s,data,len) #define DBGCP_HDA(ptr,s,data,len) #define strrchr grub_strrchr static inline void memswap (void *b1, void *b2, grub_size_t size) { register grub_uint8_t t; while (size--) { t = *(grub_uint8_t *) b1; *(grub_uint8_t *) b1 = *(grub_uint8_t *) b2; *(grub_uint8_t *) b2 = t; b1 = (grub_uint8_t *) b1 + 1; b2 = (grub_uint8_t *) b2 + 1; } } static inline int flsl (long n) { int i; for (i = sizeof (n) - 1; i >= 0; i--) if (n & (1 << i)) return i + 1; return 0; } #define INT_MAX 2147483647L #define putchar(x) grub_printf("%c", x) #define snprintf grub_snprintf #define ssnprintf grub_snprintf #define vsnprintf grub_vsnprintf #endif debian/grub-extras/disabled/gpxe/include_wrap/gpxe/nap.h0000664000000000000000000000305312524662415020523 0ustar /* * Copyright © 2009 Vladimir 'phcoder' Serbinenko * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ FILE_LICENCE ( BSD2 ); #ifndef _GPXE_NAP_H #define _GPXE_NAP_H #include static inline void cpu_nap ( void ) { grub_cpu_idle (); } #endif debian/grub-extras/disabled/gpxe/include_wrap/gpxe/vsprintf.h0000664000000000000000000000002712524662415021616 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/gpxe/efi/0000775000000000000000000000000012524676037020343 5ustar debian/grub-extras/disabled/gpxe/include_wrap/gpxe/efi/efi_uaccess.h0000664000000000000000000000002712524662415022757 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/gpxe/list.h0000664000000000000000000000672212524662415020726 0ustar /* * Copyright © 2009 Vladimir 'phcoder' Serbinenko * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ FILE_LICENCE ( BSD2 ); #ifndef _GPXE_LIST_H #define _GPXE_LIST_H 1 #include #include struct list_head { struct list_head *next; struct list_head *prev; }; #define LIST_HEAD struct list_head #define INIT_LIST_HEAD(x) ((x)->next = NULL) #define LIST_HEAD_INIT(x) { .next = NULL, .prev = NULL } #define list_empty(x) ((x)->next == NULL) #define offsetof(type, elem) ((grub_uint8_t *) (&((type *) NULL)->elem) - (grub_uint8_t *) NULL) #define container_of(var, type, elem) ((type *) ((grub_uint8_t *)(var) - offsetof (type, elem))) #define list_get_next(it, lst_el, hold) \ container_of ((it)->lst_el.next, typeof (*hold), lst_el) #define list_for_each_entry(it, lst, lst_el) \ for ((it) = container_of((lst)->next, typeof (*(it)), lst_el); \ &(it)->lst_el != NULL && &(it)->lst_el != (void *) lst; \ (it) = list_get_next(it, lst_el, it)) #define list_for_each_entry_safe(it, next_h, lst, lst_el) \ for ((it) = container_of((lst)->next, typeof (*(it)), lst_el); \ &(it)->lst_el != NULL && &(it)->lst_el != (void *) lst; \ ((it) = container_of ((next_h), typeof (*(next_h)), lst_el)), \ (next_h) = list_get_next(it, lst_el, next_h)) static inline void list_del (struct list_head *head) { if (head->next == head->prev) { head->next->prev = NULL; head->prev->next = NULL; } else { head->prev->next = head->next; head->next->prev = head->prev; } } static inline void list_add_tail (struct list_head *head, struct list_head *new) { if (list_empty (head)) { head->next = head->prev = new; new->next = new->prev = head; } else { head->prev->next = new; new->prev = head->prev; new->next = head; head->prev = new; } } static inline void list_add (struct list_head *head, struct list_head *new) { if (list_empty (head)) { head->next = head->prev = new; new->next = new->prev = head; } else { head->next->prev = new; new->next = head->next; new->prev = head; head->next = new; } } #endif debian/grub-extras/disabled/gpxe/include_wrap/gpxe/device.h0000664000000000000000000000002612524662415021201 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/gpxe/io.h0000664000000000000000000000002612524662415020351 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/stdint.h0000664000000000000000000000002712524662415020305 0ustar #include debian/grub-extras/disabled/gpxe/include_wrap/byteswap.h0000664000000000000000000000002712524662415020636 0ustar #include debian/grub-extras/disabled/gpxe/Makefile.common0000664000000000000000000000023412524662415017102 0ustar GPXE_CPPFLAGS = '-DFILE_LICENCE(x)=' -I$(srcdir)/contrib/gpxe/src/include -I$(srcdir)/contrib/gpxe/include_wrap GPXE_CFLAGS = -Wno-pointer-arith -Wno-error debian/grub-extras/disabled/gpxe/wrap/0000775000000000000000000000000012524676037015132 5ustar debian/grub-extras/disabled/gpxe/wrap/nic.c0000664000000000000000000001000612524662415016037 0ustar /* * Copyright © 2009 Vladimir 'phcoder' Serbinenko * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ FILE_LICENCE ( BSD2 ); #include #include /* Helper for grub_gpxe_register_pci_nic. */ static int grub_gpxe_pci_nic_init (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) { struct pci_driver *nic = data; unsigned i; for (i = 0; i < nic->id_count; i++) { int err; if (nic->ids[i].devid == pciid) { struct pci_device *pci; struct pci_device_id *id; int reg; grub_dprintf ("gpxe", "Attaching NIC %d:%d.%d\n", grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev)); pci = grub_malloc (sizeof (*pci)); if (!pci) { grub_print_error (); grub_errno = GRUB_ERR_NONE; return 0; } id = grub_malloc (sizeof (*id)); if (!id) { grub_free (pci); grub_print_error (); grub_errno = GRUB_ERR_NONE; return 0; } id->devid = pciid; pci->dev.desc.bus_type = BUS_TYPE_PCI; pci->dev.desc.bus = grub_pci_get_bus (dev); pci->dev.desc.location = (grub_pci_get_device (dev) << 3) | grub_pci_get_function (dev); pci->dev.desc.vendor = pciid & 0xffff; pci->dev.desc.device = pciid >> 16; pci->vendor = pciid & 0xffff; pci->device = pciid >> 16; pci->dev.name = grub_xasprintf ("PCI:%02x:%02x.%x", grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev)); pci->dev.pci_dev = dev; pci->priv = 0; pci->drvdata = 0; reg = GRUB_PCI_REG_ADDRESSES; while (reg < GRUB_PCI_REG_CIS_POINTER) { grub_uint64_t space; grub_pci_address_t addr; addr = grub_pci_make_address (dev, reg); space = grub_pci_read (addr); reg += sizeof (grub_uint32_t); if (space == 0) continue; if ((space & GRUB_PCI_ADDR_SPACE_MASK) == GRUB_PCI_ADDR_SPACE_IO) { pci->ioaddr = space & GRUB_PCI_ADDR_IO_MASK; break; } if ((space & GRUB_PCI_ADDR_MEM_TYPE_MASK) == GRUB_PCI_ADDR_MEM_TYPE_64) reg += sizeof (grub_uint32_t); } /* No IRQ support yet. */ pci->irq = 0; grub_dprintf ("gpxe", "Probing NIC %d:%d.%d\n", grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev)); err = nic->probe (pci, id); grub_dprintf ("gpxe", "Nic probe finished with status %d\n", err); } } return 0; } void grub_gpxe_register_pci_nic (struct pci_driver *nic) { grub_dprintf ("gpxe", "Registering nic\n"); grub_pci_iterate (grub_gpxe_pci_nic_init, nic); } /* FIXME: free all resources associated with driver and detach devices. */ void grub_gpxe_unregister_pci_nic (struct pci_driver *nic __attribute__ ((unused))) { } debian/grub-extras/disabled/gpxe/wrap/wrap.c0000664000000000000000000000415712524662415016251 0ustar /* * Copyright © 2009 Vladimir 'phcoder' Serbinenko * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ FILE_LICENCE ( BSD2 ); #include #include void memcpy_user (userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len ) { grub_memcpy ((void *) dest+dest_off, (void *) src+src_off, len); } userptr_t virt_to_user (volatile const void *in) { return in; } void free_memblock (void *ptr, size_t size __attribute__ ((unused))) { grub_free (ptr); } void * memchr (void *s, grub_uint8_t c, grub_size_t size) { for (;size && *(grub_uint8_t *)s != c; size--, s = (grub_uint8_t *)s + 1); if (size) return s; return NULL; } grub_size_t strnlen (char *str, grub_size_t n) { grub_size_t r = 0; while (*str && n) { str++; n--; r++; } return r; } debian/grub-extras/disabled/gpxe/wrap/pci.c0000664000000000000000000000360412524662415016047 0ustar /* * Copyright (C) 2006 Michael Brown . * * Based in part on pci.c from Etherboot 5.4, by Ken Yap and David * Munro, in turn based on the Linux kernel's PCI implementation. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include /** * Enable PCI device * * @v pci PCI device * * Set device to be a busmaster in case BIOS neglected to do so. Also * adjust PCI latency timer to a reasonable value, 32. */ void adjust_pci_device ( struct pci_device *pci ) { unsigned short new_command, pci_command; unsigned char pci_latency; pci_read_config_word ( pci, PCI_COMMAND, &pci_command ); new_command = ( pci_command | PCI_COMMAND_MASTER | PCI_COMMAND_MEM | PCI_COMMAND_IO ); if ( pci_command != new_command ) { pci_write_config_word ( pci, PCI_COMMAND, new_command ); } pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency); if ( pci_latency < 32 ) { pci_write_config_byte ( pci, PCI_LATENCY_TIMER, 32); } } debian/grub-extras/disabled/gpxe/src/0000775000000000000000000000000012524676037014750 5ustar debian/grub-extras/disabled/gpxe/src/drivers/0000775000000000000000000000000012524676037016426 5ustar debian/grub-extras/disabled/gpxe/src/drivers/nvs/0000775000000000000000000000000012524676037017234 5ustar debian/grub-extras/disabled/gpxe/src/drivers/nvs/threewire.c0000664000000000000000000000704012524662415021372 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include /** @file * * Three-wire serial devices * */ /** * Read data from three-wire device * * @v nvs NVS device * @v address Address from which to read * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code */ int threewire_read ( struct nvs_device *nvs, unsigned int address, void *data, size_t len ) { struct spi_device *device = nvs_to_spi ( nvs ); struct spi_bus *bus = device->bus; int rc; assert ( bus->mode == SPI_MODE_THREEWIRE ); DBGC ( device, "3wire %p reading %zd bytes at %04x\n", device, len, address ); if ( ( rc = bus->rw ( bus, device, THREEWIRE_READ, address, NULL, data, len ) ) != 0 ) { DBGC ( device, "3wire %p could not read: %s\n", device, strerror ( rc ) ); return rc; } return 0; } /** * Write data to three-wire device * * @v nvs NVS device * @v address Address from which to read * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code */ int threewire_write ( struct nvs_device *nvs, unsigned int address, const void *data, size_t len ) { struct spi_device *device = nvs_to_spi ( nvs ); struct spi_bus *bus = device->bus; int rc; assert ( bus->mode == SPI_MODE_THREEWIRE ); DBGC ( device, "3wire %p writing %zd bytes at %04x\n", device, len, address ); /* Enable device for writing */ if ( ( rc = bus->rw ( bus, device, THREEWIRE_EWEN, THREEWIRE_EWEN_ADDRESS, NULL, NULL, 0 ) ) != 0 ){ DBGC ( device, "3wire %p could not enable writing: %s\n", device, strerror ( rc ) ); return rc; } /* Write data */ if ( ( rc = bus->rw ( bus, device, THREEWIRE_WRITE, address, data, NULL, len ) ) != 0 ) { DBGC ( device, "3wire %p could not write: %s\n", device, strerror ( rc ) ); return rc; } /* Our model of an SPI bus doesn't provide a mechanism for * "assert CS, wait for MISO to become high, so just wait for * long enough to ensure that the write has completed. */ mdelay ( THREEWIRE_WRITE_MDELAY ); return 0; } /** * Autodetect device address length * * @v device SPI device * @ret rc Return status code */ int threewire_detect_address_len ( struct spi_device *device ) { struct nvs_device *nvs = &device->nvs; int rc; DBGC ( device, "3wire %p autodetecting address length\n", device ); device->address_len = SPI_AUTODETECT_ADDRESS_LEN; if ( ( rc = threewire_read ( nvs, 0, NULL, ( 1 << nvs->word_len_log2 ) ) ) != 0 ) { DBGC ( device, "3wire %p could not autodetect address " "length: %s\n", device, strerror ( rc ) ); return rc; } DBGC ( device, "3wire %p autodetected address length %d\n", device, device->address_len ); return 0; } debian/grub-extras/disabled/gpxe/src/drivers/nvs/spi.c0000664000000000000000000000732012524662415020170 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include /** @file * * SPI devices * */ /** * Munge SPI device address into command * * @v command SPI command * @v address Address * @v munge_address Device requires address munging * @ret command Actual SPI command to use * * Some devices with 9-bit addresses (e.g. AT25040A EEPROM) use bit 3 * of the command byte as address bit A8, rather than having a * two-byte address. This function takes care of generating the * appropriate command. */ static inline unsigned int spi_command ( unsigned int command, unsigned int address, int munge_address ) { return ( command | ( ( ( address >> 8 ) & munge_address ) << 3 ) ); } /** * Wait for SPI device to complete operation * * @v device SPI device * @ret rc Return status code */ static int spi_wait ( struct spi_device *device ) { struct spi_bus *bus = device->bus; uint8_t status; int i; int rc; for ( i = 0 ; i < 50 ; i++ ) { udelay ( 20 ); if ( ( rc = bus->rw ( bus, device, SPI_RDSR, -1, NULL, &status, sizeof ( status ) ) ) != 0 ) return rc; if ( ! ( status & SPI_STATUS_NRDY ) ) return 0; } DBG ( "SPI %p timed out\n", device ); return -ETIMEDOUT; } /** * Read data from SPI device * * @v nvs NVS device * @v address Address from which to read * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code */ int spi_read ( struct nvs_device *nvs, unsigned int address, void *data, size_t len ) { struct spi_device *device = nvs_to_spi ( nvs ); struct spi_bus *bus = device->bus; unsigned int command = spi_command ( SPI_READ, address, device->munge_address ); int rc; DBG ( "SPI %p reading %zd bytes from %#04x\n", device, len, address ); if ( ( rc = bus->rw ( bus, device, command, address, NULL, data, len ) ) != 0 ) { DBG ( "SPI %p failed to read data from device\n", device ); return rc; } return 0; } /** * Write data to SPI device * * @v nvs NVS device * @v address Address from which to read * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code */ int spi_write ( struct nvs_device *nvs, unsigned int address, const void *data, size_t len ) { struct spi_device *device = nvs_to_spi ( nvs ); struct spi_bus *bus = device->bus; unsigned int command = spi_command ( SPI_WRITE, address, device->munge_address ); int rc; DBG ( "SPI %p writing %zd bytes to %#04x\n", device, len, address ); if ( ( rc = bus->rw ( bus, device, SPI_WREN, -1, NULL, NULL, 0 ) ) != 0 ) { DBG ( "SPI %p failed to write-enable device\n", device ); return rc; } if ( ( rc = bus->rw ( bus, device, command, address, data, NULL, len ) ) != 0 ) { DBG ( "SPI %p failed to write data to device\n", device ); return rc; } if ( ( rc = spi_wait ( device ) ) != 0 ) { DBG ( "SPI %p failed to complete write operation\n", device ); return rc; } return 0; } debian/grub-extras/disabled/gpxe/src/drivers/nvs/nvs.c0000664000000000000000000000733412524662415020210 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include /** @file * * Non-volatile storage * */ /** * Read from non-volatile storage device * * @v nvs NVS device * @v address Address from which to read * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code */ int nvs_read ( struct nvs_device *nvs, unsigned int address, void *data, size_t len ) { size_t frag_len; int rc; /* We don't even attempt to handle buffer lengths that aren't * an integral number of words. */ assert ( ( len & ( ( 1 << nvs->word_len_log2 ) - 1 ) ) == 0 ); while ( len ) { /* Calculate space remaining up to next block boundary */ frag_len = ( ( nvs->block_size - ( address & ( nvs->block_size - 1 ) ) ) << nvs->word_len_log2 ); /* Limit to space remaining in buffer */ if ( frag_len > len ) frag_len = len; /* Read this portion of the buffer from the device */ if ( ( rc = nvs->read ( nvs, address, data, frag_len ) ) != 0 ) return rc; /* Update parameters */ data += frag_len; address += ( frag_len >> nvs->word_len_log2 ); len -= frag_len; } return 0; } /** * Verify content of non-volatile storage device * * @v nvs NVS device * @v address Address from which to read * @v data Data to compare against * @v len Length of data buffer * @ret rc Return status code */ static int nvs_verify ( struct nvs_device *nvs, unsigned int address, const void *data, size_t len ) { uint8_t read_data[len]; int rc; /* Read data into temporary buffer */ if ( ( rc = nvs_read ( nvs, address, read_data, len ) ) != 0 ) return rc; /* Compare data */ if ( memcmp ( data, read_data, len ) != 0 ) { DBG ( "NVS %p verification failed at %#04x+%zd\n", nvs, address, len ); return -EIO; } return 0; } /** * Write to non-volatile storage device * * @v nvs NVS device * @v address Address to which to write * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code */ int nvs_write ( struct nvs_device *nvs, unsigned int address, const void *data, size_t len ) { size_t frag_len; int rc; /* We don't even attempt to handle buffer lengths that aren't * an integral number of words. */ assert ( ( len & ( ( 1 << nvs->word_len_log2 ) - 1 ) ) == 0 ); while ( len ) { /* Calculate space remaining up to next block boundary */ frag_len = ( ( nvs->block_size - ( address & ( nvs->block_size - 1 ) ) ) << nvs->word_len_log2 ); /* Limit to space remaining in buffer */ if ( frag_len > len ) frag_len = len; /* Write this portion of the buffer to the device */ if ( ( rc = nvs->write ( nvs, address, data, frag_len ) ) != 0) return rc; /* Read back and verify data */ if ( ( rc = nvs_verify ( nvs, address, data, frag_len ) ) != 0) return rc; /* Update parameters */ data += frag_len; address += ( frag_len >> nvs->word_len_log2 ); len -= frag_len; } return 0; } debian/grub-extras/disabled/gpxe/src/drivers/bitbash/0000775000000000000000000000000012524676037020042 5ustar debian/grub-extras/disabled/gpxe/src/drivers/bitbash/i2c_bit.c0000664000000000000000000002231412524662415021516 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include /** @file * * I2C bit-bashing interface * * This implements a simple I2C master via a bit-bashing interface * that provides two lines: SCL (clock) and SDA (data). */ /** * Delay between output state changes * * Max rated i2c speed (for the basic i2c protocol) is 100kbps, * i.e. 200k clock transitions per second. */ static void i2c_delay ( void ) { udelay ( I2C_UDELAY ); } /** * Set state of I2C SCL line * * @v basher Bit-bashing interface * @v state New state of SCL */ static void setscl ( struct bit_basher *basher, int state ) { DBG2 ( "%c", ( state ? '/' : '\\' ) ); write_bit ( basher, I2C_BIT_SCL, state ); i2c_delay(); } /** * Set state of I2C SDA line * * @v basher Bit-bashing interface * @v state New state of SDA */ static void setsda ( struct bit_basher *basher, int state ) { DBG2 ( "%c", ( state ? '1' : '0' ) ); write_bit ( basher, I2C_BIT_SDA, state ); i2c_delay(); } /** * Get state of I2C SDA line * * @v basher Bit-bashing interface * @ret state State of SDA */ static int getsda ( struct bit_basher *basher ) { int state; state = read_bit ( basher, I2C_BIT_SDA ); DBG2 ( "%c", ( state ? '+' : '-' ) ); return state; } /** * Send an I2C start condition * * @v basher Bit-bashing interface */ static void i2c_start ( struct bit_basher *basher ) { setscl ( basher, 1 ); setsda ( basher, 0 ); setscl ( basher, 0 ); setsda ( basher, 1 ); } /** * Send an I2C data bit * * @v basher Bit-bashing interface * @v bit Bit to send */ static void i2c_send_bit ( struct bit_basher *basher, int bit ) { setsda ( basher, bit ); setscl ( basher, 1 ); setscl ( basher, 0 ); setsda ( basher, 1 ); } /** * Receive an I2C data bit * * @v basher Bit-bashing interface * @ret bit Received bit */ static int i2c_recv_bit ( struct bit_basher *basher ) { int bit; setscl ( basher, 1 ); bit = getsda ( basher ); setscl ( basher, 0 ); return bit; } /** * Send an I2C stop condition * * @v basher Bit-bashing interface */ static void i2c_stop ( struct bit_basher *basher ) { setsda ( basher, 0 ); setscl ( basher, 1 ); setsda ( basher, 1 ); } /** * Send byte via I2C bus and check for acknowledgement * * @v basher Bit-bashing interface * @v byte Byte to send * @ret rc Return status code * * Sends a byte via the I2C bus and checks for an acknowledgement from * the slave device. */ static int i2c_send_byte ( struct bit_basher *basher, uint8_t byte ) { int i; int ack; /* Send byte */ DBG2 ( "[send %02x]", byte ); for ( i = 8 ; i ; i-- ) { i2c_send_bit ( basher, byte & 0x80 ); byte <<= 1; } /* Check for acknowledgement from slave */ ack = ( i2c_recv_bit ( basher ) == 0 ); DBG2 ( "%s", ( ack ? "[acked]" : "[not acked]" ) ); return ( ack ? 0 : -EIO ); } /** * Receive byte via I2C bus * * @v basher Bit-bashing interface * @ret byte Received byte * * Receives a byte via the I2C bus and sends NACK to the slave device. */ static uint8_t i2c_recv_byte ( struct bit_basher *basher ) { uint8_t byte = 0; int i; /* Receive byte */ for ( i = 8 ; i ; i-- ) { byte <<= 1; byte |= ( i2c_recv_bit ( basher ) & 0x1 ); } /* Send NACK */ i2c_send_bit ( basher, 1 ); DBG2 ( "[rcvd %02x]", byte ); return byte; } /** * Select I2C device for reading or writing * * @v basher Bit-bashing interface * @v i2cdev I2C device * @v offset Starting offset within the device * @v direction I2C_READ or I2C_WRITE * @ret rc Return status code */ static int i2c_select ( struct bit_basher *basher, struct i2c_device *i2cdev, unsigned int offset, unsigned int direction ) { unsigned int address; int shift; unsigned int byte; int rc; i2c_start ( basher ); /* Calculate address to appear on bus */ address = ( ( ( i2cdev->dev_addr | ( offset >> ( 8 * i2cdev->word_addr_len ) ) ) << 1 ) | direction ); /* Send address a byte at a time */ for ( shift = ( 8 * ( i2cdev->dev_addr_len - 1 ) ) ; shift >= 0 ; shift -= 8 ) { byte = ( ( address >> shift ) & 0xff ); if ( ( rc = i2c_send_byte ( basher, byte ) ) != 0 ) return rc; } return 0; } /** * Reset I2C bus * * @v basher Bit-bashing interface * @ret rc Return status code * * i2c devices often don't have a reset line, so even a reboot or * system power cycle is sometimes not enough to bring them back to a * known state. */ static int i2c_reset ( struct bit_basher *basher ) { unsigned int i; int sda; /* Clock through several cycles, waiting for an opportunity to * pull SDA low while SCL is high (which creates a start * condition). */ setscl ( basher, 0 ); setsda ( basher, 1 ); for ( i = 0 ; i < I2C_RESET_MAX_CYCLES ; i++ ) { setscl ( basher, 1 ); sda = getsda ( basher ); if ( sda ) { /* Now that the device will see a start, issue it */ i2c_start ( basher ); /* Stop the bus to leave it in a known good state */ i2c_stop ( basher ); DBGC ( basher, "I2CBIT %p reset after %d attempts\n", basher, ( i + 1 ) ); return 0; } setscl ( basher, 0 ); } DBGC ( basher, "I2CBIT %p could not reset after %d attempts\n", basher, i ); return -ETIMEDOUT; } /** * Read data from I2C device via bit-bashing interface * * @v i2c I2C interface * @v i2cdev I2C device * @v offset Starting offset within the device * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code * * Note that attempting to read zero bytes of data is a valid way to * check for I2C device presence. */ static int i2c_bit_read ( struct i2c_interface *i2c, struct i2c_device *i2cdev, unsigned int offset, uint8_t *data, unsigned int len ) { struct i2c_bit_basher *i2cbit = container_of ( i2c, struct i2c_bit_basher, i2c ); struct bit_basher *basher = &i2cbit->basher; int rc = 0; DBGC ( basher, "I2CBIT %p reading from device %x: ", basher, i2cdev->dev_addr ); for ( ; ; data++, offset++ ) { /* Select device for writing */ if ( ( rc = i2c_select ( basher, i2cdev, offset, I2C_WRITE ) ) != 0 ) break; /* Abort at end of data */ if ( ! ( len-- ) ) break; /* Select offset */ if ( ( rc = i2c_send_byte ( basher, offset ) ) != 0 ) break; /* Select device for reading */ if ( ( rc = i2c_select ( basher, i2cdev, offset, I2C_READ ) ) != 0 ) break; /* Read byte */ *data = i2c_recv_byte ( basher ); DBGC ( basher, "%02x ", *data ); } DBGC ( basher, "%s\n", ( rc ? "failed" : "" ) ); i2c_stop ( basher ); return rc; } /** * Write data to I2C device via bit-bashing interface * * @v i2c I2C interface * @v i2cdev I2C device * @v offset Starting offset within the device * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code * * Note that attempting to write zero bytes of data is a valid way to * check for I2C device presence. */ static int i2c_bit_write ( struct i2c_interface *i2c, struct i2c_device *i2cdev, unsigned int offset, const uint8_t *data, unsigned int len ) { struct i2c_bit_basher *i2cbit = container_of ( i2c, struct i2c_bit_basher, i2c ); struct bit_basher *basher = &i2cbit->basher; int rc = 0; DBGC ( basher, "I2CBIT %p writing to device %x: ", basher, i2cdev->dev_addr ); for ( ; ; data++, offset++ ) { /* Select device for writing */ if ( ( rc = i2c_select ( basher, i2cdev, offset, I2C_WRITE ) ) != 0 ) break; /* Abort at end of data */ if ( ! ( len-- ) ) break; /* Select offset */ if ( ( rc = i2c_send_byte ( basher, offset ) ) != 0 ) break; /* Write data to device */ DBGC ( basher, "%02x ", *data ); if ( ( rc = i2c_send_byte ( basher, *data ) ) != 0 ) break; } DBGC ( basher, "%s\n", ( rc ? "failed" : "" ) ); i2c_stop ( basher ); return rc; } /** * Initialise I2C bit-bashing interface * * @v i2cbit I2C bit-bashing interface * @v bash_op Bit-basher operations */ int init_i2c_bit_basher ( struct i2c_bit_basher *i2cbit, struct bit_basher_operations *bash_op ) { struct bit_basher *basher = &i2cbit->basher; int rc; /* Initialise data structures */ basher->op = bash_op; assert ( basher->op->read != NULL ); assert ( basher->op->write != NULL ); i2cbit->i2c.read = i2c_bit_read; i2cbit->i2c.write = i2c_bit_write; /* Reset I2C bus */ if ( ( rc = i2c_reset ( basher ) ) != 0 ) { DBGC ( basher, "I2CBIT %p could not reset I2C bus: %s\n", basher, strerror ( rc ) ); return rc; } return 0; } debian/grub-extras/disabled/gpxe/src/drivers/bitbash/spi_bit.c0000664000000000000000000001510312524662415021632 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include /** @file * * SPI bit-bashing interface * */ /** Delay between SCLK changes and around SS changes */ static void spi_bit_delay ( void ) { udelay ( SPI_BIT_UDELAY ); } /** Chip select line will be asserted */ #define SELECT_SLAVE 0 /** Chip select line will be deasserted */ #define DESELECT_SLAVE SPI_MODE_SSPOL /** * Select/deselect slave * * @v spibit SPI bit-bashing interface * @v slave Slave number * @v state Slave select state * * @c state must be @c SELECT_SLAVE or @c DESELECT_SLAVE. */ static void spi_bit_set_slave_select ( struct spi_bit_basher *spibit, unsigned int slave, unsigned int state ) { struct bit_basher *basher = &spibit->basher; state ^= ( spibit->bus.mode & SPI_MODE_SSPOL ); DBGC2 ( spibit, "SPIBIT %p setting slave %d select %s\n", spibit, slave, ( state ? "high" : "low" ) ); spi_bit_delay(); write_bit ( basher, SPI_BIT_SS ( slave ), state ); spi_bit_delay(); } /** * Transfer bits over SPI bit-bashing bus * * @v bus SPI bus * @v data_out TX data buffer (or NULL) * @v data_in RX data buffer (or NULL) * @v len Length of transfer (in @b bits) * @v endianness Endianness of this data transfer * * This issues @c len clock cycles on the SPI bus, shifting out data * from the @c data_out buffer to the MOSI line and shifting in data * from the MISO line to the @c data_in buffer. If @c data_out is * NULL, then the data sent will be all zeroes. If @c data_in is * NULL, then the incoming data will be discarded. */ static void spi_bit_transfer ( struct spi_bit_basher *spibit, const void *data_out, void *data_in, unsigned int len, int endianness ) { struct spi_bus *bus = &spibit->bus; struct bit_basher *basher = &spibit->basher; unsigned int sclk = ( ( bus->mode & SPI_MODE_CPOL ) ? 1 : 0 ); unsigned int cpha = ( ( bus->mode & SPI_MODE_CPHA ) ? 1 : 0 ); unsigned int bit_offset; unsigned int byte_offset; unsigned int byte_mask; unsigned int bit; unsigned int step; DBGC2 ( spibit, "SPIBIT %p transferring %d bits in mode %#x\n", spibit, len, bus->mode ); for ( step = 0 ; step < ( len * 2 ) ; step++ ) { /* Calculate byte offset and byte mask */ bit_offset = ( ( endianness == SPI_BIT_BIG_ENDIAN ) ? ( len - ( step / 2 ) - 1 ) : ( step / 2 ) ); byte_offset = ( bit_offset / 8 ); byte_mask = ( 1 << ( bit_offset % 8 ) ); /* Shift data in or out */ if ( sclk == cpha ) { const uint8_t *byte; /* Shift data out */ if ( data_out ) { byte = ( data_out + byte_offset ); bit = ( *byte & byte_mask ); DBGCP ( spibit, "SPIBIT %p wrote bit %d\n", spibit, ( bit ? 1 : 0 ) ); } else { bit = 0; } write_bit ( basher, SPI_BIT_MOSI, bit ); } else { uint8_t *byte; /* Shift data in */ bit = read_bit ( basher, SPI_BIT_MISO ); if ( data_in ) { DBGCP ( spibit, "SPIBIT %p read bit %d\n", spibit, ( bit ? 1 : 0 ) ); byte = ( data_in + byte_offset ); *byte &= ~byte_mask; *byte |= ( bit & byte_mask ); } } /* Toggle clock line */ spi_bit_delay(); sclk ^= 1; write_bit ( basher, SPI_BIT_SCLK, sclk ); } } /** * Read/write data via SPI bit-bashing bus * * @v bus SPI bus * @v device SPI device * @v command Command * @v address Address to read/write (<0 for no address) * @v data_out TX data buffer (or NULL) * @v data_in RX data buffer (or NULL) * @v len Length of transfer * @ret rc Return status code */ static int spi_bit_rw ( struct spi_bus *bus, struct spi_device *device, unsigned int command, int address, const void *data_out, void *data_in, size_t len ) { struct spi_bit_basher *spibit = container_of ( bus, struct spi_bit_basher, bus ); uint32_t tmp_command; uint32_t tmp_address; uint32_t tmp_address_detect; /* Set clock line to idle state */ write_bit ( &spibit->basher, SPI_BIT_SCLK, ( bus->mode & SPI_MODE_CPOL ) ); /* Assert chip select on specified slave */ spi_bit_set_slave_select ( spibit, device->slave, SELECT_SLAVE ); /* Transmit command */ assert ( device->command_len <= ( 8 * sizeof ( tmp_command ) ) ); tmp_command = cpu_to_le32 ( command ); spi_bit_transfer ( spibit, &tmp_command, NULL, device->command_len, SPI_BIT_BIG_ENDIAN ); /* Transmit address, if present */ if ( address >= 0 ) { assert ( device->address_len <= ( 8 * sizeof ( tmp_address ))); tmp_address = cpu_to_le32 ( address ); if ( device->address_len == SPI_AUTODETECT_ADDRESS_LEN ) { /* Autodetect address length. This relies on * the device responding with a dummy zero * data bit before the first real data bit. */ DBGC ( spibit, "SPIBIT %p autodetecting device " "address length\n", spibit ); assert ( address == 0 ); device->address_len = 0; do { spi_bit_transfer ( spibit, &tmp_address, &tmp_address_detect, 1, SPI_BIT_BIG_ENDIAN ); device->address_len++; } while ( le32_to_cpu ( tmp_address_detect ) & 1 ); DBGC ( spibit, "SPIBIT %p autodetected device address " "length %d\n", spibit, device->address_len ); } else { spi_bit_transfer ( spibit, &tmp_address, NULL, device->address_len, SPI_BIT_BIG_ENDIAN ); } } /* Transmit/receive data */ spi_bit_transfer ( spibit, data_out, data_in, ( len * 8 ), spibit->endianness ); /* Deassert chip select on specified slave */ spi_bit_set_slave_select ( spibit, device->slave, DESELECT_SLAVE ); return 0; } /** * Initialise SPI bit-bashing interface * * @v spibit SPI bit-bashing interface */ void init_spi_bit_basher ( struct spi_bit_basher *spibit ) { assert ( &spibit->basher.op->read != NULL ); assert ( &spibit->basher.op->write != NULL ); spibit->bus.rw = spi_bit_rw; } debian/grub-extras/disabled/gpxe/src/drivers/bitbash/bitbash.c0000664000000000000000000000316012524662415021615 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** @file * * Bit-bashing interfaces * */ /** * Set/clear output bit * * @v basher Bit-bashing interface * @v bit_id Bit number * @v data Value to write * * If @c data is 0, a logic 0 will be written. If @c data is * non-zero, a logic 1 will be written. */ void write_bit ( struct bit_basher *basher, unsigned int bit_id, unsigned long data ) { basher->op->write ( basher, bit_id, ( data ? -1UL : 0 ) ); } /** * Read input bit * * @v basher Bit-bashing interface * @v bit_id Bit number * @ret data Value read * * @c data will always be either 0 or -1UL. The idea is that the * caller can simply binary-AND the returned value with whatever mask * it needs to apply. */ int read_bit ( struct bit_basher *basher, unsigned int bit_id ) { return ( basher->op->read ( basher, bit_id ) ? -1UL : 0 ); } debian/grub-extras/disabled/gpxe/src/drivers/net/0000775000000000000000000000000012524676037017214 5ustar debian/grub-extras/disabled/gpxe/src/drivers/net/rtl8139.c0000664000000000000000000004377712524662415020523 0ustar /* rtl8139.c - etherboot driver for the Realtek 8139 chipset ported from the linux driver written by Donald Becker by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999 This software may be used and distributed according to the terms of the GNU Public License, incorporated herein by reference. changes to the original driver: - removed support for interrupts, switching to polling mode (yuck!) - removed support for the 8129 chip (external MII) */ FILE_LICENCE ( GPL_ANY ); /*********************************************************************/ /* Revision History */ /*********************************************************************/ /* 27 May 2006 mcb30@users.sourceforge.net (Michael Brown) Rewrote to use the new net driver API, the updated PCI API, and the generic three-wire serial device support for EEPROM access. 28 Dec 2002 ken_yap@users.sourceforge.net (Ken Yap) Put in virt_to_bus calls to allow Etherboot relocation. 06 Apr 2001 ken_yap@users.sourceforge.net (Ken Yap) Following email from Hyun-Joon Cha, added a disable routine, otherwise NIC remains live and can crash the kernel later. 4 Feb 2000 espenlaub@informatik.uni-ulm.de (Klaus Espenlaub) Shuffled things around, removed the leftovers from the 8129 support that was in the Linux driver and added a bit more 8139 definitions. Moved the 8K receive buffer to a fixed, available address outside the 0x98000-0x9ffff range. This is a bit of a hack, but currently the only way to make room for the Etherboot features that need substantial amounts of code like the ANSI console support. Currently the buffer is just below 0x10000, so this even conforms to the tagged boot image specification, which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000. My interpretation of this "reserved" is that Etherboot may do whatever it likes, as long as its environment is kept intact (like the BIOS variables). Hopefully fixed rtl_poll() once and for all. The symptoms were that if Etherboot was left at the boot menu for several minutes, the first eth_poll failed. Seems like I am the only person who does this. First of all I fixed the debugging code and then set out for a long bug hunting session. It took me about a week full time work - poking around various places in the driver, reading Don Becker's and Jeff Garzik's Linux driver and even the FreeBSD driver (what a piece of crap!) - and eventually spotted the nasty thing: the transmit routine was acknowledging each and every interrupt pending, including the RxOverrun and RxFIFIOver interrupts. This confused the RTL8139 thoroughly. It destroyed the Rx ring contents by dumping the 2K FIFO contents right where we wanted to get the next packet. Oh well, what fun. 18 Jan 2000 mdc@etherboot.org (Marty Connor) Drastically simplified error handling. Basically, if any error in transmission or reception occurs, the card is reset. Also, pointed all transmit descriptors to the same buffer to save buffer space. This should decrease driver size and avoid corruption because of exceeding 32K during runtime. 28 Jul 1999 (Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de) rtl_poll was quite broken: it used the RxOK interrupt flag instead of the RxBufferEmpty flag which often resulted in very bad transmission performace - below 1kBytes/s. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define TX_RING_SIZE 4 struct rtl8139_tx { unsigned int next; struct io_buffer *iobuf[TX_RING_SIZE]; }; struct rtl8139_rx { void *ring; unsigned int offset; }; struct rtl8139_nic { unsigned short ioaddr; struct rtl8139_tx tx; struct rtl8139_rx rx; struct spi_bit_basher spibit; struct spi_device eeprom; struct nvo_block nvo; }; /* Tuning Parameters */ #define TX_FIFO_THRESH 256 /* In bytes, rounded down to 32 byte units. */ #define RX_FIFO_THRESH 4 /* Rx buffer level before first PCI xfer. */ #define RX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 bytes */ #define TX_DMA_BURST 4 /* Calculate as 16<ioaddr + Cfg9346 ); return ( eereg & mask ); } static void rtl_spi_write_bit ( struct bit_basher *basher, unsigned int bit_id, unsigned long data ) { struct rtl8139_nic *rtl = container_of ( basher, struct rtl8139_nic, spibit.basher ); uint8_t mask = rtl_ee_bits[bit_id]; uint8_t eereg; eereg = inb ( rtl->ioaddr + Cfg9346 ); eereg &= ~mask; eereg |= ( data & mask ); outb ( eereg, rtl->ioaddr + Cfg9346 ); } static struct bit_basher_operations rtl_basher_ops = { .read = rtl_spi_read_bit, .write = rtl_spi_write_bit, }; /** Portion of EEPROM available for non-volatile stored options * * We use offset 0x40 (i.e. address 0x20), length 0x40. This block is * marked as VPD in the rtl8139 datasheets, so we use it only if we * detect that the card is not supporting VPD. */ static struct nvo_fragment rtl_nvo_fragments[] = { { 0x20, 0x40 }, { 0, 0 } }; /** * Set up for EEPROM access * * @v netdev Net device */ static void rtl_init_eeprom ( struct net_device *netdev ) { struct rtl8139_nic *rtl = netdev->priv; int ee9356; int vpd; /* Initialise three-wire bus */ rtl->spibit.basher.op = &rtl_basher_ops; rtl->spibit.bus.mode = SPI_MODE_THREEWIRE; init_spi_bit_basher ( &rtl->spibit ); /* Detect EEPROM type and initialise three-wire device */ ee9356 = ( inw ( rtl->ioaddr + RxConfig ) & Eeprom9356 ); if ( ee9356 ) { DBGC ( rtl, "rtl8139 %p EEPROM is an AT93C56\n", rtl ); init_at93c56 ( &rtl->eeprom, 16 ); } else { DBGC ( rtl, "rtl8139 %p EEPROM is an AT93C46\n", rtl ); init_at93c46 ( &rtl->eeprom, 16 ); } rtl->eeprom.bus = &rtl->spibit.bus; /* Initialise space for non-volatile options, if available */ vpd = ( inw ( rtl->ioaddr + Config1 ) & VPDEnable ); if ( vpd ) { DBGC ( rtl, "rtl8139 %p EEPROM in use for VPD; cannot use " "for options\n", rtl ); } else { nvo_init ( &rtl->nvo, &rtl->eeprom.nvs, rtl_nvo_fragments, &netdev->refcnt ); } } /** * Reset NIC * * @v netdev Net device * * Issues a hardware reset and waits for the reset to complete. */ static void rtl_reset ( struct net_device *netdev ) { struct rtl8139_nic *rtl = netdev->priv; /* Reset chip */ outb ( CmdReset, rtl->ioaddr + ChipCmd ); mdelay ( 10 ); memset ( &rtl->tx, 0, sizeof ( rtl->tx ) ); rtl->rx.offset = 0; } /** * Open NIC * * @v netdev Net device * @ret rc Return status code */ static int rtl_open ( struct net_device *netdev ) { struct rtl8139_nic *rtl = netdev->priv; int i; /* Program the MAC address */ for ( i = 0 ; i < ETH_ALEN ; i++ ) outb ( netdev->ll_addr[i], rtl->ioaddr + MAC0 + i ); /* Set up RX ring */ rtl->rx.ring = malloc ( RX_BUF_LEN + RX_BUF_PAD ); if ( ! rtl->rx.ring ) return -ENOMEM; outl ( virt_to_bus ( rtl->rx.ring ), rtl->ioaddr + RxBuf ); DBGC ( rtl, "rtl8139 %p RX ring at %lx\n", rtl, virt_to_bus ( rtl->rx.ring ) ); /* Enable TX and RX */ outb ( ( CmdRxEnb | CmdTxEnb ), rtl->ioaddr + ChipCmd ); outl ( ( ( RX_FIFO_THRESH << 13 ) | ( RX_BUF_LEN_IDX << 11 ) | ( RX_DMA_BURST << 8 ) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys ), rtl->ioaddr + RxConfig ); outl ( 0xffffffffUL, rtl->ioaddr + MAR0 + 0 ); outl ( 0xffffffffUL, rtl->ioaddr + MAR0 + 4 ); outl ( ( ( TX_DMA_BURST << 8 ) | ( TX_IPG << 24 ) ), rtl->ioaddr + TxConfig ); return 0; } /** * Close NIC * * @v netdev Net device */ static void rtl_close ( struct net_device *netdev ) { struct rtl8139_nic *rtl = netdev->priv; /* Reset the hardware to disable everything in one go */ rtl_reset ( netdev ); /* Free RX ring */ free ( rtl->rx.ring ); rtl->rx.ring = NULL; } /** * Transmit packet * * @v netdev Network device * @v iobuf I/O buffer * @ret rc Return status code */ static int rtl_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { struct rtl8139_nic *rtl = netdev->priv; /* Check for space in TX ring */ if ( rtl->tx.iobuf[rtl->tx.next] != NULL ) { DBGC ( rtl, "rtl8139 %p TX overflow\n", rtl ); return -ENOBUFS; } /* Pad and align packet */ iob_pad ( iobuf, ETH_ZLEN ); /* Add to TX ring */ DBGC2 ( rtl, "rtl8139 %p TX id %d at %lx+%zx\n", rtl, rtl->tx.next, virt_to_bus ( iobuf->data ), iob_len ( iobuf ) ); rtl->tx.iobuf[rtl->tx.next] = iobuf; outl ( virt_to_bus ( iobuf->data ), rtl->ioaddr + TxAddr0 + 4 * rtl->tx.next ); outl ( ( ( ( TX_FIFO_THRESH & 0x7e0 ) << 11 ) | iob_len ( iobuf ) ), rtl->ioaddr + TxStatus0 + 4 * rtl->tx.next ); rtl->tx.next = ( rtl->tx.next + 1 ) % TX_RING_SIZE; return 0; } /** * Poll for received packets * * @v netdev Network device */ static void rtl_poll ( struct net_device *netdev ) { struct rtl8139_nic *rtl = netdev->priv; unsigned int status; unsigned int tsad; unsigned int rx_status; unsigned int rx_len; struct io_buffer *rx_iob; int wrapped_len; int i; /* Acknowledge interrupts */ status = inw ( rtl->ioaddr + IntrStatus ); if ( ! status ) return; outw ( status, rtl->ioaddr + IntrStatus ); /* Handle TX completions */ tsad = inw ( rtl->ioaddr + TxSummary ); for ( i = 0 ; i < TX_RING_SIZE ; i++ ) { if ( ( rtl->tx.iobuf[i] != NULL ) && ( tsad & ( 1 << i ) ) ) { DBGC2 ( rtl, "rtl8139 %p TX id %d complete\n", rtl, i ); netdev_tx_complete ( netdev, rtl->tx.iobuf[i] ); rtl->tx.iobuf[i] = NULL; } } /* Handle received packets */ while ( ! ( inw ( rtl->ioaddr + ChipCmd ) & RxBufEmpty ) ) { rx_status = * ( ( uint16_t * ) ( rtl->rx.ring + rtl->rx.offset ) ); rx_len = * ( ( uint16_t * ) ( rtl->rx.ring + rtl->rx.offset + 2 ) ); if ( rx_status & RxOK ) { DBGC2 ( rtl, "rtl8139 %p RX packet at offset " "%x+%x\n", rtl, rtl->rx.offset, rx_len ); rx_iob = alloc_iob ( rx_len ); if ( ! rx_iob ) { netdev_rx_err ( netdev, NULL, -ENOMEM ); /* Leave packet for next call to poll() */ break; } wrapped_len = ( ( rtl->rx.offset + 4 + rx_len ) - RX_BUF_LEN ); if ( wrapped_len < 0 ) wrapped_len = 0; memcpy ( iob_put ( rx_iob, rx_len - wrapped_len ), rtl->rx.ring + rtl->rx.offset + 4, rx_len - wrapped_len ); memcpy ( iob_put ( rx_iob, wrapped_len ), rtl->rx.ring, wrapped_len ); netdev_rx ( netdev, rx_iob ); } else { DBGC ( rtl, "rtl8139 %p RX bad packet (status %#04x " "len %d)\n", rtl, rx_status, rx_len ); netdev_rx_err ( netdev, NULL, -EINVAL ); } rtl->rx.offset = ( ( ( rtl->rx.offset + 4 + rx_len + 3 ) & ~3 ) % RX_BUF_LEN ); outw ( rtl->rx.offset - 16, rtl->ioaddr + RxBufPtr ); } } /** * Enable/disable interrupts * * @v netdev Network device * @v enable Interrupts should be enabled */ static void rtl_irq ( struct net_device *netdev, int enable ) { struct rtl8139_nic *rtl = netdev->priv; DBGC ( rtl, "rtl8139 %p interrupts %s\n", rtl, ( enable ? "enabled" : "disabled" ) ); outw ( ( enable ? ( ROK | RER | TOK | TER ) : 0 ), rtl->ioaddr + IntrMask ); } /** RTL8139 net device operations */ static struct net_device_operations rtl_operations = { .open = rtl_open, .close = rtl_close, .transmit = rtl_transmit, .poll = rtl_poll, .irq = rtl_irq, }; /** * Probe PCI device * * @v pci PCI device * @v id PCI ID * @ret rc Return status code */ static int rtl_probe ( struct pci_device *pci, const struct pci_device_id *id __unused ) { struct net_device *netdev; struct rtl8139_nic *rtl; int rc; /* Allocate net device */ netdev = alloc_etherdev ( sizeof ( *rtl ) ); if ( ! netdev ) return -ENOMEM; netdev_init ( netdev, &rtl_operations ); rtl = netdev->priv; pci_set_drvdata ( pci, netdev ); netdev->dev = &pci->dev; memset ( rtl, 0, sizeof ( *rtl ) ); rtl->ioaddr = pci->ioaddr; /* Fix up PCI device */ adjust_pci_device ( pci ); /* Reset the NIC, set up EEPROM access and read MAC address */ rtl_reset ( netdev ); rtl_init_eeprom ( netdev ); nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->hw_addr, ETH_ALEN ); /* Mark as link up; we don't yet handle link state */ netdev_link_up ( netdev ); /* Register network device */ if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err_register_netdev; /* Register non-volatile storage */ if ( rtl->nvo.nvs ) { if ( ( rc = register_nvo ( &rtl->nvo, netdev_settings ( netdev ) ) ) != 0) goto err_register_nvo; } return 0; err_register_nvo: unregister_netdev ( netdev ); err_register_netdev: rtl_reset ( netdev ); netdev_nullify ( netdev ); netdev_put ( netdev ); return rc; } /** * Remove PCI device * * @v pci PCI device */ static void rtl_remove ( struct pci_device *pci ) { struct net_device *netdev = pci_get_drvdata ( pci ); struct rtl8139_nic *rtl = netdev->priv; if ( rtl->nvo.nvs ) unregister_nvo ( &rtl->nvo ); unregister_netdev ( netdev ); rtl_reset ( netdev ); netdev_nullify ( netdev ); netdev_put ( netdev ); } static struct pci_device_id rtl8139_nics[] = { PCI_ROM(0x10ec, 0x8129, "rtl8129", "Realtek 8129", 0), PCI_ROM(0x10ec, 0x8139, "rtl8139", "Realtek 8139", 0), PCI_ROM(0x10ec, 0x8138, "rtl8139b", "Realtek 8139B", 0), PCI_ROM(0x1186, 0x1300, "dfe538", "DFE530TX+/DFE538TX", 0), PCI_ROM(0x1113, 0x1211, "smc1211-1", "SMC EZ10/100", 0), PCI_ROM(0x1112, 0x1211, "smc1211", "SMC EZ10/100", 0), PCI_ROM(0x1500, 0x1360, "delta8139", "Delta Electronics 8139", 0), PCI_ROM(0x4033, 0x1360, "addtron8139", "Addtron Technology 8139", 0), PCI_ROM(0x1186, 0x1340, "dfe690txd", "D-Link DFE690TXD", 0), PCI_ROM(0x13d1, 0xab06, "fe2000vx", "AboCom FE2000VX", 0), PCI_ROM(0x1259, 0xa117, "allied8139", "Allied Telesyn 8139", 0), PCI_ROM(0x14ea, 0xab06, "fnw3603tx", "Planex FNW-3603-TX", 0), PCI_ROM(0x14ea, 0xab07, "fnw3800tx", "Planex FNW-3800-TX", 0), PCI_ROM(0xffff, 0x8139, "clone-rtl8139", "Cloned 8139", 0), }; struct pci_driver rtl8139_driver __pci_driver = { .ids = rtl8139_nics, .id_count = ( sizeof ( rtl8139_nics ) / sizeof ( rtl8139_nics[0] ) ), .probe = rtl_probe, .remove = rtl_remove, }; GRUB_MOD_LICENSE("GPLv2+"); GRUB_MOD_INIT(gpxe_rtl8139) { grub_gpxe_register_pci_nic (&rtl8139_driver); } GRUB_MOD_FINI(gpxe_rtl8139) { grub_gpxe_unregister_pci_nic (&rtl8139_driver); } debian/grub-extras/disabled/gpxe/src/drivers/net/b44.h0000664000000000000000000005326212524662415017761 0ustar /* * Copyright (c) 2008 Stefan Hajnoczi * Copyright (c) 2008 Pantelis Koukousoulas * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * This driver is a port of the b44 linux driver version 1.01 * * Copyright (c) 2002 David S. Miller * Copyright (c) Pekka Pietikainen * Copyright (C) 2006 Broadcom Corporation. * * Some ssb bits copied from version 2.0 of the b44 driver * Copyright (c) Michael Buesch * * Copyright (c) a lot of people too. Please respect their work. */ FILE_LICENCE ( GPL2_OR_LATER ); #ifndef _B44_H #define _B44_H /* BCM44xx Register layout */ #define B44_DEVCTRL 0x0000UL /* Device Control */ #define DEVCTRL_MPM 0x00000040 /* MP PME Enable (B0 only) */ #define DEVCTRL_PFE 0x00000080 /* Pattern Filtering Enable */ #define DEVCTRL_IPP 0x00000400 /* Internal EPHY Present */ #define DEVCTRL_EPR 0x00008000 /* EPHY Reset */ #define DEVCTRL_PME 0x00001000 /* PHY Mode Enable */ #define DEVCTRL_PMCE 0x00002000 /* PHY Mode Clocks Enable */ #define DEVCTRL_PADDR 0x0007c000 /* PHY Address */ #define DEVCTRL_PADDR_SHIFT 18 #define B44_BIST_STAT 0x000CUL /* Built-In Self-Test Status */ #define B44_WKUP_LEN 0x0010UL /* Wakeup Length */ #define WKUP_LEN_P0_MASK 0x0000007f /* Pattern 0 */ #define WKUP_LEN_D0 0x00000080 #define WKUP_LEN_P1_MASK 0x00007f00 /* Pattern 1 */ #define WKUP_LEN_P1_SHIFT 8 #define WKUP_LEN_D1 0x00008000 #define WKUP_LEN_P2_MASK 0x007f0000 /* Pattern 2 */ #define WKUP_LEN_P2_SHIFT 16 #define WKUP_LEN_D2 0x00000000 #define WKUP_LEN_P3_MASK 0x7f000000 /* Pattern 3 */ #define WKUP_LEN_P3_SHIFT 24 #define WKUP_LEN_D3 0x80000000 #define WKUP_LEN_DISABLE 0x80808080 #define WKUP_LEN_ENABLE_TWO 0x80800000 #define WKUP_LEN_ENABLE_THREE 0x80000000 #define B44_ISTAT 0x0020UL /* Interrupt Status */ #define ISTAT_LS 0x00000020 /* Link Change (B0 only) */ #define ISTAT_PME 0x00000040 /* Power Management Event */ #define ISTAT_TO 0x00000080 /* General Purpose Timeout */ #define ISTAT_DSCE 0x00000400 /* Descriptor Error */ #define ISTAT_DATAE 0x00000800 /* Data Error */ #define ISTAT_DPE 0x00001000 /* Descr. Protocol Error */ #define ISTAT_RDU 0x00002000 /* Receive Descr. Underflow */ #define ISTAT_RFO 0x00004000 /* Receive FIFO Overflow */ #define ISTAT_TFU 0x00008000 /* Transmit FIFO Underflow */ #define ISTAT_RX 0x00010000 /* RX Interrupt */ #define ISTAT_TX 0x01000000 /* TX Interrupt */ #define ISTAT_EMAC 0x04000000 /* EMAC Interrupt */ #define ISTAT_MII_WRITE 0x08000000 /* MII Write Interrupt */ #define ISTAT_MII_READ 0x10000000 /* MII Read Interrupt */ #define ISTAT_ERRORS (ISTAT_DSCE|ISTAT_DATAE|ISTAT_DPE|\ ISTAT_RDU|ISTAT_RFO|ISTAT_TFU) #define B44_IMASK 0x0024UL /* Interrupt Mask */ #define IMASK_DEF (ISTAT_ERRORS | ISTAT_RX | ISTAT_TX) #define IMASK_DISABLE 0 #define B44_GPTIMER 0x0028UL /* General Purpose Timer */ #define B44_ADDR_LO 0x0088UL /* ENET Address Lo (B0 only) */ #define B44_ADDR_HI 0x008CUL /* ENET Address Hi (B0 only) */ #define B44_FILT_ADDR 0x0090UL /* ENET Filter Address */ #define B44_FILT_DATA 0x0094UL /* ENET Filter Data */ #define B44_TXBURST 0x00A0UL /* TX Max Burst Length */ #define B44_RXBURST 0x00A4UL /* RX Max Burst Length */ #define B44_MAC_CTRL 0x00A8UL /* MAC Control */ #define MAC_CTRL_CRC32_ENAB 0x00000001 /* CRC32 Generation Enable */ #define MAC_CTRL_PHY_PDOWN 0x00000004 /* Onchip EPHY Powerdown */ #define MAC_CTRL_PHY_EDET 0x00000008 /* Onchip EPHY Energy Detected*/ #define MAC_CTRL_PHY_LEDCTRL 0x000000e0 /* Onchip EPHY LED Control */ #define MAC_CTRL_PHY_LEDCTRL_SHIFT 5 #define B44_MAC_FLOW 0x00ACUL /* MAC Flow Control */ #define MAC_FLOW_RX_HI_WATER 0x000000ff /* Receive FIFO HI Water Mark */ #define MAC_FLOW_PAUSE_ENAB 0x00008000 /* Enbl Pause Frm Generation */ #define B44_RCV_LAZY 0x0100UL /* Lazy Interrupt Control */ #define RCV_LAZY_TO_MASK 0x00ffffff /* Timeout */ #define RCV_LAZY_FC_MASK 0xff000000 /* Frame Count */ #define RCV_LAZY_FC_SHIFT 24 #define B44_DMATX_CTRL 0x0200UL /* DMA TX Control */ #define DMATX_CTRL_ENABLE 0x00000001 /* Enable */ #define DMATX_CTRL_SUSPEND 0x00000002 /* Suepend Request */ #define DMATX_CTRL_LPBACK 0x00000004 /* Loopback Enable */ #define DMATX_CTRL_FAIRPRIOR 0x00000008 /* Fair Priority */ #define DMATX_CTRL_FLUSH 0x00000010 /* Flush Request */ #define B44_DMATX_ADDR 0x0204UL /* DMA TX Descriptor Ring Addr */ #define B44_DMATX_PTR 0x0208UL /* DMA TX Last Posted Desc. */ #define B44_DMATX_STAT 0x020CUL /* DMA TX Cur Actve Desc. + Sts */ #define DMATX_STAT_CDMASK 0x00000fff /* Current Descriptor Mask */ #define DMATX_STAT_SMASK 0x0000f000 /* State Mask */ #define DMATX_STAT_SDISABLED 0x00000000 /* State Disabled */ #define DMATX_STAT_SACTIVE 0x00001000 /* State Active */ #define DMATX_STAT_SIDLE 0x00002000 /* State Idle Wait */ #define DMATX_STAT_SSTOPPED 0x00003000 /* State Stopped */ #define DMATX_STAT_SSUSP 0x00004000 /* State Suspend Pending */ #define DMATX_STAT_EMASK 0x000f0000 /* Error Mask */ #define DMATX_STAT_ENONE 0x00000000 /* Error None */ #define DMATX_STAT_EDPE 0x00010000 /* Error Desc. Protocol Error */ #define DMATX_STAT_EDFU 0x00020000 /* Error Data FIFO Underrun */ #define DMATX_STAT_EBEBR 0x00030000 /* Bus Error on Buffer Read */ #define DMATX_STAT_EBEDA 0x00040000 /* Bus Error on Desc. Access */ #define DMATX_STAT_FLUSHED 0x00100000 /* Flushed */ #define B44_DMARX_CTRL 0x0210UL /* DMA RX Control */ #define DMARX_CTRL_ENABLE 0x00000001 /* Enable */ #define DMARX_CTRL_ROMASK 0x000000fe /* Receive Offset Mask */ #define DMARX_CTRL_ROSHIFT 1 /* Receive Offset Shift */ #define B44_DMARX_ADDR 0x0214UL /* DMA RX Descriptor Ring Addr */ #define B44_DMARX_PTR 0x0218UL /* DMA RX Last Posted Desc */ #define B44_DMARX_STAT 0x021CUL /* Cur Active Desc. + Status */ #define DMARX_STAT_CDMASK 0x00000fff /* Current Descriptor Mask */ #define DMARX_STAT_SMASK 0x0000f000 /* State Mask */ #define DMARX_STAT_SDISABLED 0x00000000 /* State Disbaled */ #define DMARX_STAT_SACTIVE 0x00001000 /* State Active */ #define DMARX_STAT_SIDLE 0x00002000 /* State Idle Wait */ #define DMARX_STAT_SSTOPPED 0x00003000 /* State Stopped */ #define DMARX_STAT_EMASK 0x000f0000 /* Error Mask */ #define DMARX_STAT_ENONE 0x00000000 /* Error None */ #define DMARX_STAT_EDPE 0x00010000 /* Error Desc. Protocol Error */ #define DMARX_STAT_EDFO 0x00020000 /* Error Data FIFO Overflow */ #define DMARX_STAT_EBEBW 0x00030000 /* Error on Buffer Write */ #define DMARX_STAT_EBEDA 0x00040000 /* Bus Error on Desc. Access */ #define B44_DMAFIFO_AD 0x0220UL /* DMA FIFO Diag Address */ #define DMAFIFO_AD_OMASK 0x0000ffff /* Offset Mask */ #define DMAFIFO_AD_SMASK 0x000f0000 /* Select Mask */ #define DMAFIFO_AD_SXDD 0x00000000 /* Select Transmit DMA Data */ #define DMAFIFO_AD_SXDP 0x00010000 /* Sel Transmit DMA Pointers */ #define DMAFIFO_AD_SRDD 0x00040000 /* Select Receive DMA Data */ #define DMAFIFO_AD_SRDP 0x00050000 /* Sel Receive DMA Pointers */ #define DMAFIFO_AD_SXFD 0x00080000 /* Select Transmit FIFO Data */ #define DMAFIFO_AD_SXFP 0x00090000 /* Sel Transmit FIFO Pointers */ #define DMAFIFO_AD_SRFD 0x000c0000 /* Select Receive FIFO Data */ #define DMAFIFO_AD_SRFP 0x000c0000 /* Sel Receive FIFO Pointers */ #define B44_DMAFIFO_LO 0x0224UL /* DMA FIFO Diag Low Data */ #define B44_DMAFIFO_HI 0x0228UL /* DMA FIFO Diag High Data */ #define B44_RXCONFIG 0x0400UL /* EMAC RX Config */ #define RXCONFIG_DBCAST 0x00000001 /* Disable Broadcast */ #define RXCONFIG_ALLMULTI 0x00000002 /* Accept All Multicast */ #define RXCONFIG_NORX_WHILE_TX 0x00000004 /* Rcv Disble While TX */ #define RXCONFIG_PROMISC 0x00000008 /* Promiscuous Enable */ #define RXCONFIG_LPBACK 0x00000010 /* Loopback Enable */ #define RXCONFIG_FLOW 0x00000020 /* Flow Control Enable */ #define RXCONFIG_FLOW_ACCEPT 0x00000040 /* Accept UFC Frame */ #define RXCONFIG_RFILT 0x00000080 /* Reject Filter */ #define B44_RXMAXLEN 0x0404UL /* EMAC RX Max Packet Length */ #define B44_TXMAXLEN 0x0408UL /* EMAC TX Max Packet Length */ #define B44_MDIO_CTRL 0x0410UL /* EMAC MDIO Control */ #define MDIO_CTRL_MAXF_MASK 0x0000007f /* MDC Frequency */ #define MDIO_CTRL_PREAMBLE 0x00000080 /* MII Preamble Enable */ #define B44_MDIO_DATA 0x0414UL /* EMAC MDIO Data */ #define MDIO_DATA_DATA 0x0000ffff /* R/W Data */ #define MDIO_DATA_TA_MASK 0x00030000 /* Turnaround Value */ #define MDIO_DATA_TA_SHIFT 16 #define MDIO_TA_VALID 2 #define MDIO_DATA_RA_MASK 0x007c0000 /* Register Address */ #define MDIO_DATA_RA_SHIFT 18 #define MDIO_DATA_PMD_MASK 0x0f800000 /* Physical Media Device */ #define MDIO_DATA_PMD_SHIFT 23 #define MDIO_DATA_OP_MASK 0x30000000 /* Opcode */ #define MDIO_DATA_OP_SHIFT 28 #define MDIO_OP_WRITE 1 #define MDIO_OP_READ 2 #define MDIO_DATA_SB_MASK 0xc0000000 /* Start Bits */ #define MDIO_DATA_SB_SHIFT 30 #define MDIO_DATA_SB_START 0x40000000 /* Start Of Frame */ #define B44_EMAC_IMASK 0x0418UL /* EMAC Interrupt Mask */ #define B44_EMAC_ISTAT 0x041CUL /* EMAC Interrupt Status */ #define EMAC_INT_MII 0x00000001 /* MII MDIO Interrupt */ #define EMAC_INT_MIB 0x00000002 /* MIB Interrupt */ #define EMAC_INT_FLOW 0x00000003 /* Flow Control Interrupt */ #define B44_CAM_DATA_LO 0x0420UL /* EMAC CAM Data Low */ #define B44_CAM_DATA_HI 0x0424UL /* EMAC CAM Data High */ #define CAM_DATA_HI_VALID 0x00010000 /* Valid Bit */ #define B44_CAM_CTRL 0x0428UL /* EMAC CAM Control */ #define CAM_CTRL_ENABLE 0x00000001 /* CAM Enable */ #define CAM_CTRL_MSEL 0x00000002 /* Mask Select */ #define CAM_CTRL_READ 0x00000004 /* Read */ #define CAM_CTRL_WRITE 0x00000008 /* Read */ #define CAM_CTRL_INDEX_MASK 0x003f0000 /* Index Mask */ #define CAM_CTRL_INDEX_SHIFT 16 #define CAM_CTRL_BUSY 0x80000000 /* CAM Busy */ #define B44_ENET_CTRL 0x042CUL /* EMAC ENET Control */ #define ENET_CTRL_ENABLE 0x00000001 /* EMAC Enable */ #define ENET_CTRL_DISABLE 0x00000002 /* EMAC Disable */ #define ENET_CTRL_SRST 0x00000004 /* EMAC Soft Reset */ #define ENET_CTRL_EPSEL 0x00000008 /* External PHY Select */ #define B44_TX_CTRL 0x0430UL /* EMAC TX Control */ #define TX_CTRL_DUPLEX 0x00000001 /* Full Duplex */ #define TX_CTRL_FMODE 0x00000002 /* Flow Mode */ #define TX_CTRL_SBENAB 0x00000004 /* Single Backoff Enable */ #define TX_CTRL_SMALL_SLOT 0x00000008 /* Small Slottime */ #define B44_TX_HIWMARK 0x0434UL /* EMAC TX High Watermark */ #define TX_HIWMARK_DEFLT 56 /* Default used in all drivers */ #define B44_MIB_CTRL 0x0438UL /* EMAC MIB Control */ #define MIB_CTRL_CLR_ON_READ 0x00000001 /* Autoclear on Read */ #define B44_TX_GOOD_O 0x0500UL /* MIB TX Good Octets */ #define B44_TX_GOOD_P 0x0504UL /* MIB TX Good Packets */ #define B44_TX_O 0x0508UL /* MIB TX Octets */ #define B44_TX_P 0x050CUL /* MIB TX Packets */ #define B44_TX_BCAST 0x0510UL /* MIB TX Broadcast Packets */ #define B44_TX_MCAST 0x0514UL /* MIB TX Multicast Packets */ #define B44_TX_64 0x0518UL /* MIB TX <= 64 byte Packets */ #define B44_TX_65_127 0x051CUL /* MIB TX 65 to 127 byte Pkts */ #define B44_TX_128_255 0x0520UL /* MIB TX 128 to 255 byte Pkts */ #define B44_TX_256_511 0x0524UL /* MIB TX 256 to 511 byte Pkts */ #define B44_TX_512_1023 0x0528UL /* MIB TX 512 to 1023 byte Pkts */ #define B44_TX_1024_MAX 0x052CUL /* MIB TX 1024 to max byte Pkts */ #define B44_TX_JABBER 0x0530UL /* MIB TX Jabber Packets */ #define B44_TX_OSIZE 0x0534UL /* MIB TX Oversize Packets */ #define B44_TX_FRAG 0x0538UL /* MIB TX Fragment Packets */ #define B44_TX_URUNS 0x053CUL /* MIB TX Underruns */ #define B44_TX_TCOLS 0x0540UL /* MIB TX Total Collisions */ #define B44_TX_SCOLS 0x0544UL /* MIB TX Single Collisions */ #define B44_TX_MCOLS 0x0548UL /* MIB TX Multiple Collisions */ #define B44_TX_ECOLS 0x054CUL /* MIB TX Excessive Collisions */ #define B44_TX_LCOLS 0x0550UL /* MIB TX Late Collisions */ #define B44_TX_DEFERED 0x0554UL /* MIB TX Defered Packets */ #define B44_TX_CLOST 0x0558UL /* MIB TX Carrier Lost */ #define B44_TX_PAUSE 0x055CUL /* MIB TX Pause Packets */ #define B44_RX_GOOD_O 0x0580UL /* MIB RX Good Octets */ #define B44_RX_GOOD_P 0x0584UL /* MIB RX Good Packets */ #define B44_RX_O 0x0588UL /* MIB RX Octets */ #define B44_RX_P 0x058CUL /* MIB RX Packets */ #define B44_RX_BCAST 0x0590UL /* MIB RX Broadcast Packets */ #define B44_RX_MCAST 0x0594UL /* MIB RX Multicast Packets */ #define B44_RX_64 0x0598UL /* MIB RX <= 64 byte Packets */ #define B44_RX_65_127 0x059CUL /* MIB RX 65 to 127 byte Pkts */ #define B44_RX_128_255 0x05A0UL /* MIB RX 128 to 255 byte Pkts */ #define B44_RX_256_511 0x05A4UL /* MIB RX 256 to 511 byte Pkts */ #define B44_RX_512_1023 0x05A8UL /* MIB RX 512 to 1023 byte Pkts */ #define B44_RX_1024_MAX 0x05ACUL /* MIB RX 1024 to max byte Pkts */ #define B44_RX_JABBER 0x05B0UL /* MIB RX Jabber Packets */ #define B44_RX_OSIZE 0x05B4UL /* MIB RX Oversize Packets */ #define B44_RX_FRAG 0x05B8UL /* MIB RX Fragment Packets */ #define B44_RX_MISS 0x05BCUL /* MIB RX Missed Packets */ #define B44_RX_CRCA 0x05C0UL /* MIB RX CRC Align Errors */ #define B44_RX_USIZE 0x05C4UL /* MIB RX Undersize Packets */ #define B44_RX_CRC 0x05C8UL /* MIB RX CRC Errors */ #define B44_RX_ALIGN 0x05CCUL /* MIB RX Align Errors */ #define B44_RX_SYM 0x05D0UL /* MIB RX Symbol Errors */ #define B44_RX_PAUSE 0x05D4UL /* MIB RX Pause Packets */ #define B44_RX_NPAUSE 0x05D8UL /* MIB RX Non-Pause Packets */ /* Sonics Silicon backplane register definitions */ #define B44_SBIMSTATE 0x0F90UL /* SB Initiator Agent State */ #define SBIMSTATE_PC 0x0000000f /* Pipe Count */ #define SBIMSTATE_AP_MASK 0x00000030 /* Arbitration Priority */ #define SBIMSTATE_AP_BOTH 0x00000000 /* both timeslices and token */ #define SBIMSTATE_AP_TS 0x00000010 /* Use timeslices only */ #define SBIMSTATE_AP_TK 0x00000020 /* Use token only */ #define SBIMSTATE_AP_RSV 0x00000030 /* Reserved */ #define SBIMSTATE_IBE 0x00020000 /* In Band Error */ #define SBIMSTATE_TO 0x00040000 /* Timeout */ #define SBIMSTATE_BAD ( SBIMSTATE_IBE | SBIMSTATE_TO ) #define B44_SBINTVEC 0x0F94UL /* SB Interrupt Mask */ #define SBINTVEC_PCI 0x00000001 /* Enable interrupts for PCI */ #define SBINTVEC_ENET0 0x00000002 /* Enable ints for enet 0 */ #define SBINTVEC_ILINE20 0x00000004 /* Enable ints for iline20 */ #define SBINTVEC_CODEC 0x00000008 /* Enable ints for v90 codec */ #define SBINTVEC_USB 0x00000010 /* Enable intts for usb */ #define SBINTVEC_EXTIF 0x00000020 /* Enable ints for ext i/f */ #define SBINTVEC_ENET1 0x00000040 /* Enable ints for enet 1 */ #define B44_SBTMSLOW 0x0F98UL /* SB Target State Low */ #define SBTMSLOW_RESET 0x00000001 /* Reset */ #define SBTMSLOW_REJECT 0x00000002 /* Reject */ #define SBTMSLOW_CLOCK 0x00010000 /* Clock Enable */ #define SBTMSLOW_FGC 0x00020000 /* Force Gated Clocks On */ #define SBTMSLOW_PE 0x40000000 /* Power Management Enable */ #define SBTMSLOW_BE 0x80000000 /* BIST Enable */ #define B44_SBTMSHIGH 0x0F9CUL /* SB Target State High */ #define SBTMSHIGH_SERR 0x00000001 /* S-error */ #define SBTMSHIGH_INT 0x00000002 /* Interrupt */ #define SBTMSHIGH_BUSY 0x00000004 /* Busy */ #define SBTMSHIGH_GCR 0x20000000 /* Gated Clock Request */ #define SBTMSHIGH_BISTF 0x40000000 /* BIST Failed */ #define SBTMSHIGH_BISTD 0x80000000 /* BIST Done */ #define B44_SBIDHIGH 0x0FFCUL /* SB Identification High */ #define SBIDHIGH_RC_MASK 0x0000000f /* Revision Code */ #define SBIDHIGH_CC_MASK 0x0000fff0 /* Core Code */ #define SBIDHIGH_CC_SHIFT 4 #define SBIDHIGH_VC_MASK 0xffff0000 /* Vendor Code */ #define SBIDHIGH_VC_SHIFT 16 /* SSB PCI config space registers. */ #define SSB_PMCSR 0x44 #define SSB_PE 0x100 #define SSB_BAR0_WIN 0x80 #define SSB_BAR1_WIN 0x84 #define SSB_SPROM_CONTROL 0x88 #define SSB_BAR1_CONTROL 0x8c /* SSB core and host control registers. */ #define SSB_CONTROL 0x0000UL #define SSB_ARBCONTROL 0x0010UL #define SSB_ISTAT 0x0020UL #define SSB_IMASK 0x0024UL #define SSB_MBOX 0x0028UL #define SSB_BCAST_ADDR 0x0050UL #define SSB_BCAST_DATA 0x0054UL #define SSB_PCI_TRANS_0 0x0100UL #define SSB_PCI_TRANS_1 0x0104UL #define SSB_PCI_TRANS_2 0x0108UL #define SSB_SPROM 0x0800UL #define SSB_PCI_MEM 0x00000000 #define SSB_PCI_IO 0x00000001 #define SSB_PCI_CFG0 0x00000002 #define SSB_PCI_CFG1 0x00000003 #define SSB_PCI_PREF 0x00000004 #define SSB_PCI_BURST 0x00000008 #define SSB_PCI_MASK0 0xfc000000 #define SSB_PCI_MASK1 0xfc000000 #define SSB_PCI_MASK2 0xc0000000 /* 4400 PHY registers */ #define B44_MII_AUXCTRL 24 /* Auxiliary Control */ #define MII_AUXCTRL_DUPLEX 0x0001 /* Full Duplex */ #define MII_AUXCTRL_SPEED 0x0002 /* 1=100Mbps, 0=10Mbps */ #define MII_AUXCTRL_FORCED 0x0004 /* Forced 10/100 */ #define B44_MII_ALEDCTRL 26 /* Activity LED */ #define MII_ALEDCTRL_ALLMSK 0x7fff #define B44_MII_TLEDCTRL 27 /* Traffic Meter LED */ #define MII_TLEDCTRL_ENABLE 0x0040 /* RX/TX descriptor */ struct dma_desc { u32 ctrl; /* length of data and flags */ u32 addr; /* address of data */ }; /* There are only 12 bits in the DMA engine for descriptor offsetting * so the table must be aligned on a boundary of this. */ #define B44_DMA_ALIGNMENT 4096 /* The DMA engine can only address the first gigabyte of address space */ #define B44_30BIT_DMA_MASK 0x3fffffff #define DESC_CTRL_LEN 0x00001fff #define DESC_CTRL_CMASK 0x0ff00000 /* Core specific bits */ #define DESC_CTRL_EOT 0x10000000 /* End of Table */ #define DESC_CTRL_IOC 0x20000000 /* Interrupt On Completion */ #define DESC_CTRL_EOF 0x40000000 /* End of Frame */ #define DESC_CTRL_SOF 0x80000000 /* Start of Frame */ struct rx_header { u16 len; u16 flags; u16 pad[12]; }; #define RX_HEADER_LEN 28 #define RX_FLAG_OFIFO 0x00000001 /* FIFO Overflow */ #define RX_FLAG_CRCERR 0x00000002 /* CRC Error */ #define RX_FLAG_SERR 0x00000004 /* Receive Symbol Error */ #define RX_FLAG_ODD 0x00000008 /* Frame has odd number of nibbles */ #define RX_FLAG_LARGE 0x00000010 /* Frame is > RX MAX Length */ #define RX_FLAG_MCAST 0x00000020 /* Dest is Multicast Address */ #define RX_FLAG_BCAST 0x00000040 /* Dest is Broadcast Address */ #define RX_FLAG_MISS 0x00000080 /* Received due to promisc mode */ #define RX_FLAG_LAST 0x00000800 /* Last buffer in frame */ #define RX_FLAG_ERRORS (RX_FLAG_ODD | RX_FLAG_SERR |\ RX_FLAG_CRCERR | RX_FLAG_OFIFO) /* Client Mode PCI memory access space (1 GB) */ #define SB_PCI_DMA 0x40000000 /* Address of PCI core on BCM4400 cards */ #define BCM4400_PCI_CORE_ADDR 0x18002000 /* Hardware minimum and maximum for a single frame's data payload */ #define B44_MIN_MTU 60 #define B44_MAX_MTU 1500 #define B44_RING_SIZE 8 #define B44_RING_LAST ( B44_RING_SIZE - 1 ) #define B44_RX_RING_LEN_BYTES ( sizeof bp->rx[0] * B44_RING_SIZE ) #define B44_TX_RING_LEN_BYTES ( sizeof bp->tx[0] * B44_RING_SIZE ) #define RX_PKT_OFFSET 30 #define RX_PKT_BUF_SZ (1536 + RX_PKT_OFFSET + 64) #define B44_FULL_RESET 1 #define B44_FULL_RESET_SKIP_PHY 2 #define B44_PARTIAL_RESET 3 #define B44_CHIP_RESET_FULL 4 #define B44_CHIP_RESET_PARTIAL 5 #define SSB_CORE_DOWN ( SBTMSLOW_RESET | SBTMSLOW_REJECT ) #define B44_REGS_SIZE 8192 /** Driver private state */ struct b44_private { struct net_device *netdev; struct pci_device *pci; u8 *regs; /* memory-mapped registers */ u8 phy_addr; struct dma_desc *tx; struct io_buffer *tx_iobuf[B44_RING_SIZE]; u32 tx_cur; /* next available descriptor */ u32 tx_dirty; /* oldest pending descriptor */ struct dma_desc *rx; struct io_buffer *rx_iobuf[B44_RING_SIZE]; u32 rx_cur; /* next descriptor to read */ }; static void ssb_core_reset ( struct b44_private *bp ); static void ssb_core_disable ( struct b44_private *bp ); static u32 ssb_pci_setup ( struct b44_private *bp, u32 cores ); static void b44_chip_reset ( struct b44_private *bp, int reset_kind ); static void b44_init_hw ( struct b44_private *bp, int reset_kind ); static void b44_cam_write ( struct b44_private *bp, u8 *data, int index ); static void b44_set_mac_addr ( struct b44_private *bp ); static void b44_set_rx_mode ( struct net_device *netdev ); static void b44_halt(struct b44_private *); static int b44_phy_reset ( struct b44_private *bp ); static int b44_phy_write ( struct b44_private *bp, int reg, u32 val ); static int b44_phy_read ( struct b44_private *bp, int reg, u32 *val ); static int b44_init_tx_ring ( struct b44_private *bp ); static void b44_free_tx_ring ( struct b44_private *bp ); static int b44_init_rx_ring ( struct b44_private *bp ); static void b44_free_rx_ring ( struct b44_private *bp ); static void b44_rx_refill ( struct b44_private *bp, u32 pending ); static void b44_populate_rx_descriptor (struct b44_private *bp, u32 index); static int b44_probe ( struct pci_device *pci, const struct pci_device_id *id ); static void b44_remove ( struct pci_device *pci ); static int b44_open ( struct net_device *netdev ); static void b44_close ( struct net_device *netdev ); static void b44_irq ( struct net_device *netdev, int enable ); static void b44_poll ( struct net_device *netdev ); static void b44_process_rx_packets ( struct b44_private *bp ); static int b44_transmit ( struct net_device *netdev, struct io_buffer *iobuf ); static struct net_device_operations b44_operations; #endif /* _B44_H */ debian/grub-extras/disabled/gpxe/src/drivers/net/b44.c0000664000000000000000000005201212524662415017744 0ustar /* * Copyright (c) 2008 Stefan Hajnoczi * Copyright (c) 2008 Pantelis Koukousoulas * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * This driver is a port of the b44 linux driver version 1.01 * * Copyright (c) 2002 David S. Miller * Copyright (c) Pekka Pietikainen * Copyright (C) 2006 Broadcom Corporation. * * Some ssb bits copied from version 2.0 of the b44 driver * Copyright (c) Michael Buesch * * Copyright (c) a lot of people too. Please respect their work. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "b44.h" static inline int ring_next(int index) { /* B44_RING_SIZE is a power of 2 :) */ return (index + 1) & (B44_RING_SIZE - 1); } /* Memory-mapped I/O wrappers */ static inline u32 br32(const struct b44_private *bp, u32 reg) { return readl(bp->regs + reg); } static inline void bw32(const struct b44_private *bp, u32 reg, u32 val) { writel(val, bp->regs + reg); } static inline void bflush(const struct b44_private *bp, u32 reg, u32 timeout) { readl(bp->regs + reg); udelay(timeout); } #define VIRT_TO_B44(addr) ( virt_to_bus(addr) + SB_PCI_DMA ) /** * Return non-zero if the installed RAM is within * the limit given and zero if it is outside. * Hopefully will be removed soon. */ int phys_ram_within_limit(u64 limit) { struct memory_map memmap; struct memory_region *highest = NULL; get_memmap(&memmap); highest = &memmap.regions[memmap.count - 1]; return (highest->end < limit); } /** * Ring cells waiting to be processed are between 'tx_cur' and 'pending' * indexes in the ring. */ static u32 pending_tx_index(struct b44_private *bp) { u32 pending = br32(bp, B44_DMATX_STAT); pending &= DMATX_STAT_CDMASK; pending /= sizeof(struct dma_desc); return pending & (B44_RING_SIZE - 1); } /** * Ring cells waiting to be processed are between 'rx_cur' and 'pending' * indexes in the ring. */ static u32 pending_rx_index(struct b44_private *bp) { u32 pending = br32(bp, B44_DMARX_STAT); pending &= DMARX_STAT_CDMASK; pending /= sizeof(struct dma_desc); return pending & (B44_RING_SIZE - 1); } /** * Wait until the given bit is set/cleared. */ static int b44_wait_bit(struct b44_private *bp, unsigned long reg, u32 bit, unsigned long timeout, const int clear) { unsigned long i; for (i = 0; i < timeout; i++) { u32 val = br32(bp, reg); if (clear && !(val & bit)) break; if (!clear && (val & bit)) break; udelay(10); } if (i == timeout) { return -ENODEV; } return 0; } /* * Sonics Silicon Backplane support. SSB is a mini-bus interconnecting * so-called IP Cores. One of those cores implements the Fast Ethernet * functionality and another one the PCI engine. * * You need to switch to the core you want to talk to before actually * sending commands. * * See: http://bcm-v4.sipsolutions.net/Backplane for (reverse-engineered) * specs. */ static inline u32 ssb_get_core_rev(struct b44_private *bp) { return (br32(bp, B44_SBIDHIGH) & SBIDHIGH_RC_MASK); } static inline int ssb_is_core_up(struct b44_private *bp) { return ((br32(bp, B44_SBTMSLOW) & (SSB_CORE_DOWN | SBTMSLOW_CLOCK)) == SBTMSLOW_CLOCK); } static u32 ssb_pci_setup(struct b44_private *bp, u32 cores) { u32 bar_orig, pci_rev, val; pci_read_config_dword(bp->pci, SSB_BAR0_WIN, &bar_orig); pci_write_config_dword(bp->pci, SSB_BAR0_WIN, BCM4400_PCI_CORE_ADDR); pci_rev = ssb_get_core_rev(bp); val = br32(bp, B44_SBINTVEC); val |= cores; bw32(bp, B44_SBINTVEC, val); val = br32(bp, SSB_PCI_TRANS_2); val |= SSB_PCI_PREF | SSB_PCI_BURST; bw32(bp, SSB_PCI_TRANS_2, val); pci_write_config_dword(bp->pci, SSB_BAR0_WIN, bar_orig); return pci_rev; } static void ssb_core_disable(struct b44_private *bp) { if (br32(bp, B44_SBTMSLOW) & SBTMSLOW_RESET) return; bw32(bp, B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_CLOCK)); b44_wait_bit(bp, B44_SBTMSLOW, SBTMSLOW_REJECT, 100000, 0); b44_wait_bit(bp, B44_SBTMSHIGH, SBTMSHIGH_BUSY, 100000, 1); bw32(bp, B44_SBTMSLOW, (SBTMSLOW_FGC | SBTMSLOW_CLOCK | SSB_CORE_DOWN)); bflush(bp, B44_SBTMSLOW, 1); bw32(bp, B44_SBTMSLOW, SSB_CORE_DOWN); bflush(bp, B44_SBTMSLOW, 1); } static void ssb_core_reset(struct b44_private *bp) { u32 val; const u32 mask = (SBTMSLOW_CLOCK | SBTMSLOW_FGC | SBTMSLOW_RESET); ssb_core_disable(bp); bw32(bp, B44_SBTMSLOW, mask); bflush(bp, B44_SBTMSLOW, 1); /* Clear SERR if set, this is a hw bug workaround. */ if (br32(bp, B44_SBTMSHIGH) & SBTMSHIGH_SERR) bw32(bp, B44_SBTMSHIGH, 0); val = br32(bp, B44_SBIMSTATE); if (val & (SBIMSTATE_BAD)) { bw32(bp, B44_SBIMSTATE, val & ~SBIMSTATE_BAD); } bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK | SBTMSLOW_FGC)); bflush(bp, B44_SBTMSLOW, 1); bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK)); bflush(bp, B44_SBTMSLOW, 1); } /* * Driver helper functions */ /* * Chip reset provides power to the b44 MAC & PCI cores, which * is necessary for MAC register access. We only do a partial * reset in case of transmit/receive errors (ISTAT_ERRORS) to * avoid the chip being hung for an unnecessary long time in * this case. * * Called-by: b44_close, b44_halt, b44_inithw(b44_open), b44_probe */ static void b44_chip_reset(struct b44_private *bp, int reset_kind) { if (ssb_is_core_up(bp)) { bw32(bp, B44_RCV_LAZY, 0); bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE); b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 200, 1); bw32(bp, B44_DMATX_CTRL, 0); bp->tx_dirty = bp->tx_cur = 0; if (br32(bp, B44_DMARX_STAT) & DMARX_STAT_EMASK) b44_wait_bit(bp, B44_DMARX_STAT, DMARX_STAT_SIDLE, 100, 0); bw32(bp, B44_DMARX_CTRL, 0); bp->rx_cur = 0; } else { ssb_pci_setup(bp, SBINTVEC_ENET0); } ssb_core_reset(bp); /* Don't enable PHY if we are only doing a partial reset. */ if (reset_kind == B44_CHIP_RESET_PARTIAL) return; /* Make PHY accessible. */ bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE | (0x0d & MDIO_CTRL_MAXF_MASK))); bflush(bp, B44_MDIO_CTRL, 1); /* Enable internal or external PHY */ if (!(br32(bp, B44_DEVCTRL) & DEVCTRL_IPP)) { bw32(bp, B44_ENET_CTRL, ENET_CTRL_EPSEL); bflush(bp, B44_ENET_CTRL, 1); } else { u32 val = br32(bp, B44_DEVCTRL); if (val & DEVCTRL_EPR) { bw32(bp, B44_DEVCTRL, (val & ~DEVCTRL_EPR)); bflush(bp, B44_DEVCTRL, 100); } } } /** * called by b44_poll in the error path */ static void b44_halt(struct b44_private *bp) { /* disable ints */ bw32(bp, B44_IMASK, 0); bflush(bp, B44_IMASK, 1); DBG("b44: powering down PHY\n"); bw32(bp, B44_MAC_CTRL, MAC_CTRL_PHY_PDOWN); /* * Now reset the chip, but without enabling * the MAC&PHY part of it. * This has to be done _after_ we shut down the PHY */ b44_chip_reset(bp, B44_CHIP_RESET_PARTIAL); } /* * Called at device open time to get the chip ready for * packet processing. * * Called-by: b44_open */ static void b44_init_hw(struct b44_private *bp, int reset_kind) { u32 val; #define CTRL_MASK (DMARX_CTRL_ENABLE | (RX_PKT_OFFSET << DMARX_CTRL_ROSHIFT)) b44_chip_reset(bp, B44_CHIP_RESET_FULL); if (reset_kind == B44_FULL_RESET) { b44_phy_reset(bp); } /* Enable CRC32, set proper LED modes and power on PHY */ bw32(bp, B44_MAC_CTRL, MAC_CTRL_CRC32_ENAB | MAC_CTRL_PHY_LEDCTRL); bw32(bp, B44_RCV_LAZY, (1 << RCV_LAZY_FC_SHIFT)); /* This sets the MAC address too. */ b44_set_rx_mode(bp->netdev); /* MTU + eth header + possible VLAN tag + struct rx_header */ bw32(bp, B44_RXMAXLEN, B44_MAX_MTU + ETH_HLEN + 8 + RX_HEADER_LEN); bw32(bp, B44_TXMAXLEN, B44_MAX_MTU + ETH_HLEN + 8 + RX_HEADER_LEN); bw32(bp, B44_TX_HIWMARK, TX_HIWMARK_DEFLT); if (reset_kind == B44_PARTIAL_RESET) { bw32(bp, B44_DMARX_CTRL, CTRL_MASK); } else { bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); bw32(bp, B44_DMATX_ADDR, VIRT_TO_B44(bp->tx)); bw32(bp, B44_DMARX_CTRL, CTRL_MASK); bw32(bp, B44_DMARX_ADDR, VIRT_TO_B44(bp->rx)); bw32(bp, B44_DMARX_PTR, B44_RX_RING_LEN_BYTES); bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); } val = br32(bp, B44_ENET_CTRL); bw32(bp, B44_ENET_CTRL, (val | ENET_CTRL_ENABLE)); #undef CTRL_MASK } /*** Management of ring descriptors ***/ static void b44_populate_rx_descriptor(struct b44_private *bp, u32 idx) { struct rx_header *rh; u32 ctrl, addr; rh = bp->rx_iobuf[idx]->data; rh->len = 0; rh->flags = 0; ctrl = DESC_CTRL_LEN & (RX_PKT_BUF_SZ - RX_PKT_OFFSET); if (idx == B44_RING_LAST) { ctrl |= DESC_CTRL_EOT; } addr = VIRT_TO_B44(bp->rx_iobuf[idx]->data); bp->rx[idx].ctrl = cpu_to_le32(ctrl); bp->rx[idx].addr = cpu_to_le32(addr); bw32(bp, B44_DMARX_PTR, idx * sizeof(struct dma_desc)); } /* * Refill RX ring descriptors with buffers. This is needed * because during rx we are passing ownership of descriptor * buffers to the network stack. */ static void b44_rx_refill(struct b44_private *bp, u32 pending) { u32 i; // skip pending for (i = pending + 1; i != bp->rx_cur; i = ring_next(i)) { if (bp->rx_iobuf[i] != NULL) continue; bp->rx_iobuf[i] = alloc_iob(RX_PKT_BUF_SZ); if (!bp->rx_iobuf[i]) { DBG("Refill rx ring failed!!\n"); break; } b44_populate_rx_descriptor(bp, i); } } static void b44_free_rx_ring(struct b44_private *bp) { u32 i; if (bp->rx) { for (i = 0; i < B44_RING_SIZE; i++) { free_iob(bp->rx_iobuf[i]); bp->rx_iobuf[i] = NULL; } free_dma(bp->rx, B44_RX_RING_LEN_BYTES); bp->rx = NULL; } } static int b44_init_rx_ring(struct b44_private *bp) { b44_free_rx_ring(bp); bp->rx = malloc_dma(B44_RX_RING_LEN_BYTES, B44_DMA_ALIGNMENT); if (!bp->rx) return -ENOMEM; memset(bp->rx_iobuf, 0, sizeof(bp->rx_iobuf)); bp->rx_iobuf[0] = alloc_iob(RX_PKT_BUF_SZ); b44_populate_rx_descriptor(bp, 0); b44_rx_refill(bp, 0); DBG("Init RX rings: rx=0x%08lx\n", VIRT_TO_B44(bp->rx)); return 0; } static void b44_free_tx_ring(struct b44_private *bp) { if (bp->tx) { free_dma(bp->tx, B44_TX_RING_LEN_BYTES); bp->tx = NULL; } } static int b44_init_tx_ring(struct b44_private *bp) { b44_free_tx_ring(bp); bp->tx = malloc_dma(B44_TX_RING_LEN_BYTES, B44_DMA_ALIGNMENT); if (!bp->tx) return -ENOMEM; memset(bp->tx, 0, B44_TX_RING_LEN_BYTES); memset(bp->tx_iobuf, 0, sizeof(bp->tx_iobuf)); DBG("Init TX rings: tx=0x%08lx\n", VIRT_TO_B44(bp->tx)); return 0; } /*** Interaction with the PHY ***/ static int b44_phy_read(struct b44_private *bp, int reg, u32 * val) { int err; u32 arg1 = (MDIO_OP_READ << MDIO_DATA_OP_SHIFT); u32 arg2 = (bp->phy_addr << MDIO_DATA_PMD_SHIFT); u32 arg3 = (reg << MDIO_DATA_RA_SHIFT); u32 arg4 = (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT); u32 argv = arg1 | arg2 | arg3 | arg4; bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII); bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START | argv)); err = b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0); *val = br32(bp, B44_MDIO_DATA) & MDIO_DATA_DATA; return err; } static int b44_phy_write(struct b44_private *bp, int reg, u32 val) { u32 arg1 = (MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT); u32 arg2 = (bp->phy_addr << MDIO_DATA_PMD_SHIFT); u32 arg3 = (reg << MDIO_DATA_RA_SHIFT); u32 arg4 = (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT); u32 arg5 = (val & MDIO_DATA_DATA); u32 argv = arg1 | arg2 | arg3 | arg4 | arg5; bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII); bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START | argv)); return b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0); } static int b44_phy_reset(struct b44_private *bp) { u32 val; int err; err = b44_phy_write(bp, MII_BMCR, BMCR_RESET); if (err) return err; udelay(100); err = b44_phy_read(bp, MII_BMCR, &val); if (!err) { if (val & BMCR_RESET) { return -ENODEV; } } return 0; } /* * The BCM44xx CAM (Content Addressable Memory) stores the MAC * and PHY address. */ static void b44_cam_write(struct b44_private *bp, unsigned char *data, int index) { u32 val; val = ((u32) data[2]) << 24; val |= ((u32) data[3]) << 16; val |= ((u32) data[4]) << 8; val |= ((u32) data[5]) << 0; bw32(bp, B44_CAM_DATA_LO, val); val = (CAM_DATA_HI_VALID | (((u32) data[0]) << 8) | (((u32) data[1]) << 0)); bw32(bp, B44_CAM_DATA_HI, val); val = CAM_CTRL_WRITE | (index << CAM_CTRL_INDEX_SHIFT); bw32(bp, B44_CAM_CTRL, val); b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1); } static void b44_set_mac_addr(struct b44_private *bp) { u32 val; bw32(bp, B44_CAM_CTRL, 0); b44_cam_write(bp, bp->netdev->ll_addr, 0); val = br32(bp, B44_CAM_CTRL); bw32(bp, B44_CAM_CTRL, val | CAM_CTRL_ENABLE); } /* Read 128-bytes of EEPROM. */ static void b44_read_eeprom(struct b44_private *bp, u8 * data) { long i; u16 *ptr = (u16 *) data; for (i = 0; i < 128; i += 2) ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i)); } static void b44_load_mac_and_phy_addr(struct b44_private *bp) { u8 eeprom[128]; /* Load MAC address, note byteswapping */ b44_read_eeprom(bp, &eeprom[0]); bp->netdev->hw_addr[0] = eeprom[79]; bp->netdev->hw_addr[1] = eeprom[78]; bp->netdev->hw_addr[2] = eeprom[81]; bp->netdev->hw_addr[3] = eeprom[80]; bp->netdev->hw_addr[4] = eeprom[83]; bp->netdev->hw_addr[5] = eeprom[82]; /* Load PHY address */ bp->phy_addr = eeprom[90] & 0x1f; } static void b44_set_rx_mode(struct net_device *netdev) { struct b44_private *bp = netdev_priv(netdev); unsigned char zero[6] = { 0, 0, 0, 0, 0, 0 }; u32 val; int i; val = br32(bp, B44_RXCONFIG); val &= ~RXCONFIG_PROMISC; val |= RXCONFIG_ALLMULTI; b44_set_mac_addr(bp); for (i = 1; i < 64; i++) b44_cam_write(bp, zero, i); bw32(bp, B44_RXCONFIG, val); val = br32(bp, B44_CAM_CTRL); bw32(bp, B44_CAM_CTRL, val | CAM_CTRL_ENABLE); } /*** Implementation of gPXE driver callbacks ***/ /** * Probe device * * @v pci PCI device * @v id Matching entry in ID table * @ret rc Return status code */ static int b44_probe(struct pci_device *pci, const struct pci_device_id *id) { struct net_device *netdev; struct b44_private *bp; int rc; /* * Bail out if more than 1GB of physical RAM is installed. * This limitation will be removed later when dma mapping * is merged into mainline. */ if (!phys_ram_within_limit(B44_30BIT_DMA_MASK)) { DBG("Sorry, this version of the driver does not\n" "support systems with more than 1GB of RAM.\n"); return -ENOMEM; } /* Set up netdev */ netdev = alloc_etherdev(sizeof(*bp)); if (!netdev) return -ENOMEM; netdev_init(netdev, &b44_operations); pci_set_drvdata(pci, netdev); netdev->dev = &pci->dev; /* Set up private data */ bp = netdev_priv(netdev); memset(bp, 0, sizeof(*bp)); bp->netdev = netdev; bp->pci = pci; /* Map device registers */ bp->regs = ioremap(pci->membase, B44_REGS_SIZE); if (!bp->regs) { netdev_put(netdev); return -ENOMEM; } /* Enable PCI bus mastering */ adjust_pci_device(pci); b44_load_mac_and_phy_addr(bp); /* Link management currently not implemented */ netdev_link_up(netdev); rc = register_netdev(netdev); if (rc != 0) { iounmap(bp->regs); netdev_put(netdev); return rc; } b44_chip_reset(bp, B44_CHIP_RESET_FULL); DBG("b44 %s (%04x:%04x) regs=%p MAC=%s\n", id->name, id->vendor, id->device, bp->regs, eth_ntoa(netdev->ll_addr)); return 0; } /** * Remove device * * @v pci PCI device */ static void b44_remove(struct pci_device *pci) { struct net_device *netdev = pci_get_drvdata(pci); struct b44_private *bp = netdev_priv(netdev); ssb_core_disable(bp); unregister_netdev(netdev); iounmap(bp->regs); netdev_nullify(netdev); netdev_put(netdev); } /** Enable or disable interrupts * * @v netdev Network device * @v enable Interrupts should be enabled */ static void b44_irq(struct net_device *netdev, int enable) { struct b44_private *bp = netdev_priv(netdev); /* Interrupt mask specifies which events generate interrupts */ bw32(bp, B44_IMASK, enable ? IMASK_DEF : IMASK_DISABLE); } /** Open network device * * @v netdev Network device * @ret rc Return status code */ static int b44_open(struct net_device *netdev) { struct b44_private *bp = netdev_priv(netdev); int rc; rc = b44_init_tx_ring(bp); if (rc != 0) return rc; rc = b44_init_rx_ring(bp); if (rc != 0) return rc; b44_init_hw(bp, B44_FULL_RESET); /* Disable interrupts */ b44_irq(netdev, 0); return 0; } /** Close network device * * @v netdev Network device */ static void b44_close(struct net_device *netdev) { struct b44_private *bp = netdev_priv(netdev); b44_chip_reset(bp, B44_FULL_RESET); b44_free_tx_ring(bp); b44_free_rx_ring(bp); } /** Transmit packet * * @v netdev Network device * @v iobuf I/O buffer * @ret rc Return status code */ static int b44_transmit(struct net_device *netdev, struct io_buffer *iobuf) { struct b44_private *bp = netdev_priv(netdev); u32 cur = bp->tx_cur; u32 ctrl; /* Check for TX ring overflow */ if (bp->tx[cur].ctrl) { DBG("tx overflow\n"); return -ENOBUFS; } /* Will call netdev_tx_complete() on the iobuf later */ bp->tx_iobuf[cur] = iobuf; /* Set up TX descriptor */ ctrl = (iob_len(iobuf) & DESC_CTRL_LEN) | DESC_CTRL_IOC | DESC_CTRL_SOF | DESC_CTRL_EOF; if (cur == B44_RING_LAST) ctrl |= DESC_CTRL_EOT; bp->tx[cur].ctrl = cpu_to_le32(ctrl); bp->tx[cur].addr = cpu_to_le32(VIRT_TO_B44(iobuf->data)); /* Update next available descriptor index */ cur = ring_next(cur); bp->tx_cur = cur; wmb(); /* Tell card that a new TX descriptor is ready */ bw32(bp, B44_DMATX_PTR, cur * sizeof(struct dma_desc)); return 0; } /** Recycles sent TX descriptors and notifies network stack * * @v bp Driver state */ static void b44_tx_complete(struct b44_private *bp) { u32 cur, i; cur = pending_tx_index(bp); for (i = bp->tx_dirty; i != cur; i = ring_next(i)) { /* Free finished frame */ netdev_tx_complete(bp->netdev, bp->tx_iobuf[i]); bp->tx_iobuf[i] = NULL; /* Clear TX descriptor */ bp->tx[i].ctrl = 0; bp->tx[i].addr = 0; } bp->tx_dirty = cur; } static void b44_process_rx_packets(struct b44_private *bp) { struct io_buffer *iob; /* received data */ struct rx_header *rh; u32 pending, i; u16 len; pending = pending_rx_index(bp); for (i = bp->rx_cur; i != pending; i = ring_next(i)) { iob = bp->rx_iobuf[i]; if (iob == NULL) break; rh = iob->data; len = le16_to_cpu(rh->len); /* * Guard against incompletely written RX descriptors. * Without this, things can get really slow! */ if (len == 0) break; /* Discard CRC that is generated by the card */ len -= 4; /* Check for invalid packets and errors */ if (len > RX_PKT_BUF_SZ - RX_PKT_OFFSET || (rh->flags & cpu_to_le16(RX_FLAG_ERRORS))) { DBG("rx error len=%d flags=%04x\n", len, cpu_to_le16(rh->flags)); rh->len = 0; rh->flags = 0; netdev_rx_err(bp->netdev, iob, -EINVAL); continue; } /* Clear RX descriptor */ rh->len = 0; rh->flags = 0; bp->rx_iobuf[i] = NULL; /* Hand off the IO buffer to the network stack */ iob_reserve(iob, RX_PKT_OFFSET); iob_put(iob, len); netdev_rx(bp->netdev, iob); } bp->rx_cur = i; b44_rx_refill(bp, pending_rx_index(bp)); } /** Poll for completed and received packets * * @v netdev Network device */ static void b44_poll(struct net_device *netdev) { struct b44_private *bp = netdev_priv(netdev); u32 istat; /* Interrupt status */ istat = br32(bp, B44_ISTAT); istat &= IMASK_DEF; /* only the events we care about */ if (!istat) return; if (istat & ISTAT_TX) b44_tx_complete(bp); if (istat & ISTAT_RX) b44_process_rx_packets(bp); if (istat & ISTAT_ERRORS) { DBG("b44 error istat=0x%08x\n", istat); /* Reset B44 core partially to avoid long waits */ b44_irq(bp->netdev, 0); b44_halt(bp); b44_init_tx_ring(bp); b44_init_rx_ring(bp); b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY); } /* Acknowledge interrupt */ bw32(bp, B44_ISTAT, 0); bflush(bp, B44_ISTAT, 1); } static struct net_device_operations b44_operations = { .open = b44_open, .close = b44_close, .transmit = b44_transmit, .poll = b44_poll, .irq = b44_irq, }; static struct pci_device_id b44_nics[] = { PCI_ROM(0x14e4, 0x4401, "BCM4401", "BCM4401", 0), PCI_ROM(0x14e4, 0x170c, "BCM4401-B0", "BCM4401-B0", 0), PCI_ROM(0x14e4, 0x4402, "BCM4401-B1", "BCM4401-B1", 0), }; struct pci_driver b44_driver __pci_driver = { .ids = b44_nics, .id_count = sizeof b44_nics / sizeof b44_nics[0], .probe = b44_probe, .remove = b44_remove, }; debian/grub-extras/disabled/gpxe/src/drivers/net/tulip.c0000664000000000000000000022462312524662415020521 0ustar /* -*- Mode:C; c-basic-offset:4; -*- */ /* Tulip and clone Etherboot Driver By Marty Connor (mdc@etherboot.org) Copyright (C) 2001 Entity Cyber, Inc. This software may be used and distributed according to the terms of the GNU Public License, incorporated herein by reference. As of April 2001 this driver should support most tulip cards that the Linux tulip driver supports because Donald Becker's Linux media detection code is now included. Based on Ken Yap's Tulip Etherboot Driver and Donald Becker's Linux Tulip Driver. Supports N-Way speed auto-configuration on MX98715, MX98715A and MX98725. Support inexpensive PCI 10/100 cards based on the Macronix MX987x5 chip, such as the SOHOware Fast model SFA110A, and the LinkSYS model LNE100TX. The NetGear model FA310X, based on the LC82C168 chip is supported. The TRENDnet TE100-PCIA NIC which uses a genuine Intel 21143-PD chipset is supported. Also, Davicom DM9102's. Documentation and source code used: Source for Etherboot driver at http://etherboot.sourceforge.net/ MX98715A Data Sheet and MX98715A Application Note on http://www.macronix.com/ (PDF format files) Source for Linux tulip driver at http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html Adapted by Ken Yap from FreeBSD netboot DEC 21143 driver Author: David Sharp date: Nov/98 Some code fragments were taken from verious places, Ken Yap's etherboot, FreeBSD's if_de.c, and various Linux related files. DEC's manuals for the 21143 and SROM format were very helpful. The Linux de driver development page has a number of links to useful related information. Have a look at: ftp://cesdis.gsfc.nasa.gov/pub/linux/drivers/tulip-devel.html */ FILE_LICENCE ( GPL_ANY ); /*********************************************************************/ /* Revision History */ /*********************************************************************/ /* 08 Feb 2005 Ramesh Chander chhabaramesh at yahoo.co.in added table entries for SGThomson STE10/100A 07 Sep 2003 timlegge Multicast Support Added 11 Apr 2001 mdc [patch to etherboot 4.7.24] Major rewrite to include Linux tulip driver media detection code. This driver should support a lot more cards now. 16 Jul 2000 mdc 0.75b11 Added support for ADMtek 0985 Centaur-P, a "Comet" tulip clone which is used on the LinkSYS LNE100TX v4.x cards. We already support LNE100TX v2.0 cards, which use a different controller. 04 Jul 2000 jam ? Added test of status after receiving a packet from the card. Also uncommented the tulip_disable routine. Stray packets seemed to be causing problems. 27 Apr 2000 njl ? 29 Feb 2000 mdc 0.75b7 Increased reset delay to 3 seconds because Macronix cards seem to need more reset time before card comes back to a usable state. 26 Feb 2000 mdc 0.75b6 Added a 1 second delay after initializing the transmitter because some cards seem to need the time or they drop the first packet transmitted. 23 Feb 2000 mdc 0.75b5 removed udelay code and used currticks() for more reliable delay code in reset pause and sanity timeouts. Added function prototypes and TX debugging code. 21 Feb 2000 mdc patch to Etherboot 4.4.3 Incorporated patches from Bob Edwards and Paul Mackerras of Linuxcare's OZLabs to deal with inefficiencies in tulip_transmit and udelay. We now wait for packet transmission to complete (or sanity timeout). 04 Feb 2000 Robert.Edwards@anu.edu.au patch to Etherboot 4.4.2 patch to tulip.c that implements the automatic selection of the MII interface on cards using the Intel/DEC 21143 reference design, in particular, the TRENDnet TE100-PCIA NIC which uses a genuine Intel 21143-PD chipset. 11 Jan 2000 mdc 0.75b4 Added support for NetGear FA310TX card based on the LC82C168 chip. This should also support Lite-On LC82C168 boards. Added simple MII support. Re-arranged code to better modularize initializations. 04 Dec 1999 mdc 0.75b3 Added preliminary support for LNE100TX PCI cards. Should work for PNIC2 cards. No MII support, but single interface (RJ45) tulip cards seem to not care. 03 Dec 1999 mdc 0.75b2 Renamed from mx987x5 to tulip, merged in original tulip init code from tulip.c to support other tulip compatible cards. 02 Dec 1999 mdc 0.75b1 Released Beta MX987x5 Driver for code review and testing to netboot and thinguin mailing lists. */ /*********************************************************************/ /* Declarations */ /*********************************************************************/ #include "etherboot.h" #include "nic.h" #include #include /* User settable parameters */ #undef TULIP_DEBUG #undef TULIP_DEBUG_WHERE #ifdef TULIP_DEBUG static int tulip_debug = 2; /* 1 normal messages, 0 quiet .. 7 verbose. */ #endif #define TX_TIME_OUT 2*TICKS_PER_SEC /* helpful macros if on a big_endian machine for changing byte order. not strictly needed on Intel */ #define get_unaligned(ptr) (*(ptr)) #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) #define get_u16(ptr) (*(u16 *)(ptr)) #define virt_to_le32desc(addr) virt_to_bus(addr) #define TULIP_IOTYPE PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0 #define TULIP_SIZE 0x80 /* This is a mysterious value that can be written to CSR11 in the 21040 (only) to support a pre-NWay full-duplex signaling mechanism using short frames. No one knows what it should be, but if left at its default value some 10base2(!) packets trigger a full-duplex-request interrupt. */ #define FULL_DUPLEX_MAGIC 0x6969 static const int csr0 = 0x01A00000 | 0x8000; /* The possible media types that can be set in options[] are: */ #define MEDIA_MASK 31 static const char * const medianame[32] = { "10baseT", "10base2", "AUI", "100baseTx", "10baseT-FDX", "100baseTx-FDX", "100baseT4", "100baseFx", "100baseFx-FDX", "MII 10baseT", "MII 10baseT-FDX", "MII", "10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FDX", "MII 100baseT4", "MII 100baseFx-HDX", "MII 100baseFx-FDX", "Home-PNA 1Mbps", "Invalid-19", }; /* This much match tulip_tbl[]! Note 21142 == 21143. */ enum tulip_chips { DC21040=0, DC21041=1, DC21140=2, DC21142=3, DC21143=3, LC82C168, MX98713, MX98715, MX98725, AX88141, AX88140, PNIC2, COMET, COMPEX9881, I21145, XIRCOM, SGThomson, /*Ramesh Chander*/ }; enum pci_id_flags_bits { /* Set PCI command register bits before calling probe1(). */ PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, /* Read and map the single following PCI BAR. */ PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4, PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400, PCI_UNUSED_IRQ=0x800, }; struct pci_id_info { char *name; struct match_info { u32 pci, pci_mask, subsystem, subsystem_mask; u32 revision, revision_mask; /* Only 8 bits. */ } id; enum pci_id_flags_bits pci_flags; int io_size; /* Needed for I/O region check or ioremap(). */ int drv_flags; /* Driver use, intended as capability flags. */ }; static const struct pci_id_info pci_id_tbl[] = { { "Digital DC21040 Tulip", { 0x00021011, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 0x80, DC21040 }, { "Digital DC21041 Tulip", { 0x00141011, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 0x80, DC21041 }, { "Digital DS21140A Tulip", { 0x00091011, 0xffffffff, 0,0, 0x20,0xf0 }, TULIP_IOTYPE, 0x80, DC21140 }, { "Digital DS21140 Tulip", { 0x00091011, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 0x80, DC21140 }, { "Digital DS21143 Tulip", { 0x00191011, 0xffffffff, 0,0, 65,0xff }, TULIP_IOTYPE, TULIP_SIZE, DC21142 }, { "Digital DS21142 Tulip", { 0x00191011, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, TULIP_SIZE, DC21142 }, { "Kingston KNE110tx (PNIC)", { 0x000211AD, 0xffffffff, 0xf0022646, 0xffffffff, 0, 0 }, TULIP_IOTYPE, 256, LC82C168 }, { "Lite-On 82c168 PNIC", { 0x000211AD, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, LC82C168 }, { "Macronix 98713 PMAC", { 0x051210d9, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, MX98713 }, { "Macronix 98715 PMAC", { 0x053110d9, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, MX98715 }, { "Macronix 98725 PMAC", { 0x053110d9, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, MX98725 }, { "ASIX AX88141", { 0x1400125B, 0xffffffff, 0,0, 0x10, 0xf0 }, TULIP_IOTYPE, 128, AX88141 }, { "ASIX AX88140", { 0x1400125B, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 128, AX88140 }, { "Lite-On LC82C115 PNIC-II", { 0xc11511AD, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, PNIC2 }, { "ADMtek AN981 Comet", { 0x09811317, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, COMET }, { "ADMTek AN983 Comet", { 0x12161113, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, COMET }, { "ADMTek Comet AN983b", { 0x95111317, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, COMET }, { "ADMtek Centaur-P", { 0x09851317, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, COMET }, { "ADMtek Centaur-C", { 0x19851317, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, COMET }, { "Compex RL100-TX", { 0x988111F6, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 128, COMPEX9881 }, { "Intel 21145 Tulip", { 0x00398086, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 128, I21145 }, { "Xircom Tulip clone", { 0x0003115d, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 128, XIRCOM }, { "Davicom DM9102", { 0x91021282, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 0x80, DC21140 }, { "Davicom DM9100", { 0x91001282, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 0x80, DC21140 }, { "Macronix mxic-98715 (EN1217)", { 0x12171113, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, MX98715 }, { "3Com 3cSOHO100B-TX (ADMtek Centuar)", { 0x930010b7, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, TULIP_SIZE, COMET }, { "SG Thomson STE10/100A", { 0x2774104a, 0xffffffff, 0, 0, 0, 0 }, TULIP_IOTYPE, 256, COMET }, /*Ramesh Chander*/ { 0, { 0, 0, 0, 0, 0, 0 }, 0, 0, 0 }, }; enum tbl_flag { HAS_MII=1, HAS_MEDIA_TABLE=2, CSR12_IN_SROM=4, ALWAYS_CHECK_MII=8, HAS_PWRDWN=0x10, MC_HASH_ONLY=0x20, /* Hash-only multicast filter. */ HAS_PNICNWAY=0x80, HAS_NWAY=0x40, /* Uses internal NWay xcvr. */ HAS_INTR_MITIGATION=0x100, IS_ASIX=0x200, HAS_8023X=0x400, }; /* Note: this table must match enum tulip_chips above. */ static struct tulip_chip_table { char *chip_name; int flags; } tulip_tbl[] = { { "Digital DC21040 Tulip", 0}, { "Digital DC21041 Tulip", HAS_MEDIA_TABLE | HAS_NWAY }, { "Digital DS21140 Tulip", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM }, { "Digital DS21143 Tulip", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_PWRDWN | HAS_NWAY | HAS_INTR_MITIGATION }, { "Lite-On 82c168 PNIC", HAS_MII | HAS_PNICNWAY }, { "Macronix 98713 PMAC", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM }, { "Macronix 98715 PMAC", HAS_MEDIA_TABLE }, { "Macronix 98725 PMAC", HAS_MEDIA_TABLE }, { "ASIX AX88140", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY | IS_ASIX }, { "ASIX AX88141", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY | IS_ASIX }, { "Lite-On PNIC-II", HAS_MII | HAS_NWAY | HAS_8023X }, { "ADMtek Comet", HAS_MII | MC_HASH_ONLY }, { "Compex 9881 PMAC", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM }, { "Intel DS21145 Tulip", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_PWRDWN | HAS_NWAY }, { "Xircom tulip work-alike", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_PWRDWN | HAS_NWAY }, { "SGThomson STE10/100A", HAS_MII | MC_HASH_ONLY }, /*Ramesh Chander*/ { 0, 0 }, }; /* A full-duplex map for media types. */ enum MediaIs { MediaIsFD = 1, MediaAlwaysFD=2, MediaIsMII=4, MediaIsFx=8, MediaIs100=16}; static const char media_cap[32] = {0,0,0,16, 3,19,16,24, 27,4,7,5, 0,20,23,20, 20,31,0,0, }; static u8 t21040_csr13[] = {2,0x0C,8,4, 4,0,0,0, 0,0,0,0, 4,0,0,0}; /* 21041 transceiver register settings: 10-T, 10-2, AUI, 10-T, 10T-FD */ static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }; static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, }; static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; /* not used static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, }; */ static u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, }; /* not used static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; */ /* Offsets to the Command and Status Registers, "CSRs". All accesses must be longword instructions and quadword aligned. */ enum tulip_offsets { CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28, CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58, CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0 }; /* The bits in the CSR5 status registers, mostly interrupt sources. */ enum status_bits { TimerInt=0x800, TPLnkFail=0x1000, TPLnkPass=0x10, NormalIntr=0x10000, AbnormalIntr=0x8000, RxJabber=0x200, RxDied=0x100, RxNoBuf=0x80, RxIntr=0x40, TxFIFOUnderflow=0x20, TxJabber=0x08, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01, }; /* The configuration bits in CSR6. */ enum csr6_mode_bits { TxOn=0x2000, RxOn=0x0002, FullDuplex=0x0200, AcceptBroadcast=0x0100, AcceptAllMulticast=0x0080, AcceptAllPhys=0x0040, AcceptRunt=0x0008, }; enum desc_status_bits { DescOwnded=0x80000000, RxDescFatalErr=0x8000, RxWholePkt=0x0300, }; struct medialeaf { u8 type; u8 media; unsigned char *leafdata; }; struct mediatable { u16 defaultmedia; u8 leafcount, csr12dir; /* General purpose pin directions. */ unsigned has_mii:1, has_nonmii:1, has_reset:6; u32 csr15dir, csr15val; /* 21143 NWay setting. */ struct medialeaf mleaf[0]; }; struct mediainfo { struct mediainfo *next; int info_type; int index; unsigned char *info; }; /* EEPROM Address width definitions */ #define EEPROM_ADDRLEN 6 #define EEPROM_SIZE 128 /* 2 << EEPROM_ADDRLEN */ /* The EEPROM commands include the alway-set leading bit. */ #define EE_WRITE_CMD (5 << addr_len) #define EE_READ_CMD (6 << addr_len) #define EE_ERASE_CMD (7 << addr_len) /* EEPROM_Ctrl bits. */ #define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */ #define EE_CS 0x01 /* EEPROM chip select. */ #define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ #define EE_WRITE_0 0x01 #define EE_WRITE_1 0x05 #define EE_DATA_READ 0x08 /* EEPROM chip data out. */ #define EE_ENB (0x4800 | EE_CS) /* Delay between EEPROM clock transitions. Even at 33Mhz current PCI implementations don't overrun the EEPROM clock. We add a bus turn-around to insure that this remains true. */ #define eeprom_delay() inl(ee_addr) /* Size of transmit and receive buffers */ #define BUFLEN 1536 /* Ring-wrap flag in length field, use for last ring entry. 0x01000000 means chain on buffer2 address, 0x02000000 means use the ring start address in CSR2/3. Note: Some work-alike chips do not function correctly in chained mode. The ASIX chip works only in chained mode. Thus we indicate ring mode, but always write the 'next' field for chained mode as well. */ #define DESC_RING_WRAP 0x02000000 /* transmit and receive descriptor format */ struct tulip_rx_desc { volatile u32 status; u32 length; u32 buffer1, buffer2; }; struct tulip_tx_desc { volatile u32 status; u32 length; u32 buffer1, buffer2; }; /*********************************************************************/ /* Global Storage */ /*********************************************************************/ static u32 ioaddr; struct tulip_private { int cur_rx; int chip_id; /* index into tulip_tbl[] */ int pci_id_idx; /* index into pci_id_tbl[] */ int revision; int flags; unsigned short vendor_id; /* PCI card vendor code */ unsigned short dev_id; /* PCI card device code */ unsigned char ehdr[ETH_HLEN]; /* buffer for ethernet header */ const char *nic_name; unsigned int csr0, csr6; /* Current CSR0, CSR6 settings. */ unsigned int if_port; unsigned int full_duplex; /* Full-duplex operation requested. */ unsigned int full_duplex_lock; unsigned int medialock; /* Do not sense media type. */ unsigned int mediasense; /* Media sensing in progress. */ unsigned int nway, nwayset; /* 21143 internal NWay. */ unsigned int default_port; unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */ u8 media_table_storage[(sizeof(struct mediatable) + 32*sizeof(struct medialeaf))]; u16 sym_advertise, mii_advertise; /* NWay to-advertise. */ struct mediatable *mtable; u16 lpar; /* 21143 Link partner ability. */ u16 advertising[4]; /* MII advertise, from SROM table. */ signed char phys[4], mii_cnt; /* MII device addresses. */ int cur_index; /* Current media index. */ int saved_if_port; }; /* Note: transmit and receive buffers must be longword aligned and longword divisable */ #define TX_RING_SIZE 2 #define RX_RING_SIZE 4 struct { struct tulip_tx_desc tx_ring[TX_RING_SIZE]; unsigned char txb[BUFLEN]; struct tulip_rx_desc rx_ring[RX_RING_SIZE]; unsigned char rxb[RX_RING_SIZE * BUFLEN]; struct tulip_private tpx; } tulip_bss __shared __attribute__ ((aligned(4))); #define tx_ring tulip_bss.tx_ring #define txb tulip_bss.txb #define rx_ring tulip_bss.rx_ring #define rxb tulip_bss.rxb static struct tulip_private *tp; /* Known cards that have old-style EEPROMs. Writing this table is described at http://cesdis.gsfc.nasa.gov/linux/drivers/tulip-drivers/tulip-media.html */ static struct fixups { char *name; unsigned char addr0, addr1, addr2; u16 newtable[32]; /* Max length below. */ } eeprom_fixups[] = { {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c, 0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }}, {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f, 0x0000, 0x009E, /* 10baseT */ 0x0004, 0x009E, /* 10baseT-FD */ 0x0903, 0x006D, /* 100baseTx */ 0x0905, 0x006D, /* 100baseTx-FD */ }}, {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f, 0x0107, 0x8021, /* 100baseFx */ 0x0108, 0x8021, /* 100baseFx-FD */ 0x0100, 0x009E, /* 10baseT */ 0x0104, 0x009E, /* 10baseT-FD */ 0x0103, 0x006D, /* 100baseTx */ 0x0105, 0x006D, /* 100baseTx-FD */ }}, {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513, 0x1001, 0x009E, /* 10base2, CSR12 0x10*/ 0x0000, 0x009E, /* 10baseT */ 0x0004, 0x009E, /* 10baseT-FD */ 0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */ 0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}}, {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F, 0x1B01, 0x0000, /* 10base2, CSR12 0x1B */ 0x0B00, 0x009E, /* 10baseT, CSR12 0x0B */ 0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */ 0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */ 0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */ }}, {0, 0, 0, 0, {}}}; static const char * block_name[] = {"21140 non-MII", "21140 MII PHY", "21142 Serial PHY", "21142 MII PHY", "21143 SYM PHY", "21143 reset method"}; /*********************************************************************/ /* Function Prototypes */ /*********************************************************************/ static int mdio_read(struct nic *nic, int phy_id, int location); static void mdio_write(struct nic *nic, int phy_id, int location, int value); static int read_eeprom(unsigned long ioaddr, int location, int addr_len); static void parse_eeprom(struct nic *nic); static int tulip_probe(struct nic *nic,struct pci_device *pci); static void tulip_init_ring(struct nic *nic); static void tulip_reset(struct nic *nic); static void tulip_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p); static int tulip_poll(struct nic *nic, int retrieve); static void tulip_disable(struct nic *nic); static void nway_start(struct nic *nic); static void pnic_do_nway(struct nic *nic); static void select_media(struct nic *nic, int startup); static void init_media(struct nic *nic); static void start_link(struct nic *nic); static int tulip_check_duplex(struct nic *nic); static void tulip_wait(unsigned int nticks); #ifdef TULIP_DEBUG_WHERE static void whereami(const char *str); #endif #ifdef TULIP_DEBUG static void tulip_more(void); #endif /*********************************************************************/ /* Utility Routines */ /*********************************************************************/ #ifdef TULIP_DEBUG_WHERE static void whereami (const char *str, struct pci_device *pci) { printf("%s: %s\n", tp->nic_name, str); /* sleep(2); */ } #endif #ifdef TULIP_DEBUG static void tulip_more(void) { printf("\n\n-- more --"); while (!iskey()) /* wait */; getchar(); printf("\n\n"); } #endif /* TULIP_DEBUG */ static void tulip_wait(unsigned int nticks) { unsigned int to = currticks() + nticks; while (currticks() < to) /* wait */ ; } /*********************************************************************/ /* Media Descriptor Code */ /*********************************************************************/ /* MII transceiver control section. Read and write the MII registers using software-generated serial MDIO protocol. See the MII specifications or DP83840A data sheet for details. */ /* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually met by back-to-back PCI I/O cycles, but we insert a delay to avoid "overclocking" issues or future 66Mhz PCI. */ #define mdio_delay() inl(mdio_addr) /* Read and write the MII registers using software-generated serial MDIO protocol. It is just different enough from the EEPROM protocol to not share code. The maxium data clock rate is 2.5 Mhz. */ #define MDIO_SHIFT_CLK 0x10000 #define MDIO_DATA_WRITE0 0x00000 #define MDIO_DATA_WRITE1 0x20000 #define MDIO_ENB 0x00000 /* Ignore the 0x02000 databook setting. */ #define MDIO_ENB_IN 0x40000 #define MDIO_DATA_READ 0x80000 /* MII transceiver control section. Read and write the MII registers using software-generated serial MDIO protocol. See the MII specifications or DP83840A data sheet for details. */ int mdio_read(struct nic *nic __unused, int phy_id, int location) { int i; int read_cmd = (0xf6 << 10) | (phy_id << 5) | location; int retval = 0; long mdio_addr = ioaddr + CSR9; #ifdef TULIP_DEBUG_WHERE whereami("mdio_read\n"); #endif if (tp->chip_id == LC82C168) { int i = 1000; outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0); inl(ioaddr + 0xA0); inl(ioaddr + 0xA0); while (--i > 0) if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000)) return retval & 0xffff; return 0xffff; } if (tp->chip_id == COMET) { if (phy_id == 1) { if (location < 7) return inl(ioaddr + 0xB4 + (location<<2)); else if (location == 17) return inl(ioaddr + 0xD0); else if (location >= 29 && location <= 31) return inl(ioaddr + 0xD4 + ((location-29)<<2)); } return 0xffff; } /* Establish sync by sending at least 32 logic ones. */ for (i = 32; i >= 0; i--) { outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr); mdio_delay(); outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); mdio_delay(); } /* Shift the read command bits out. */ for (i = 15; i >= 0; i--) { int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0; outl(MDIO_ENB | dataval, mdio_addr); mdio_delay(); outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr); mdio_delay(); } /* Read the two transition, 16 data, and wire-idle bits. */ for (i = 19; i > 0; i--) { outl(MDIO_ENB_IN, mdio_addr); mdio_delay(); retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0); outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); mdio_delay(); } return (retval>>1) & 0xffff; } void mdio_write(struct nic *nic __unused, int phy_id, int location, int value) { int i; int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value; long mdio_addr = ioaddr + CSR9; #ifdef TULIP_DEBUG_WHERE whereami("mdio_write\n"); #endif if (tp->chip_id == LC82C168) { int i = 1000; outl(cmd, ioaddr + 0xA0); do if ( ! (inl(ioaddr + 0xA0) & 0x80000000)) break; while (--i > 0); return; } if (tp->chip_id == COMET) { if (phy_id != 1) return; if (location < 7) outl(value, ioaddr + 0xB4 + (location<<2)); else if (location == 17) outl(value, ioaddr + 0xD0); else if (location >= 29 && location <= 31) outl(value, ioaddr + 0xD4 + ((location-29)<<2)); return; } /* Establish sync by sending 32 logic ones. */ for (i = 32; i >= 0; i--) { outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr); mdio_delay(); outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); mdio_delay(); } /* Shift the command bits out. */ for (i = 31; i >= 0; i--) { int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0; outl(MDIO_ENB | dataval, mdio_addr); mdio_delay(); outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr); mdio_delay(); } /* Clear out extra bits. */ for (i = 2; i > 0; i--) { outl(MDIO_ENB_IN, mdio_addr); mdio_delay(); outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); mdio_delay(); } } /*********************************************************************/ /* EEPROM Reading Code */ /*********************************************************************/ /* EEPROM routines adapted from the Linux Tulip Code */ /* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->. */ static int read_eeprom(unsigned long ioaddr, int location, int addr_len) { int i; unsigned short retval = 0; long ee_addr = ioaddr + CSR9; int read_cmd = location | EE_READ_CMD; #ifdef TULIP_DEBUG_WHERE whereami("read_eeprom\n"); #endif outl(EE_ENB & ~EE_CS, ee_addr); outl(EE_ENB, ee_addr); /* Shift the read command bits out. */ for (i = 4 + addr_len; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; outl(EE_ENB | dataval, ee_addr); eeprom_delay(); outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); eeprom_delay(); } outl(EE_ENB, ee_addr); for (i = 16; i > 0; i--) { outl(EE_ENB | EE_SHIFT_CLK, ee_addr); eeprom_delay(); retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0); outl(EE_ENB, ee_addr); eeprom_delay(); } /* Terminate the EEPROM access. */ outl(EE_ENB & ~EE_CS, ee_addr); return retval; } /*********************************************************************/ /* EEPROM Parsing Code */ /*********************************************************************/ static void parse_eeprom(struct nic *nic) { unsigned char *p, *ee_data = tp->eeprom; int new_advertise = 0; int i; #ifdef TULIP_DEBUG_WHERE whereami("parse_eeprom\n"); #endif tp->mtable = 0; /* Detect an old-style (SA only) EEPROM layout: memcmp(ee_data, ee_data+16, 8). */ for (i = 0; i < 8; i ++) if (ee_data[i] != ee_data[16+i]) break; if (i >= 8) { /* Do a fix-up based on the vendor half of the station address. */ for (i = 0; eeprom_fixups[i].name; i++) { if (nic->node_addr[0] == eeprom_fixups[i].addr0 && nic->node_addr[1] == eeprom_fixups[i].addr1 && nic->node_addr[2] == eeprom_fixups[i].addr2) { if (nic->node_addr[2] == 0xE8 && ee_data[0x1a] == 0x55) i++; /* An Accton EN1207, not an outlaw Maxtech. */ memcpy(ee_data + 26, eeprom_fixups[i].newtable, sizeof(eeprom_fixups[i].newtable)); #ifdef TULIP_DEBUG printf("%s: Old format EEPROM on '%s' board.\n%s: Using substitute media control info.\n", tp->nic_name, eeprom_fixups[i].name, tp->nic_name); #endif break; } } if (eeprom_fixups[i].name == NULL) { /* No fixup found. */ #ifdef TULIP_DEBUG printf("%s: Old style EEPROM with no media selection information.\n", tp->nic_name); #endif return; } } if (ee_data[19] > 1) { #ifdef TULIP_DEBUG printf("%s: Multiport cards (%d ports) may not work correctly.\n", tp->nic_name, ee_data[19]); #endif } p = (void *)ee_data + ee_data[27]; if (ee_data[27] == 0) { /* No valid media table. */ #ifdef TULIP_DEBUG if (tulip_debug > 1) { printf("%s: No Valid Media Table. ee_data[27] = %hhX\n", tp->nic_name, ee_data[27]); } #endif } else if (tp->chip_id == DC21041) { int media = get_u16(p); int count = p[2]; p += 3; printf("%s: 21041 Media table, default media %hX (%s).\n", tp->nic_name, media, media & 0x0800 ? "Autosense" : medianame[media & 15]); for (i = 0; i < count; i++) { unsigned char media_block = *p++; int media_code = media_block & MEDIA_MASK; if (media_block & 0x40) p += 6; switch(media_code) { case 0: new_advertise |= 0x0020; break; case 4: new_advertise |= 0x0040; break; } printf("%s: 21041 media #%d, %s.\n", tp->nic_name, media_code, medianame[media_code]); } } else { unsigned char csr12dir = 0; int count; struct mediatable *mtable; u16 media = get_u16(p); p += 2; if (tp->flags & CSR12_IN_SROM) csr12dir = *p++; count = *p++; tp->mtable = mtable = (struct mediatable *)&tp->media_table_storage[0]; mtable->defaultmedia = media; mtable->leafcount = count; mtable->csr12dir = csr12dir; mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0; mtable->csr15dir = mtable->csr15val = 0; printf("%s: EEPROM default media type %s.\n", tp->nic_name, media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]); for (i = 0; i < count; i++) { struct medialeaf *leaf = &mtable->mleaf[i]; if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */ leaf->type = 0; leaf->media = p[0] & 0x3f; leaf->leafdata = p; if ((p[2] & 0x61) == 0x01) /* Bogus, but Znyx boards do it. */ mtable->has_mii = 1; p += 4; } else { switch(leaf->type = p[1]) { case 5: mtable->has_reset = i; leaf->media = p[2] & 0x0f; break; case 1: case 3: mtable->has_mii = 1; leaf->media = 11; break; case 2: if ((p[2] & 0x3f) == 0) { u32 base15 = (p[2] & 0x40) ? get_u16(p + 7) : 0x0008; u16 *p1 = (u16 *)(p + (p[2] & 0x40 ? 9 : 3)); mtable->csr15dir = (get_unaligned(p1 + 0)<<16) + base15; mtable->csr15val = (get_unaligned(p1 + 1)<<16) + base15; } /* Fall through. */ case 0: case 4: mtable->has_nonmii = 1; leaf->media = p[2] & MEDIA_MASK; switch (leaf->media) { case 0: new_advertise |= 0x0020; break; case 4: new_advertise |= 0x0040; break; case 3: new_advertise |= 0x0080; break; case 5: new_advertise |= 0x0100; break; case 6: new_advertise |= 0x0200; break; } break; default: leaf->media = 19; } leaf->leafdata = p + 2; p += (p[0] & 0x3f) + 1; } #ifdef TULIP_DEBUG if (tulip_debug > 1 && leaf->media == 11) { unsigned char *bp = leaf->leafdata; printf("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %hhX %hhX.\n", tp->nic_name, bp[0], bp[1], bp[2 + bp[1]*2], bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]); } #endif printf("%s: Index #%d - Media %s (#%d) described " "by a %s (%d) block.\n", tp->nic_name, i, medianame[leaf->media], leaf->media, leaf->type < 6 ? block_name[leaf->type] : "UNKNOWN", leaf->type); } if (new_advertise) tp->sym_advertise = new_advertise; } } /*********************************************************************/ /* tulip_init_ring - setup the tx and rx descriptors */ /*********************************************************************/ static void tulip_init_ring(struct nic *nic __unused) { int i; #ifdef TULIP_DEBUG_WHERE whereami("tulip_init_ring\n"); #endif tp->cur_rx = 0; for (i = 0; i < RX_RING_SIZE; i++) { rx_ring[i].status = cpu_to_le32(0x80000000); rx_ring[i].length = cpu_to_le32(BUFLEN); rx_ring[i].buffer1 = virt_to_le32desc(&rxb[i * BUFLEN]); rx_ring[i].buffer2 = virt_to_le32desc(&rx_ring[i+1]); } /* Mark the last entry as wrapping the ring. */ rx_ring[i-1].length = cpu_to_le32(DESC_RING_WRAP | BUFLEN); rx_ring[i-1].buffer2 = virt_to_le32desc(&rx_ring[0]); /* We only use 1 transmit buffer, but we use 2 descriptors so transmit engines have somewhere to point to if they feel the need */ tx_ring[0].status = 0x00000000; tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]); tx_ring[0].buffer2 = virt_to_le32desc(&tx_ring[1]); /* this descriptor should never get used, since it will never be owned by the machine (status will always == 0) */ tx_ring[1].status = 0x00000000; tx_ring[1].buffer1 = virt_to_le32desc(&txb[0]); tx_ring[1].buffer2 = virt_to_le32desc(&tx_ring[0]); /* Mark the last entry as wrapping the ring, though this should never happen */ tx_ring[1].length = cpu_to_le32(DESC_RING_WRAP | BUFLEN); } static void set_rx_mode(struct nic *nic __unused) { int csr6 = inl(ioaddr + CSR6) & ~0x00D5; tp->csr6 &= ~0x00D5; /* !IFF_PROMISC */ tp->csr6 |= AcceptAllMulticast; csr6 |= AcceptAllMulticast; outl(csr6, ioaddr + CSR6); } /*********************************************************************/ /* eth_reset - Reset adapter */ /*********************************************************************/ static void tulip_reset(struct nic *nic) { int i; unsigned long to; #ifdef TULIP_DEBUG_WHERE whereami("tulip_reset\n"); #endif /* Stop Tx and RX */ outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6); /* On some chip revs we must set the MII/SYM port before the reset!? */ if (tp->mii_cnt || (tp->mtable && tp->mtable->has_mii)) { outl(0x814C0000, ioaddr + CSR6); } /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */ outl(0x00000001, ioaddr + CSR0); tulip_wait(1); /* turn off reset and set cache align=16lword, burst=unlimit */ outl(tp->csr0, ioaddr + CSR0); /* Wait the specified 50 PCI cycles after a reset */ tulip_wait(1); /* set up transmit and receive descriptors */ tulip_init_ring(nic); if (tp->chip_id == PNIC2) { u32 addr_high = (nic->node_addr[1]<<8) + (nic->node_addr[0]<<0); /* This address setting does not appear to impact chip operation?? */ outl((nic->node_addr[5]<<8) + nic->node_addr[4] + (nic->node_addr[3]<<24) + (nic->node_addr[2]<<16), ioaddr + 0xB0); outl(addr_high + (addr_high<<16), ioaddr + 0xB8); } /* MC_HASH_ONLY boards don't support setup packets */ if (tp->flags & MC_HASH_ONLY) { u32 addr_low = cpu_to_le32(get_unaligned((u32 *)nic->node_addr)); u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(nic->node_addr+4))); /* clear multicast hash filters and setup MAC address filters */ if (tp->flags & IS_ASIX) { outl(0, ioaddr + CSR13); outl(addr_low, ioaddr + CSR14); outl(1, ioaddr + CSR13); outl(addr_high, ioaddr + CSR14); outl(2, ioaddr + CSR13); outl(0, ioaddr + CSR14); outl(3, ioaddr + CSR13); outl(0, ioaddr + CSR14); } else if (tp->chip_id == COMET) { outl(addr_low, ioaddr + 0xA4); outl(addr_high, ioaddr + 0xA8); outl(0, ioaddr + 0xAC); outl(0, ioaddr + 0xB0); } } else { /* for other boards we send a setup packet to initialize the filters */ u32 tx_flags = 0x08000000 | 192; /* construct perfect filter frame with mac address as first match and broadcast address for all others */ for (i=0; i<192; i++) txb[i] = 0xFF; txb[0] = nic->node_addr[0]; txb[1] = nic->node_addr[1]; txb[4] = nic->node_addr[2]; txb[5] = nic->node_addr[3]; txb[8] = nic->node_addr[4]; txb[9] = nic->node_addr[5]; tx_ring[0].length = cpu_to_le32(tx_flags); tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]); tx_ring[0].status = cpu_to_le32(0x80000000); } /* Point to rx and tx descriptors */ outl(virt_to_le32desc(&rx_ring[0]), ioaddr + CSR3); outl(virt_to_le32desc(&tx_ring[0]), ioaddr + CSR4); init_media(nic); /* set the chip's operating mode (but don't turn on xmit and recv yet) */ outl((tp->csr6 & ~0x00002002), ioaddr + CSR6); /* send setup packet for cards that support it */ if (!(tp->flags & MC_HASH_ONLY)) { /* enable transmit wait for completion */ outl(tp->csr6 | 0x00002000, ioaddr + CSR6); /* immediate transmit demand */ outl(0, ioaddr + CSR1); to = currticks() + TX_TIME_OUT; while ((tx_ring[0].status & 0x80000000) && (currticks() < to)) /* wait */ ; if (currticks() >= to) { printf ("%s: TX Setup Timeout.\n", tp->nic_name); } } if (tp->chip_id == LC82C168) tulip_check_duplex(nic); set_rx_mode(nic); /* enable transmit and receive */ outl(tp->csr6 | 0x00002002, ioaddr + CSR6); } /*********************************************************************/ /* eth_transmit - Transmit a frame */ /*********************************************************************/ static void tulip_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p) { u16 nstype; u32 to; u32 csr6 = inl(ioaddr + CSR6); #ifdef TULIP_DEBUG_WHERE whereami("tulip_transmit\n"); #endif /* Disable Tx */ outl(csr6 & ~0x00002000, ioaddr + CSR6); memcpy(txb, d, ETH_ALEN); memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN); nstype = htons((u16) t); memcpy(txb + 2 * ETH_ALEN, (u8 *)&nstype, 2); memcpy(txb + ETH_HLEN, p, s); s += ETH_HLEN; s &= 0x0FFF; /* pad to minimum packet size */ while (s < ETH_ZLEN) txb[s++] = '\0'; #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: sending %d bytes ethtype %hX\n", tp->nic_name, s, t); #endif /* setup the transmit descriptor */ /* 0x60000000 = no interrupt on completion */ tx_ring[0].length = cpu_to_le32(0x60000000 | s); tx_ring[0].status = cpu_to_le32(0x80000000); /* Point to transmit descriptor */ outl(virt_to_le32desc(&tx_ring[0]), ioaddr + CSR4); /* Enable Tx */ outl(csr6 | 0x00002000, ioaddr + CSR6); /* immediate transmit demand */ outl(0, ioaddr + CSR1); to = currticks() + TX_TIME_OUT; while ((tx_ring[0].status & 0x80000000) && (currticks() < to)) /* wait */ ; if (currticks() >= to) { printf ("TX Timeout!\n"); } /* Disable Tx */ outl(csr6 & ~0x00002000, ioaddr + CSR6); } /*********************************************************************/ /* eth_poll - Wait for a frame */ /*********************************************************************/ static int tulip_poll(struct nic *nic, int retrieve) { #ifdef TULIP_DEBUG_WHERE whereami("tulip_poll\n"); #endif /* no packet waiting. packet still owned by NIC */ if (rx_ring[tp->cur_rx].status & 0x80000000) return 0; if ( ! retrieve ) return 1; #ifdef TULIP_DEBUG_WHERE whereami("tulip_poll got one\n"); #endif nic->packetlen = (rx_ring[tp->cur_rx].status & 0x3FFF0000) >> 16; /* if we get a corrupted packet. throw it away and move on */ if (rx_ring[tp->cur_rx].status & 0x00008000) { /* return the descriptor and buffer to receive ring */ rx_ring[tp->cur_rx].status = 0x80000000; tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE; return 0; } /* copy packet to working buffer */ memcpy(nic->packet, rxb + tp->cur_rx * BUFLEN, nic->packetlen); /* return the descriptor and buffer to receive ring */ rx_ring[tp->cur_rx].status = 0x80000000; tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE; return 1; } /*********************************************************************/ /* eth_disable - Disable the interface */ /*********************************************************************/ static void tulip_disable ( struct nic *nic ) { #ifdef TULIP_DEBUG_WHERE whereami("tulip_disable\n"); #endif tulip_reset(nic); /* disable interrupts */ outl(0x00000000, ioaddr + CSR7); /* Stop the chip's Tx and Rx processes. */ outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6); /* Clear the missed-packet counter. */ inl(ioaddr + CSR8); } /*********************************************************************/ /*IRQ - Enable, Disable, or Force interrupts */ /*********************************************************************/ static void tulip_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } static struct nic_operations tulip_operations = { .connect = dummy_connect, .poll = tulip_poll, .transmit = tulip_transmit, .irq = tulip_irq, }; /*********************************************************************/ /* eth_probe - Look for an adapter */ /*********************************************************************/ static int tulip_probe ( struct nic *nic, struct pci_device *pci ) { u32 i; u8 chip_rev; u8 ee_data[EEPROM_SIZE]; unsigned short sum; int chip_idx; static unsigned char last_phys_addr[ETH_ALEN] = {0x00, 'L', 'i', 'n', 'u', 'x'}; if (pci->ioaddr == 0) return 0; ioaddr = pci->ioaddr; nic->ioaddr = pci->ioaddr & ~3; nic->irqno = 0; /* point to private storage */ tp = &tulip_bss.tpx; tp->vendor_id = pci->vendor; tp->dev_id = pci->device; tp->if_port = 0; tp->default_port = 0; adjust_pci_device(pci); /* disable interrupts */ outl(0x00000000, ioaddr + CSR7); /* Stop the chip's Tx and Rx processes. */ outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6); /* Clear the missed-packet counter. */ inl(ioaddr + CSR8); printf("\n"); /* so we start on a fresh line */ #ifdef TULIP_DEBUG_WHERE whereami("tulip_probe\n"); #endif #ifdef TULIP_DEBUG if (tulip_debug > 1) printf ("%s: Looking for Tulip Chip: Vendor=%hX Device=%hX\n", tp->nic_name, tp->vendor, tp->dev_id); #endif /* Figure out which chip we're dealing with */ i = 0; chip_idx = -1; while (pci_id_tbl[i].name) { if ( (((u32) tp->dev_id << 16) | tp->vendor_id) == (pci_id_tbl[i].id.pci & pci_id_tbl[i].id.pci_mask) ) { chip_idx = pci_id_tbl[i].drv_flags; break; } i++; } if (chip_idx == -1) { printf ("%s: Unknown Tulip Chip: Vendor=%hX Device=%hX\n", tp->nic_name, tp->vendor_id, tp->dev_id); return 0; } tp->pci_id_idx = i; tp->flags = tulip_tbl[chip_idx].flags; #ifdef TULIP_DEBUG if (tulip_debug > 1) { printf ("%s: tp->pci_id_idx == %d, name == %s\n", tp->nic_name, tp->pci_id_idx, pci_id_tbl[tp->pci_id_idx].name); printf ("%s: chip_idx == %d, name == %s\n", tp->nic_name, chip_idx, tulip_tbl[chip_idx].chip_name); } #endif /* Bring the 21041/21143 out of sleep mode. Caution: Snooze mode does not work with some boards! */ if (tp->flags & HAS_PWRDWN) pci_write_config_dword(pci, 0x40, 0x00000000); if (inl(ioaddr + CSR5) == 0xFFFFFFFF) { printf("%s: The Tulip chip at %X is not functioning.\n", tp->nic_name, (unsigned int) ioaddr); return 0; } pci_read_config_byte(pci, PCI_REVISION, &chip_rev); printf("%s: [chip: %s] rev %d at %hX\n", tp->nic_name, tulip_tbl[chip_idx].chip_name, chip_rev, (unsigned int) ioaddr); printf("%s: Vendor=%hX Device=%hX", tp->nic_name, tp->vendor_id, tp->dev_id); if (chip_idx == DC21041 && inl(ioaddr + CSR9) & 0x8000) { printf(" 21040 compatible mode."); chip_idx = DC21040; } printf("\n"); /* The SROM/EEPROM interface varies dramatically. */ sum = 0; if (chip_idx == DC21040) { outl(0, ioaddr + CSR9); /* Reset the pointer with a dummy write. */ for (i = 0; i < ETH_ALEN; i++) { int value, boguscnt = 100000; do value = inl(ioaddr + CSR9); while (value < 0 && --boguscnt > 0); nic->node_addr[i] = value; sum += value & 0xff; } } else if (chip_idx == LC82C168) { for (i = 0; i < 3; i++) { int value, boguscnt = 100000; outl(0x600 | i, ioaddr + 0x98); do value = inl(ioaddr + CSR9); while (value < 0 && --boguscnt > 0); put_unaligned(le16_to_cpu(value), ((u16*)nic->node_addr) + i); sum += value & 0xffff; } } else if (chip_idx == COMET) { /* No need to read the EEPROM. */ put_unaligned(inl(ioaddr + 0xA4), (u32 *)nic->node_addr); put_unaligned(inl(ioaddr + 0xA8), (u16 *)(nic->node_addr + 4)); for (i = 0; i < ETH_ALEN; i ++) sum += nic->node_addr[i]; } else { /* A serial EEPROM interface, we read now and sort it out later. */ int sa_offset = 0; int ee_addr_size = read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6; for (i = 0; i < sizeof(ee_data)/2; i++) ((u16 *)ee_data)[i] = le16_to_cpu(read_eeprom(ioaddr, i, ee_addr_size)); /* DEC now has a specification (see Notes) but early board makers just put the address in the first EEPROM locations. */ /* This does memcmp(eedata, eedata+16, 8) */ for (i = 0; i < 8; i ++) if (ee_data[i] != ee_data[16+i]) sa_offset = 20; if (ee_data[0] == 0xff && ee_data[1] == 0xff && ee_data[2] == 0) { sa_offset = 2; /* Grrr, damn Matrox boards. */ } for (i = 0; i < ETH_ALEN; i ++) { nic->node_addr[i] = ee_data[i + sa_offset]; sum += ee_data[i + sa_offset]; } } /* Lite-On boards have the address byte-swapped. */ if ((nic->node_addr[0] == 0xA0 || nic->node_addr[0] == 0xC0) && nic->node_addr[1] == 0x00) for (i = 0; i < ETH_ALEN; i+=2) { char tmp = nic->node_addr[i]; nic->node_addr[i] = nic->node_addr[i+1]; nic->node_addr[i+1] = tmp; } if (sum == 0 || sum == ETH_ALEN*0xff) { printf("%s: EEPROM not present!\n", tp->nic_name); for (i = 0; i < ETH_ALEN-1; i++) nic->node_addr[i] = last_phys_addr[i]; nic->node_addr[i] = last_phys_addr[i] + 1; } for (i = 0; i < ETH_ALEN; i++) last_phys_addr[i] = nic->node_addr[i]; DBG ( "%s: %s at ioaddr %hX\n", tp->nic_name, eth_ntoa ( nic->node_addr ), (unsigned int) ioaddr ); tp->chip_id = chip_idx; tp->revision = chip_rev; tp->csr0 = csr0; /* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles. And the ASIX must have a burst limit or horrible things happen. */ if (chip_idx == DC21143 && chip_rev == 65) tp->csr0 &= ~0x01000000; else if (tp->flags & IS_ASIX) tp->csr0 |= 0x2000; if (media_cap[tp->default_port] & MediaIsMII) { static const u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 }; tp->mii_advertise = media2advert[tp->default_port - 9]; tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */ } /* This is logically part of the probe routine, but too complex to write inline. */ if (tp->flags & HAS_MEDIA_TABLE) { memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom)); parse_eeprom(nic); } start_link(nic); /* reset the device and make ready for tx and rx of packets */ tulip_reset(nic); nic->nic_op = &tulip_operations; /* give the board a chance to reset before returning */ tulip_wait(4*TICKS_PER_SEC); return 1; } static void start_link(struct nic *nic) { int i; #ifdef TULIP_DEBUG_WHERE whereami("start_link\n"); #endif if ((tp->flags & ALWAYS_CHECK_MII) || (tp->mtable && tp->mtable->has_mii) || ( ! tp->mtable && (tp->flags & HAS_MII))) { unsigned int phy, phy_idx; if (tp->mtable && tp->mtable->has_mii) { for (i = 0; i < tp->mtable->leafcount; i++) if (tp->mtable->mleaf[i].media == 11) { tp->cur_index = i; tp->saved_if_port = tp->if_port; select_media(nic, 2); tp->if_port = tp->saved_if_port; break; } } /* Find the connected MII xcvrs. */ for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys); phy++) { int mii_status = mdio_read(nic, phy, 1); if ((mii_status & 0x8301) == 0x8001 || ((mii_status & 0x8000) == 0 && (mii_status & 0x7800) != 0)) { int mii_reg0 = mdio_read(nic, phy, 0); int mii_advert = mdio_read(nic, phy, 4); int to_advert; if (tp->mii_advertise) to_advert = tp->mii_advertise; else if (tp->advertising[phy_idx]) to_advert = tp->advertising[phy_idx]; else /* Leave unchanged. */ tp->mii_advertise = to_advert = mii_advert; tp->phys[phy_idx++] = phy; printf("%s: MII transceiver %d config %hX status %hX advertising %hX.\n", tp->nic_name, phy, mii_reg0, mii_status, mii_advert); /* Fixup for DLink with miswired PHY. */ if (mii_advert != to_advert) { printf("%s: Advertising %hX on PHY %d previously advertising %hX.\n", tp->nic_name, to_advert, phy, mii_advert); mdio_write(nic, phy, 4, to_advert); } /* Enable autonegotiation: some boards default to off. */ mdio_write(nic, phy, 0, mii_reg0 | (tp->full_duplex ? 0x1100 : 0x1000) | (media_cap[tp->default_port]&MediaIs100 ? 0x2000:0)); } } tp->mii_cnt = phy_idx; if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) { printf("%s: ***WARNING***: No MII transceiver found!\n", tp->nic_name); tp->phys[0] = 1; } } /* Reset the xcvr interface and turn on heartbeat. */ switch (tp->chip_id) { case DC21040: outl(0x00000000, ioaddr + CSR13); outl(0x00000004, ioaddr + CSR13); break; case DC21041: /* This is nway_start(). */ if (tp->sym_advertise == 0) tp->sym_advertise = 0x0061; outl(0x00000000, ioaddr + CSR13); outl(0xFFFFFFFF, ioaddr + CSR14); outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ outl(inl(ioaddr + CSR6) | 0x0200, ioaddr + CSR6); outl(0x0000EF01, ioaddr + CSR13); break; case DC21140: default: if (tp->mtable) outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12); break; case DC21142: case PNIC2: if (tp->mii_cnt || media_cap[tp->if_port] & MediaIsMII) { outl(0x82020000, ioaddr + CSR6); outl(0x0000, ioaddr + CSR13); outl(0x0000, ioaddr + CSR14); outl(0x820E0000, ioaddr + CSR6); } else nway_start(nic); break; case LC82C168: if ( ! tp->mii_cnt) { tp->nway = 1; tp->nwayset = 0; outl(0x00420000, ioaddr + CSR6); outl(0x30, ioaddr + CSR12); outl(0x0001F078, ioaddr + 0xB8); outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */ } break; case MX98713: case COMPEX9881: outl(0x00000000, ioaddr + CSR6); outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */ outl(0x00000001, ioaddr + CSR13); break; case MX98715: case MX98725: outl(0x01a80000, ioaddr + CSR6); outl(0xFFFFFFFF, ioaddr + CSR14); outl(0x00001000, ioaddr + CSR12); break; case COMET: /* No initialization necessary. */ break; } } static void nway_start(struct nic *nic __unused) { int csr14 = ((tp->sym_advertise & 0x0780) << 9) | ((tp->sym_advertise&0x0020)<<1) | 0xffbf; #ifdef TULIP_DEBUG_WHERE whereami("nway_start\n"); #endif tp->if_port = 0; tp->nway = tp->mediasense = 1; tp->nwayset = tp->lpar = 0; if (tp->chip_id == PNIC2) { tp->csr6 = 0x01000000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0); return; } #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Restarting internal NWay autonegotiation, %X.\n", tp->nic_name, csr14); #endif outl(0x0001, ioaddr + CSR13); outl(csr14, ioaddr + CSR14); tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0); outl(tp->csr6, ioaddr + CSR6); if (tp->mtable && tp->mtable->csr15dir) { outl(tp->mtable->csr15dir, ioaddr + CSR15); outl(tp->mtable->csr15val, ioaddr + CSR15); } else if (tp->chip_id != PNIC2) outw(0x0008, ioaddr + CSR15); if (tp->chip_id == DC21041) /* Trigger NWAY. */ outl(0xEF01, ioaddr + CSR12); else outl(0x1301, ioaddr + CSR12); } static void init_media(struct nic *nic) { int i; #ifdef TULIP_DEBUG_WHERE whereami("init_media\n"); #endif tp->saved_if_port = tp->if_port; if (tp->if_port == 0) tp->if_port = tp->default_port; /* Allow selecting a default media. */ i = 0; if (tp->mtable == NULL) goto media_picked; if (tp->if_port) { int looking_for = media_cap[tp->if_port] & MediaIsMII ? 11 : (tp->if_port == 12 ? 0 : tp->if_port); for (i = 0; i < tp->mtable->leafcount; i++) if (tp->mtable->mleaf[i].media == looking_for) { printf("%s: Using user-specified media %s.\n", tp->nic_name, medianame[tp->if_port]); goto media_picked; } } if ((tp->mtable->defaultmedia & 0x0800) == 0) { int looking_for = tp->mtable->defaultmedia & 15; for (i = 0; i < tp->mtable->leafcount; i++) if (tp->mtable->mleaf[i].media == looking_for) { printf("%s: Using EEPROM-set media %s.\n", tp->nic_name, medianame[looking_for]); goto media_picked; } } /* Start sensing first non-full-duplex media. */ for (i = tp->mtable->leafcount - 1; (media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--) ; media_picked: tp->csr6 = 0; tp->cur_index = i; tp->nwayset = 0; if (tp->if_port) { if (tp->chip_id == DC21143 && media_cap[tp->if_port] & MediaIsMII) { /* We must reset the media CSRs when we force-select MII mode. */ outl(0x0000, ioaddr + CSR13); outl(0x0000, ioaddr + CSR14); outl(0x0008, ioaddr + CSR15); } select_media(nic, 1); return; } switch(tp->chip_id) { case DC21041: /* tp->nway = 1;*/ nway_start(nic); break; case DC21142: if (tp->mii_cnt) { select_media(nic, 1); #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Using MII transceiver %d, status %hX.\n", tp->nic_name, tp->phys[0], mdio_read(nic, tp->phys[0], 1)); #endif outl(0x82020000, ioaddr + CSR6); tp->csr6 = 0x820E0000; tp->if_port = 11; outl(0x0000, ioaddr + CSR13); outl(0x0000, ioaddr + CSR14); } else nway_start(nic); break; case PNIC2: nway_start(nic); break; case LC82C168: if (tp->mii_cnt) { tp->if_port = 11; tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0); outl(0x0001, ioaddr + CSR15); } else if (inl(ioaddr + CSR5) & TPLnkPass) pnic_do_nway(nic); else { /* Start with 10mbps to do autonegotiation. */ outl(0x32, ioaddr + CSR12); tp->csr6 = 0x00420000; outl(0x0001B078, ioaddr + 0xB8); outl(0x0201B078, ioaddr + 0xB8); } break; case MX98713: case COMPEX9881: tp->if_port = 0; tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0); outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); break; case MX98715: case MX98725: /* Provided by BOLO, Macronix - 12/10/1998. */ tp->if_port = 0; tp->csr6 = 0x01a80200; outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0); break; case COMET: /* Enable automatic Tx underrun recovery */ outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88); tp->if_port = 0; tp->csr6 = 0x00040000; break; case AX88140: case AX88141: tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100; break; default: select_media(nic, 1); } } static void pnic_do_nway(struct nic *nic __unused) { u32 phy_reg = inl(ioaddr + 0xB8); u32 new_csr6 = tp->csr6 & ~0x40C40200; #ifdef TULIP_DEBUG_WHERE whereami("pnic_do_nway\n"); #endif if (phy_reg & 0x78000000) { /* Ignore baseT4 */ if (phy_reg & 0x20000000) tp->if_port = 5; else if (phy_reg & 0x40000000) tp->if_port = 3; else if (phy_reg & 0x10000000) tp->if_port = 4; else if (phy_reg & 0x08000000) tp->if_port = 0; tp->nwayset = 1; new_csr6 = (tp->if_port & 1) ? 0x01860000 : 0x00420000; outl(0x32 | (tp->if_port & 1), ioaddr + CSR12); if (tp->if_port & 1) outl(0x1F868, ioaddr + 0xB8); if (phy_reg & 0x30000000) { tp->full_duplex = 1; new_csr6 |= 0x00000200; } #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: PNIC autonegotiated status %X, %s.\n", tp->nic_name, phy_reg, medianame[tp->if_port]); #endif if (tp->csr6 != new_csr6) { tp->csr6 = new_csr6; outl(tp->csr6 | 0x0002, ioaddr + CSR6); /* Restart Tx */ outl(tp->csr6 | 0x2002, ioaddr + CSR6); } } } /* Set up the transceiver control registers for the selected media type. */ static void select_media(struct nic *nic, int startup) { struct mediatable *mtable = tp->mtable; u32 new_csr6; int i; #ifdef TULIP_DEBUG_WHERE whereami("select_media\n"); #endif if (mtable) { struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index]; unsigned char *p = mleaf->leafdata; switch (mleaf->type) { case 0: /* 21140 non-MII xcvr. */ #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Using a 21140 non-MII transceiver" " with control setting %hhX.\n", tp->nic_name, p[1]); #endif tp->if_port = p[0]; if (startup) outl(mtable->csr12dir | 0x100, ioaddr + CSR12); outl(p[1], ioaddr + CSR12); new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18); break; case 2: case 4: { u16 setup[5]; u32 csr13val, csr14val, csr15dir, csr15val; for (i = 0; i < 5; i++) setup[i] = get_u16(&p[i*2 + 1]); tp->if_port = p[0] & 15; if (media_cap[tp->if_port] & MediaAlwaysFD) tp->full_duplex = 1; if (startup && mtable->has_reset) { struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset]; unsigned char *rst = rleaf->leafdata; #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Resetting the transceiver.\n", tp->nic_name); #endif for (i = 0; i < rst[0]; i++) outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15); } #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: 21143 non-MII %s transceiver control " "%hX/%hX.\n", tp->nic_name, medianame[tp->if_port], setup[0], setup[1]); #endif if (p[0] & 0x40) { /* SIA (CSR13-15) setup values are provided. */ csr13val = setup[0]; csr14val = setup[1]; csr15dir = (setup[3]<<16) | setup[2]; csr15val = (setup[4]<<16) | setup[2]; outl(0, ioaddr + CSR13); outl(csr14val, ioaddr + CSR14); outl(csr15dir, ioaddr + CSR15); /* Direction */ outl(csr15val, ioaddr + CSR15); /* Data */ outl(csr13val, ioaddr + CSR13); } else { csr13val = 1; csr14val = 0x0003FF7F; csr15dir = (setup[0]<<16) | 0x0008; csr15val = (setup[1]<<16) | 0x0008; if (tp->if_port <= 4) csr14val = t21142_csr14[tp->if_port]; if (startup) { outl(0, ioaddr + CSR13); outl(csr14val, ioaddr + CSR14); } outl(csr15dir, ioaddr + CSR15); /* Direction */ outl(csr15val, ioaddr + CSR15); /* Data */ if (startup) outl(csr13val, ioaddr + CSR13); } #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Setting CSR15 to %X/%X.\n", tp->nic_name, csr15dir, csr15val); #endif if (mleaf->type == 4) new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18); else new_csr6 = 0x82420000; break; } case 1: case 3: { int phy_num = p[0]; int init_length = p[1]; u16 *misc_info; tp->if_port = 11; new_csr6 = 0x020E0000; if (mleaf->type == 3) { /* 21142 */ u16 *init_sequence = (u16*)(p+2); u16 *reset_sequence = &((u16*)(p+3))[init_length]; int reset_length = p[2 + init_length*2]; misc_info = reset_sequence + reset_length; if (startup) for (i = 0; i < reset_length; i++) outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); for (i = 0; i < init_length; i++) outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); } else { u8 *init_sequence = p + 2; u8 *reset_sequence = p + 3 + init_length; int reset_length = p[2 + init_length]; misc_info = (u16*)(reset_sequence + reset_length); if (startup) { outl(mtable->csr12dir | 0x100, ioaddr + CSR12); for (i = 0; i < reset_length; i++) outl(reset_sequence[i], ioaddr + CSR12); } for (i = 0; i < init_length; i++) outl(init_sequence[i], ioaddr + CSR12); } tp->advertising[phy_num] = get_u16(&misc_info[1]) | 1; if (startup < 2) { if (tp->mii_advertise == 0) tp->mii_advertise = tp->advertising[phy_num]; #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Advertising %hX on MII %d.\n", tp->nic_name, tp->mii_advertise, tp->phys[phy_num]); #endif mdio_write(nic, tp->phys[phy_num], 4, tp->mii_advertise); } break; } default: printf("%s: Invalid media table selection %d.\n", tp->nic_name, mleaf->type); new_csr6 = 0x020E0000; } #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Using media type %s, CSR12 is %hhX.\n", tp->nic_name, medianame[tp->if_port], inl(ioaddr + CSR12) & 0xff); #endif } else if (tp->chip_id == DC21041) { int port = tp->if_port <= 4 ? tp->if_port : 0; #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: 21041 using media %s, CSR12 is %hX.\n", tp->nic_name, medianame[port == 3 ? 12: port], inl(ioaddr + CSR12)); #endif outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */ outl(t21041_csr14[port], ioaddr + CSR14); outl(t21041_csr15[port], ioaddr + CSR15); outl(t21041_csr13[port], ioaddr + CSR13); new_csr6 = 0x80020000; } else if (tp->chip_id == LC82C168) { if (startup && ! tp->medialock) tp->if_port = tp->mii_cnt ? 11 : 0; #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: PNIC PHY status is %hX, media %s.\n", tp->nic_name, inl(ioaddr + 0xB8), medianame[tp->if_port]); #endif if (tp->mii_cnt) { new_csr6 = 0x810C0000; outl(0x0001, ioaddr + CSR15); outl(0x0201B07A, ioaddr + 0xB8); } else if (startup) { /* Start with 10mbps to do autonegotiation. */ outl(0x32, ioaddr + CSR12); new_csr6 = 0x00420000; outl(0x0001B078, ioaddr + 0xB8); outl(0x0201B078, ioaddr + 0xB8); } else if (tp->if_port == 3 || tp->if_port == 5) { outl(0x33, ioaddr + CSR12); new_csr6 = 0x01860000; /* Trigger autonegotiation. */ outl(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8); } else { outl(0x32, ioaddr + CSR12); new_csr6 = 0x00420000; outl(0x1F078, ioaddr + 0xB8); } } else if (tp->chip_id == DC21040) { /* 21040 */ /* Turn on the xcvr interface. */ #ifdef TULIP_DEBUG int csr12 = inl(ioaddr + CSR12); if (tulip_debug > 1) printf("%s: 21040 media type is %s, CSR12 is %hhX.\n", tp->nic_name, medianame[tp->if_port], csr12); #endif if (media_cap[tp->if_port] & MediaAlwaysFD) tp->full_duplex = 1; new_csr6 = 0x20000; /* Set the full duplux match frame. */ outl(FULL_DUPLEX_MAGIC, ioaddr + CSR11); outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */ if (t21040_csr13[tp->if_port] & 8) { outl(0x0705, ioaddr + CSR14); outl(0x0006, ioaddr + CSR15); } else { outl(0xffff, ioaddr + CSR14); outl(0x0000, ioaddr + CSR15); } outl(0x8f01 | t21040_csr13[tp->if_port], ioaddr + CSR13); } else { /* Unknown chip type with no media table. */ if (tp->default_port == 0) tp->if_port = tp->mii_cnt ? 11 : 3; if (media_cap[tp->if_port] & MediaIsMII) { new_csr6 = 0x020E0000; } else if (media_cap[tp->if_port] & MediaIsFx) { new_csr6 = 0x028600000; } else new_csr6 = 0x038600000; #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: No media description table, assuming " "%s transceiver, CSR12 %hhX.\n", tp->nic_name, medianame[tp->if_port], inl(ioaddr + CSR12)); #endif } tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0); return; } /* Check the MII negotiated duplex and change the CSR6 setting if required. Return 0 if everything is OK. Return < 0 if the transceiver is missing or has no link beat. */ static int tulip_check_duplex(struct nic *nic) { unsigned int bmsr, lpa, negotiated, new_csr6; bmsr = mdio_read(nic, tp->phys[0], 1); lpa = mdio_read(nic, tp->phys[0], 5); #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: MII status %#x, Link partner report " "%#x.\n", tp->nic_name, bmsr, lpa); #endif if (bmsr == 0xffff) return -2; if ((bmsr & 4) == 0) { int new_bmsr = mdio_read(nic, tp->phys[0], 1); if ((new_bmsr & 4) == 0) { #ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: No link beat on the MII interface," " status %#x.\n", tp->nic_name, new_bmsr); #endif return -1; } } tp->full_duplex = lpa & 0x140; new_csr6 = tp->csr6; negotiated = lpa & tp->advertising[0]; if(negotiated & 0x380) new_csr6 &= ~0x400000; else new_csr6 |= 0x400000; if (tp->full_duplex) new_csr6 |= 0x200; else new_csr6 &= ~0x200; if (new_csr6 != tp->csr6) { tp->csr6 = new_csr6; #ifdef TULIP_DEBUG if (tulip_debug > 0) printf("%s: Setting %s-duplex based on MII" "#%d link partner capability of %#x.\n", tp->nic_name, tp->full_duplex ? "full" : "half", tp->phys[0], lpa); #endif return 1; } return 0; } static struct pci_device_id tulip_nics[] = { PCI_ROM(0x1011, 0x0002, "dc21040", "Digital Tulip", 0), PCI_ROM(0x1011, 0x0009, "ds21140", "Digital Tulip Fast", 0), PCI_ROM(0x1011, 0x0014, "dc21041", "Digital Tulip+", 0), PCI_ROM(0x1011, 0x0019, "ds21142", "Digital Tulip 21142", 0), PCI_ROM(0x10b7, 0x9300, "3csoho100b-tx","3ComSOHO100B-TX", 0), PCI_ROM(0x10b9, 0x5261, "ali1563", "ALi 1563 integrated ethernet", 0), PCI_ROM(0x10d9, 0x0512, "mx98713", "Macronix MX987x3", 0), PCI_ROM(0x10d9, 0x0531, "mx98715", "Macronix MX987x5", 0), PCI_ROM(0x1113, 0x1217, "mxic-98715", "Macronix MX987x5", 0), PCI_ROM(0x11ad, 0xc115, "lc82c115", "LinkSys LNE100TX", 0), PCI_ROM(0x11ad, 0x0002, "82c168", "Netgear FA310TX", 0), PCI_ROM(0x1282, 0x9100, "dm9100", "Davicom 9100", 0), PCI_ROM(0x1282, 0x9102, "dm9102", "Davicom 9102", 0), PCI_ROM(0x1282, 0x9009, "dm9009", "Davicom 9009", 0), PCI_ROM(0x1282, 0x9132, "dm9132", "Davicom 9132", 0), PCI_ROM(0x1317, 0x0985, "centaur-p", "ADMtek Centaur-P", 0), PCI_ROM(0x1317, 0x0981, "an981", "ADMtek AN981 Comet", 0), /* ADMTek Centaur-P (stmicro) */ PCI_ROM(0x1113, 0x1216, "an983", "ADMTek AN983 Comet", 0), PCI_ROM(0x1317, 0x9511, "an983b", "ADMTek Comet 983b", 0), PCI_ROM(0x1317, 0x1985, "centaur-c", "ADMTek Centaur-C", 0), PCI_ROM(0x8086, 0x0039, "intel21145", "Intel Tulip", 0), PCI_ROM(0x125b, 0x1400, "ax88140", "ASIX AX88140", 0), PCI_ROM(0x11f6, 0x9881, "rl100tx", "Compex RL100-TX", 0), PCI_ROM(0x115d, 0x0003, "xircomtulip", "Xircom Tulip", 0), PCI_ROM(0x104a, 0x0981, "tulip-0981", "Tulip 0x104a 0x0981", 0), PCI_ROM(0x104a, 0x2774, "SGThomson-STE10100A", "Tulip 0x104a 0x2774", 0), /*Modified by Ramesh Chander*/ PCI_ROM(0x1113, 0x9511, "tulip-9511", "Tulip 0x1113 0x9511", 0), PCI_ROM(0x1186, 0x1561, "tulip-1561", "Tulip 0x1186 0x1561", 0), PCI_ROM(0x1259, 0xa120, "tulip-a120", "Tulip 0x1259 0xa120", 0), PCI_ROM(0x13d1, 0xab02, "tulip-ab02", "Tulip 0x13d1 0xab02", 0), PCI_ROM(0x13d1, 0xab03, "tulip-ab03", "Tulip 0x13d1 0xab03", 0), PCI_ROM(0x13d1, 0xab08, "tulip-ab08", "Tulip 0x13d1 0xab08", 0), PCI_ROM(0x14f1, 0x1803, "lanfinity", "Conexant LANfinity", 0), PCI_ROM(0x1626, 0x8410, "tulip-8410", "Tulip 0x1626 0x8410", 0), PCI_ROM(0x1737, 0xab08, "tulip-1737-ab08","Tulip 0x1737 0xab08", 0), PCI_ROM(0x1737, 0xab09, "tulip-ab09", "Tulip 0x1737 0xab09", 0), }; PCI_DRIVER ( tulip_driver, tulip_nics, PCI_NO_CLASS ); DRIVER ( "Tulip", nic_driver, pci_driver, tulip_driver, tulip_probe, tulip_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/tlan.c0000664000000000000000000013421612524662415020320 0ustar /************************************************************************** * * tlan.c -- Etherboot device driver for the Texas Instruments ThunderLAN * Written 2003-2003 by Timothy Legge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Portions of this code based on: * lan.c: Linux ThunderLan Driver: * * by James Banks * * (C) 1997-1998 Caldera, Inc. * (C) 1998 James Banks * (C) 1999-2001 Torben Mathiasen * (C) 2002 Samuel Chessman * * REVISION HISTORY: * ================ * v1.0 07-08-2003 timlegge Initial not quite working version * v1.1 07-27-2003 timlegge Sync 5.0 and 5.1 versions * v1.2 08-19-2003 timlegge Implement Multicast Support * v1.3 08-23-2003 timlegge Fix the transmit Function * v1.4 01-17-2004 timlegge Initial driver output cleanup * * Indent Options: indent -kr -i8 ***************************************************************************/ FILE_LICENCE ( GPL2_OR_LATER ); #include "etherboot.h" #include "nic.h" #include #include #include #include "tlan.h" #define drv_version "v1.4" #define drv_date "01-17-2004" /* NIC specific static variables go here */ #define HZ 100 #define TX_TIME_OUT (6*HZ) /* Condensed operations for readability. */ #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) static void TLan_ResetLists(struct nic *nic __unused); static void TLan_ResetAdapter(struct nic *nic __unused); static void TLan_FinishReset(struct nic *nic __unused); static void TLan_EeSendStart(u16); static int TLan_EeSendByte(u16, u8, int); static void TLan_EeReceiveByte(u16, u8 *, int); static int TLan_EeReadByte(u16 io_base, u8, u8 *); static void TLan_PhyDetect(struct nic *nic); static void TLan_PhyPowerDown(struct nic *nic); static void TLan_PhyPowerUp(struct nic *nic); static void TLan_SetMac(struct nic *nic __unused, int areg, unsigned char *mac); static void TLan_PhyReset(struct nic *nic); static void TLan_PhyStartLink(struct nic *nic); static void TLan_PhyFinishAutoNeg(struct nic *nic); #ifdef MONITOR static void TLan_PhyMonitor(struct nic *nic); #endif static void refill_rx(struct nic *nic __unused); static int TLan_MiiReadReg(struct nic *nic __unused, u16, u16, u16 *); static void TLan_MiiSendData(u16, u32, unsigned); static void TLan_MiiSync(u16); static void TLan_MiiWriteReg(struct nic *nic __unused, u16, u16, u16); static const char *media[] = { "10BaseT-HD ", "10BaseT-FD ", "100baseTx-HD ", "100baseTx-FD", "100baseT4", 0 }; /* This much match tlan_pci_tbl[]! */ enum tlan_nics { NETEL10 = 0, NETEL100 = 1, NETFLEX3I = 2, THUNDER = 3, NETFLEX3B = 4, NETEL100PI = 5, NETEL100D = 6, NETEL100I = 7, OC2183 = 8, OC2325 = 9, OC2326 = 10, NETELLIGENT_10_100_WS_5100 = 11, NETELLIGENT_10_T2 = 12 }; struct pci_id_info { const char *name; int nic_id; struct match_info { u32 pci, pci_mask, subsystem, subsystem_mask; u32 revision, revision_mask; /* Only 8 bits. */ } id; u32 flags; u16 addrOfs; /* Address Offset */ }; static const struct pci_id_info tlan_pci_tbl[] = { {"Compaq Netelligent 10 T PCI UTP", NETEL10, {0xae340e11, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_ACTIVITY_LED, 0x83}, {"Compaq Netelligent 10/100 TX PCI UTP", NETEL100, {0xae320e11, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_ACTIVITY_LED, 0x83}, {"Compaq Integrated NetFlex-3/P", NETFLEX3I, {0xae350e11, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_NONE, 0x83}, {"Compaq NetFlex-3/P", THUNDER, {0xf1300e11, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83}, {"Compaq NetFlex-3/P", NETFLEX3B, {0xf1500e11, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_NONE, 0x83}, {"Compaq Netelligent Integrated 10/100 TX UTP", NETEL100PI, {0xae430e11, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_ACTIVITY_LED, 0x83}, {"Compaq Netelligent Dual 10/100 TX PCI UTP", NETEL100D, {0xae400e11, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_NONE, 0x83}, {"Compaq Netelligent 10/100 TX Embedded UTP", NETEL100I, {0xb0110e11, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_NONE, 0x83}, {"Olicom OC-2183/2185", OC2183, {0x0013108d, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_USE_INTERN_10, 0x83}, {"Olicom OC-2325", OC2325, {0x0012108d, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_UNMANAGED_PHY, 0xF8}, {"Olicom OC-2326", OC2326, {0x0014108d, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_USE_INTERN_10, 0xF8}, {"Compaq Netelligent 10/100 TX UTP", NETELLIGENT_10_100_WS_5100, {0xb0300e11, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_ACTIVITY_LED, 0x83}, {"Compaq Netelligent 10 T/2 PCI UTP/Coax", NETELLIGENT_10_T2, {0xb0120e11, 0xffffffff, 0, 0, 0, 0}, TLAN_ADAPTER_NONE, 0x83}, {"Compaq NetFlex-3/E", 0, /* EISA card */ {0, 0, 0, 0, 0, 0}, TLAN_ADAPTER_ACTIVITY_LED | TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83}, {"Compaq NetFlex-3/E", 0, /* EISA card */ {0, 0, 0, 0, 0, 0}, TLAN_ADAPTER_ACTIVITY_LED, 0x83}, {0, 0, {0, 0, 0, 0, 0, 0}, 0, 0}, }; struct TLanList { u32 forward; u16 cStat; u16 frameSize; struct { u32 count; u32 address; } buffer[TLAN_BUFFERS_PER_LIST]; }; struct { struct TLanList tx_ring[TLAN_NUM_TX_LISTS]; unsigned char txb[TLAN_MAX_FRAME_SIZE * TLAN_NUM_TX_LISTS]; struct TLanList rx_ring[TLAN_NUM_RX_LISTS]; unsigned char rxb[TLAN_MAX_FRAME_SIZE * TLAN_NUM_RX_LISTS]; } tlan_buffers __shared; #define tx_ring tlan_buffers.tx_ring #define txb tlan_buffers.txb #define rx_ring tlan_buffers.rx_ring #define rxb tlan_buffers.rxb typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE]; static int chip_idx; /***************************************************************** * TLAN Private Information Structure * ****************************************************************/ static struct tlan_private { unsigned short vendor_id; /* PCI Vendor code */ unsigned short dev_id; /* PCI Device code */ const char *nic_name; unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indicies */ unsigned rx_buf_sz; /* Based on mtu + Slack */ struct TLanList *txList; u32 txHead; u32 txInProgress; u32 txTail; int eoc; u32 phyOnline; u32 aui; u32 duplex; u32 phy[2]; u32 phyNum; u32 speed; u8 tlanRev; u8 tlanFullDuplex; u8 link; u8 neg_be_verbose; } TLanPrivateInfo; static struct tlan_private *priv; static u32 BASE; /*************************************************************** * TLan_ResetLists * * Returns: * Nothing * Parms: * dev The device structure with the list * stuctures to be reset. * * This routine sets the variables associated with managing * the TLAN lists to their initial values. * **************************************************************/ static void TLan_ResetLists(struct nic *nic __unused) { int i; struct TLanList *list; priv->txHead = 0; priv->txTail = 0; for (i = 0; i < TLAN_NUM_TX_LISTS; i++) { list = &tx_ring[i]; list->cStat = TLAN_CSTAT_UNUSED; list->buffer[0].address = virt_to_bus(txb + (i * TLAN_MAX_FRAME_SIZE)); list->buffer[2].count = 0; list->buffer[2].address = 0; list->buffer[9].address = 0; } priv->cur_rx = 0; priv->rx_buf_sz = (TLAN_MAX_FRAME_SIZE); // priv->rx_head_desc = &rx_ring[0]; /* Initialize all the Rx descriptors */ for (i = 0; i < TLAN_NUM_RX_LISTS; i++) { rx_ring[i].forward = virt_to_le32desc(&rx_ring[i + 1]); rx_ring[i].cStat = TLAN_CSTAT_READY; rx_ring[i].frameSize = TLAN_MAX_FRAME_SIZE; rx_ring[i].buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER; rx_ring[i].buffer[0].address = virt_to_le32desc(&rxb[i * TLAN_MAX_FRAME_SIZE]); rx_ring[i].buffer[1].count = 0; rx_ring[i].buffer[1].address = 0; } /* Mark the last entry as wrapping the ring */ rx_ring[i - 1].forward = virt_to_le32desc(&rx_ring[0]); priv->dirty_rx = (unsigned int) (i - TLAN_NUM_RX_LISTS); } /* TLan_ResetLists */ /*************************************************************** * TLan_Reset * * Returns: * 0 * Parms: * dev Pointer to device structure of adapter * to be reset. * * This function resets the adapter and it's physical * device. See Chap. 3, pp. 9-10 of the "ThunderLAN * Programmer's Guide" for details. The routine tries to * implement what is detailed there, though adjustments * have been made. * **************************************************************/ void TLan_ResetAdapter(struct nic *nic __unused) { int i; u32 addr; u32 data; u8 data8; priv->tlanFullDuplex = FALSE; priv->phyOnline = 0; /* 1. Assert reset bit. */ data = inl(BASE + TLAN_HOST_CMD); data |= TLAN_HC_AD_RST; outl(data, BASE + TLAN_HOST_CMD); udelay(1000); /* 2. Turn off interrupts. ( Probably isn't necessary ) */ data = inl(BASE + TLAN_HOST_CMD); data |= TLAN_HC_INT_OFF; outl(data, BASE + TLAN_HOST_CMD); /* 3. Clear AREGs and HASHs. */ for (i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4) { TLan_DioWrite32(BASE, (u16) i, 0); } /* 4. Setup NetConfig register. */ data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN; TLan_DioWrite16(BASE, TLAN_NET_CONFIG, (u16) data); /* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */ outl(TLAN_HC_LD_TMR | 0x3f, BASE + TLAN_HOST_CMD); outl(TLAN_HC_LD_THR | 0x0, BASE + TLAN_HOST_CMD); /* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */ outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR); addr = BASE + TLAN_DIO_DATA + TLAN_NET_SIO; TLan_SetBit(TLAN_NET_SIO_NMRST, addr); /* 7. Setup the remaining registers. */ if (priv->tlanRev >= 0x30) { data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC; TLan_DioWrite8(BASE, TLAN_INT_DIS, data8); } TLan_PhyDetect(nic); data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN; if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_BIT_RATE_PHY) { data |= TLAN_NET_CFG_BIT; if (priv->aui == 1) { TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x0a); } else if (priv->duplex == TLAN_DUPLEX_FULL) { TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x00); priv->tlanFullDuplex = TRUE; } else { TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x08); } } if (priv->phyNum == 0) { data |= TLAN_NET_CFG_PHY_EN; } TLan_DioWrite16(BASE, TLAN_NET_CONFIG, (u16) data); if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY) { TLan_FinishReset(nic); } else { TLan_PhyPowerDown(nic); } } /* TLan_ResetAdapter */ void TLan_FinishReset(struct nic *nic) { u8 data; u32 phy; u8 sio; u16 status; u16 partner; u16 tlphy_ctl; u16 tlphy_par; u16 tlphy_id1, tlphy_id2; int i; phy = priv->phy[priv->phyNum]; data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP; if (priv->tlanFullDuplex) { data |= TLAN_NET_CMD_DUPLEX; } TLan_DioWrite8(BASE, TLAN_NET_CMD, data); data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5; if (priv->phyNum == 0) { data |= TLAN_NET_MASK_MASK7; } TLan_DioWrite8(BASE, TLAN_NET_MASK, data); TLan_DioWrite16(BASE, TLAN_MAX_RX, ((1536) + 7) & ~7); TLan_MiiReadReg(nic, phy, MII_PHYSID1, &tlphy_id1); TLan_MiiReadReg(nic, phy, MII_PHYSID2, &tlphy_id2); if ((tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY) || (priv->aui)) { status = BMSR_LSTATUS; DBG ( "TLAN: %s: Link forced.\n", priv->nic_name ); } else { TLan_MiiReadReg(nic, phy, MII_BMSR, &status); udelay(1000); TLan_MiiReadReg(nic, phy, MII_BMSR, &status); if ((status & BMSR_LSTATUS) && /* We only support link info on Nat.Sem. PHY's */ (tlphy_id1 == NAT_SEM_ID1) && (tlphy_id2 == NAT_SEM_ID2)) { TLan_MiiReadReg(nic, phy, MII_LPA, &partner); TLan_MiiReadReg(nic, phy, TLAN_TLPHY_PAR, &tlphy_par); DBG ( "TLAN: %s: Link active with ", priv->nic_name ); if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) { DBG ( "forced 10%sMbps %s-Duplex\n", tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0", tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half" ); } else { DBG ( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n", tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0", tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half" ); DBG ( "TLAN: Partner capability: " ); for (i = 5; i <= 10; i++) if (partner & (1 << i)) { DBG ( "%s", media[i - 5] ); } DBG ( "\n" ); } TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK); #ifdef MONITOR /* We have link beat..for now anyway */ priv->link = 1; /*Enabling link beat monitoring */ /* TLan_SetTimer( nic, (10*HZ), TLAN_TIMER_LINK_BEAT ); */ mdelay(10000); TLan_PhyMonitor(nic); #endif } else if (status & BMSR_LSTATUS) { DBG ( "TLAN: %s: Link active\n", priv->nic_name ); TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK); } } if (priv->phyNum == 0) { TLan_MiiReadReg(nic, phy, TLAN_TLPHY_CTL, &tlphy_ctl); tlphy_ctl |= TLAN_TC_INTEN; TLan_MiiWriteReg(nic, phy, TLAN_TLPHY_CTL, tlphy_ctl); sio = TLan_DioRead8(BASE, TLAN_NET_SIO); sio |= TLAN_NET_SIO_MINTEN; TLan_DioWrite8(BASE, TLAN_NET_SIO, sio); } if (status & BMSR_LSTATUS) { TLan_SetMac(nic, 0, nic->node_addr); priv->phyOnline = 1; outb((TLAN_HC_INT_ON >> 8), BASE + TLAN_HOST_CMD + 1); outl(virt_to_bus(&rx_ring), BASE + TLAN_CH_PARM); outl(TLAN_HC_GO | TLAN_HC_RT, BASE + TLAN_HOST_CMD); } else { DBG ( "TLAN: %s: Link inactive, will retry in 10 secs...\n", priv->nic_name ); /* TLan_SetTimer( nic, (10*HZ), TLAN_TIMER_FINISH_RESET ); */ mdelay(10000); TLan_FinishReset(nic); return; } } /* TLan_FinishReset */ /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int tlan_poll(struct nic *nic, int retrieve) { /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ /* nic->packetlen should contain length of data */ u32 framesize; u32 host_cmd = 0; u32 ack = 1; int eoc = 0; int entry = priv->cur_rx % TLAN_NUM_RX_LISTS; u16 tmpCStat = le32_to_cpu(rx_ring[entry].cStat); u16 host_int = inw(BASE + TLAN_HOST_INT); if ((tmpCStat & TLAN_CSTAT_FRM_CMP) && !retrieve) return 1; outw(host_int, BASE + TLAN_HOST_INT); if (!(tmpCStat & TLAN_CSTAT_FRM_CMP)) return 0; /* printf("PI-1: 0x%hX\n", host_int); */ if (tmpCStat & TLAN_CSTAT_EOC) eoc = 1; framesize = rx_ring[entry].frameSize; nic->packetlen = framesize; DBG ( ".%d.", (unsigned int) framesize ); memcpy(nic->packet, rxb + (priv->cur_rx * TLAN_MAX_FRAME_SIZE), nic->packetlen); rx_ring[entry].cStat = 0; DBG ( "%d", entry ); entry = (entry + 1) % TLAN_NUM_RX_LISTS; priv->cur_rx = entry; if (eoc) { if ((rx_ring[entry].cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) { ack |= TLAN_HC_GO | TLAN_HC_RT; host_cmd = TLAN_HC_ACK | ack | 0x001C0000; outl(host_cmd, BASE + TLAN_HOST_CMD); } } else { host_cmd = TLAN_HC_ACK | ack | (0x000C0000); outl(host_cmd, BASE + TLAN_HOST_CMD); DBG ( "AC: 0x%hX\n", inw(BASE + TLAN_CH_PARM) ); DBG ( "PI-2: 0x%hX\n", inw(BASE + TLAN_HOST_INT) ); } refill_rx(nic); return (1); /* initially as this is called to flush the input */ } static void refill_rx(struct nic *nic __unused) { int entry = 0; for (; (priv->cur_rx - priv->dirty_rx + TLAN_NUM_RX_LISTS) % TLAN_NUM_RX_LISTS > 0; priv->dirty_rx = (priv->dirty_rx + 1) % TLAN_NUM_RX_LISTS) { entry = priv->dirty_rx % TLAN_NUM_TX_LISTS; rx_ring[entry].frameSize = TLAN_MAX_FRAME_SIZE; rx_ring[entry].cStat = TLAN_CSTAT_READY; } } /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void tlan_transmit(struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) { /* Packet */ u16 nstype; u32 to; struct TLanList *tail_list; struct TLanList *head_list; u8 *tail_buffer; u32 ack = 0; u32 host_cmd; int eoc = 0; u16 tmpCStat; u16 host_int = inw(BASE + TLAN_HOST_INT); int entry = 0; DBG ( "INT0-0x%hX\n", host_int ); if (!priv->phyOnline) { printf("TRANSMIT: %s PHY is not ready\n", priv->nic_name); return; } tail_list = priv->txList + priv->txTail; if (tail_list->cStat != TLAN_CSTAT_UNUSED) { printf("TRANSMIT: %s is busy (Head=%p Tail=%x)\n", priv->nic_name, priv->txList, (unsigned int) priv->txTail); tx_ring[entry].cStat = TLAN_CSTAT_UNUSED; // priv->txBusyCount++; return; } tail_list->forward = 0; tail_buffer = txb + (priv->txTail * TLAN_MAX_FRAME_SIZE); /* send the packet to destination */ memcpy(tail_buffer, d, ETH_ALEN); memcpy(tail_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN); nstype = htons((u16) t); memcpy(tail_buffer + 2 * ETH_ALEN, (u8 *) & nstype, 2); memcpy(tail_buffer + ETH_HLEN, p, s); s += ETH_HLEN; s &= 0x0FFF; while (s < ETH_ZLEN) tail_buffer[s++] = '\0'; /*=====================================================*/ /* Receive * 0000 0000 0001 1100 * 0000 0000 0000 1100 * 0000 0000 0000 0011 = 0x0003 * * 0000 0000 0000 0000 0000 0000 0000 0011 * 0000 0000 0000 1100 0000 0000 0000 0000 = 0x000C0000 * * Transmit * 0000 0000 0001 1100 * 0000 0000 0000 0100 * 0000 0000 0000 0001 = 0x0001 * * 0000 0000 0000 0000 0000 0000 0000 0001 * 0000 0000 0000 0100 0000 0000 0000 0000 = 0x00040000 * */ /* Setup the transmit descriptor */ tail_list->frameSize = (u16) s; tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) s; tail_list->buffer[1].count = 0; tail_list->buffer[1].address = 0; tail_list->cStat = TLAN_CSTAT_READY; DBG ( "INT1-0x%hX\n", inw(BASE + TLAN_HOST_INT) ); if (!priv->txInProgress) { priv->txInProgress = 1; outl(virt_to_le32desc(tail_list), BASE + TLAN_CH_PARM); outl(TLAN_HC_GO, BASE + TLAN_HOST_CMD); } else { if (priv->txTail == 0) { DBG ( "Out buffer\n" ); (priv->txList + (TLAN_NUM_TX_LISTS - 1))->forward = virt_to_le32desc(tail_list); } else { DBG ( "Fix this \n" ); (priv->txList + (priv->txTail - 1))->forward = virt_to_le32desc(tail_list); } } CIRC_INC(priv->txTail, TLAN_NUM_TX_LISTS); DBG ( "INT2-0x%hX\n", inw(BASE + TLAN_HOST_INT) ); to = currticks() + TX_TIME_OUT; while ((tail_list->cStat == TLAN_CSTAT_READY) && currticks() < to); head_list = priv->txList + priv->txHead; while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) { ack++; if(tmpCStat & TLAN_CSTAT_EOC) eoc =1; head_list->cStat = TLAN_CSTAT_UNUSED; CIRC_INC(priv->txHead, TLAN_NUM_TX_LISTS); head_list = priv->txList + priv->txHead; } if(!ack) printf("Incomplete TX Frame\n"); if(eoc) { head_list = priv->txList + priv->txHead; if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) { outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM); ack |= TLAN_HC_GO; } else { priv->txInProgress = 0; } } if(ack) { host_cmd = TLAN_HC_ACK | ack; outl(host_cmd, BASE + TLAN_HOST_CMD); } if(priv->tlanRev < 0x30 ) { ack = 1; head_list = priv->txList + priv->txHead; if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) { outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM); ack |= TLAN_HC_GO; } else { priv->txInProgress = 0; } host_cmd = TLAN_HC_ACK | ack | 0x00140000; outl(host_cmd, BASE + TLAN_HOST_CMD); } if (currticks() >= to) { printf("TX Time Out"); } } /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void tlan_disable ( struct nic *nic __unused ) { /* put the card in its initial state */ /* This function serves 3 purposes. * This disables DMA and interrupts so we don't receive * unexpected packets or interrupts from the card after * etherboot has finished. * This frees resources so etherboot may use * this driver on another interface * This allows etherboot to reinitialize the interface * if something is something goes wrong. * */ outl(TLAN_HC_AD_RST, BASE + TLAN_HOST_CMD); } /************************************************************************** IRQ - Enable, Disable, or Force interrupts ***************************************************************************/ static void tlan_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } static struct nic_operations tlan_operations = { .connect = dummy_connect, .poll = tlan_poll, .transmit = tlan_transmit, .irq = tlan_irq, }; static void TLan_SetMulticastList(struct nic *nic) { int i; u8 tmp; /* !IFF_PROMISC */ tmp = TLan_DioRead8(BASE, TLAN_NET_CMD); TLan_DioWrite8(BASE, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF); /* IFF_ALLMULTI */ for(i = 0; i< 3; i++) TLan_SetMac(nic, i + 1, NULL); TLan_DioWrite32(BASE, TLAN_HASH_1, 0xFFFFFFFF); TLan_DioWrite32(BASE, TLAN_HASH_2, 0xFFFFFFFF); } /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside ***************************************************************************/ #define board_found 1 #define valid_link 0 static int tlan_probe ( struct nic *nic, struct pci_device *pci ) { u16 data = 0; int err; int i; if (pci->ioaddr == 0) return 0; nic->irqno = 0; nic->ioaddr = pci->ioaddr; BASE = pci->ioaddr; /* Set nic as PCI bus master */ adjust_pci_device(pci); /* Point to private storage */ priv = &TLanPrivateInfo; /* Figure out which chip we're dealing with */ i = 0; chip_idx = -1; while (tlan_pci_tbl[i].name) { if ((((u32) pci->device << 16) | pci->vendor) == (tlan_pci_tbl[i].id.pci & 0xffffffff)) { chip_idx = i; break; } i++; } priv->vendor_id = pci->vendor; priv->dev_id = pci->device; priv->nic_name = pci->driver_name; priv->eoc = 0; err = 0; for (i = 0; i < 6; i++) err |= TLan_EeReadByte(BASE, (u8) tlan_pci_tbl[chip_idx]. addrOfs + i, (u8 *) & nic->node_addr[i]); if (err) { printf ( "TLAN: %s: Error reading MAC from eeprom: %d\n", pci->driver_name, err); } else { DBG ( "%s: %s at ioaddr %#lX, ", pci->driver_name, eth_ntoa ( nic->node_addr ), pci->ioaddr ); } priv->tlanRev = TLan_DioRead8(BASE, TLAN_DEF_REVISION); printf("revision: 0x%hX\n", priv->tlanRev); TLan_ResetLists(nic); TLan_ResetAdapter(nic); data = inl(BASE + TLAN_HOST_CMD); data |= TLAN_HC_INT_OFF; outw(data, BASE + TLAN_HOST_CMD); TLan_SetMulticastList(nic); udelay(100); priv->txList = tx_ring; /* if (board_found && valid_link) {*/ /* point to NIC specific routines */ nic->nic_op = &tlan_operations; return 1; } /***************************************************************************** ****************************************************************************** ThunderLAN Driver Eeprom routines The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A EEPROM. These functions are based on information in Microchip's data sheet. I don't know how well this functions will work with other EEPROMs. ****************************************************************************** *****************************************************************************/ /*************************************************************** * TLan_EeSendStart * * Returns: * Nothing * Parms: * io_base The IO port base address for the * TLAN device with the EEPROM to * use. * * This function sends a start cycle to an EEPROM attached * to a TLAN chip. * **************************************************************/ void TLan_EeSendStart(u16 io_base) { u16 sio; outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR); sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO; TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); TLan_SetBit(TLAN_NET_SIO_EDATA, sio); TLan_SetBit(TLAN_NET_SIO_ETXEN, sio); TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); } /* TLan_EeSendStart */ /*************************************************************** * TLan_EeSendByte * * Returns: * If the correct ack was received, 0, otherwise 1 * Parms: io_base The IO port base address for the * TLAN device with the EEPROM to * use. * data The 8 bits of information to * send to the EEPROM. * stop If TLAN_EEPROM_STOP is passed, a * stop cycle is sent after the * byte is sent after the ack is * read. * * This function sends a byte on the serial EEPROM line, * driving the clock to send each bit. The function then * reverses transmission direction and reads an acknowledge * bit. * **************************************************************/ int TLan_EeSendByte(u16 io_base, u8 data, int stop) { int err; u8 place; u16 sio; outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR); sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO; /* Assume clock is low, tx is enabled; */ for (place = 0x80; place != 0; place >>= 1) { if (place & data) TLan_SetBit(TLAN_NET_SIO_EDATA, sio); else TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); } TLan_ClearBit(TLAN_NET_SIO_ETXEN, sio); TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); err = TLan_GetBit(TLAN_NET_SIO_EDATA, sio); TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); TLan_SetBit(TLAN_NET_SIO_ETXEN, sio); if ((!err) && stop) { TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* STOP, raise data while clock is high */ TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); TLan_SetBit(TLAN_NET_SIO_EDATA, sio); } return (err); } /* TLan_EeSendByte */ /*************************************************************** * TLan_EeReceiveByte * * Returns: * Nothing * Parms: * io_base The IO port base address for the * TLAN device with the EEPROM to * use. * data An address to a char to hold the * data sent from the EEPROM. * stop If TLAN_EEPROM_STOP is passed, a * stop cycle is sent after the * byte is received, and no ack is * sent. * * This function receives 8 bits of data from the EEPROM * over the serial link. It then sends and ack bit, or no * ack and a stop bit. This function is used to retrieve * data after the address of a byte in the EEPROM has been * sent. * **************************************************************/ void TLan_EeReceiveByte(u16 io_base, u8 * data, int stop) { u8 place; u16 sio; outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR); sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO; *data = 0; /* Assume clock is low, tx is enabled; */ TLan_ClearBit(TLAN_NET_SIO_ETXEN, sio); for (place = 0x80; place; place >>= 1) { TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); if (TLan_GetBit(TLAN_NET_SIO_EDATA, sio)) *data |= place; TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); } TLan_SetBit(TLAN_NET_SIO_ETXEN, sio); if (!stop) { TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* Ack = 0 */ TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); } else { TLan_SetBit(TLAN_NET_SIO_EDATA, sio); /* No ack = 1 (?) */ TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* STOP, raise data while clock is high */ TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); TLan_SetBit(TLAN_NET_SIO_EDATA, sio); } } /* TLan_EeReceiveByte */ /*************************************************************** * TLan_EeReadByte * * Returns: * No error = 0, else, the stage at which the error * occurred. * Parms: * io_base The IO port base address for the * TLAN device with the EEPROM to * use. * ee_addr The address of the byte in the * EEPROM whose contents are to be * retrieved. * data An address to a char to hold the * data obtained from the EEPROM. * * This function reads a byte of information from an byte * cell in the EEPROM. * **************************************************************/ int TLan_EeReadByte(u16 io_base, u8 ee_addr, u8 * data) { int err; int ret = 0; TLan_EeSendStart(io_base); err = TLan_EeSendByte(io_base, 0xA0, TLAN_EEPROM_ACK); if (err) { ret = 1; goto fail; } err = TLan_EeSendByte(io_base, ee_addr, TLAN_EEPROM_ACK); if (err) { ret = 2; goto fail; } TLan_EeSendStart(io_base); err = TLan_EeSendByte(io_base, 0xA1, TLAN_EEPROM_ACK); if (err) { ret = 3; goto fail; } TLan_EeReceiveByte(io_base, data, TLAN_EEPROM_STOP); fail: return ret; } /* TLan_EeReadByte */ /***************************************************************************** ****************************************************************************** ThunderLAN Driver MII Routines These routines are based on the information in Chap. 2 of the "ThunderLAN Programmer's Guide", pp. 15-24. ****************************************************************************** *****************************************************************************/ /*************************************************************** * TLan_MiiReadReg * * Returns: * 0 if ack received ok * 1 otherwise. * * Parms: * dev The device structure containing * The io address and interrupt count * for this device. * phy The address of the PHY to be queried. * reg The register whose contents are to be * retreived. * val A pointer to a variable to store the * retrieved value. * * This function uses the TLAN's MII bus to retreive the contents * of a given register on a PHY. It sends the appropriate info * and then reads the 16-bit register value from the MII bus via * the TLAN SIO register. * **************************************************************/ int TLan_MiiReadReg(struct nic *nic __unused, u16 phy, u16 reg, u16 * val) { u8 nack; u16 sio, tmp; u32 i; int err; int minten; err = FALSE; outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR); sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO; TLan_MiiSync(BASE); minten = TLan_GetBit(TLAN_NET_SIO_MINTEN, sio); if (minten) TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio); TLan_MiiSendData(BASE, 0x1, 2); /* Start ( 01b ) */ TLan_MiiSendData(BASE, 0x2, 2); /* Read ( 10b ) */ TLan_MiiSendData(BASE, phy, 5); /* Device # */ TLan_MiiSendData(BASE, reg, 5); /* Register # */ TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio); /* Change direction */ TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Clock Idle bit */ TLan_SetBit(TLAN_NET_SIO_MCLK, sio); TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Wait 300ns */ nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio); /* Check for ACK */ TLan_SetBit(TLAN_NET_SIO_MCLK, sio); /* Finish ACK */ if (nack) { /* No ACK, so fake it */ for (i = 0; i < 16; i++) { TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); TLan_SetBit(TLAN_NET_SIO_MCLK, sio); } tmp = 0xffff; err = TRUE; } else { /* ACK, so read data */ for (tmp = 0, i = 0x8000; i; i >>= 1) { TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio)) tmp |= i; TLan_SetBit(TLAN_NET_SIO_MCLK, sio); } } TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Idle cycle */ TLan_SetBit(TLAN_NET_SIO_MCLK, sio); if (minten) TLan_SetBit(TLAN_NET_SIO_MINTEN, sio); *val = tmp; return err; } /* TLan_MiiReadReg */ /*************************************************************** * TLan_MiiSendData * * Returns: * Nothing * Parms: * base_port The base IO port of the adapter in * question. * dev The address of the PHY to be queried. * data The value to be placed on the MII bus. * num_bits The number of bits in data that are to * be placed on the MII bus. * * This function sends on sequence of bits on the MII * configuration bus. * **************************************************************/ void TLan_MiiSendData(u16 base_port, u32 data, unsigned num_bits) { u16 sio; u32 i; if (num_bits == 0) return; outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR); sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO; TLan_SetBit(TLAN_NET_SIO_MTXEN, sio); for (i = (0x1 << (num_bits - 1)); i; i >>= 1) { TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); (void) TLan_GetBit(TLAN_NET_SIO_MCLK, sio); if (data & i) TLan_SetBit(TLAN_NET_SIO_MDATA, sio); else TLan_ClearBit(TLAN_NET_SIO_MDATA, sio); TLan_SetBit(TLAN_NET_SIO_MCLK, sio); (void) TLan_GetBit(TLAN_NET_SIO_MCLK, sio); } } /* TLan_MiiSendData */ /*************************************************************** * TLan_MiiSync * * Returns: * Nothing * Parms: * base_port The base IO port of the adapter in * question. * * This functions syncs all PHYs in terms of the MII configuration * bus. * **************************************************************/ void TLan_MiiSync(u16 base_port) { int i; u16 sio; outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR); sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO; TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio); for (i = 0; i < 32; i++) { TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); TLan_SetBit(TLAN_NET_SIO_MCLK, sio); } } /* TLan_MiiSync */ /*************************************************************** * TLan_MiiWriteReg * * Returns: * Nothing * Parms: * dev The device structure for the device * to write to. * phy The address of the PHY to be written to. * reg The register whose contents are to be * written. * val The value to be written to the register. * * This function uses the TLAN's MII bus to write the contents of a * given register on a PHY. It sends the appropriate info and then * writes the 16-bit register value from the MII configuration bus * via the TLAN SIO register. * **************************************************************/ void TLan_MiiWriteReg(struct nic *nic __unused, u16 phy, u16 reg, u16 val) { u16 sio; int minten; outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR); sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO; TLan_MiiSync(BASE); minten = TLan_GetBit(TLAN_NET_SIO_MINTEN, sio); if (minten) TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio); TLan_MiiSendData(BASE, 0x1, 2); /* Start ( 01b ) */ TLan_MiiSendData(BASE, 0x1, 2); /* Write ( 01b ) */ TLan_MiiSendData(BASE, phy, 5); /* Device # */ TLan_MiiSendData(BASE, reg, 5); /* Register # */ TLan_MiiSendData(BASE, 0x2, 2); /* Send ACK */ TLan_MiiSendData(BASE, val, 16); /* Send Data */ TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Idle cycle */ TLan_SetBit(TLAN_NET_SIO_MCLK, sio); if (minten) TLan_SetBit(TLAN_NET_SIO_MINTEN, sio); } /* TLan_MiiWriteReg */ /*************************************************************** * TLan_SetMac * * Returns: * Nothing * Parms: * dev Pointer to device structure of adapter * on which to change the AREG. * areg The AREG to set the address in (0 - 3). * mac A pointer to an array of chars. Each * element stores one byte of the address. * IE, it isn't in ascii. * * This function transfers a MAC address to one of the * TLAN AREGs (address registers). The TLAN chip locks * the register on writing to offset 0 and unlocks the * register after writing to offset 5. If NULL is passed * in mac, then the AREG is filled with 0's. * **************************************************************/ void TLan_SetMac(struct nic *nic __unused, int areg, unsigned char *mac) { int i; areg *= 6; if (mac != NULL) { for (i = 0; i < 6; i++) TLan_DioWrite8(BASE, TLAN_AREG_0 + areg + i, mac[i]); } else { for (i = 0; i < 6; i++) TLan_DioWrite8(BASE, TLAN_AREG_0 + areg + i, 0); } } /* TLan_SetMac */ /********************************************************************* * TLan_PhyDetect * * Returns: * Nothing * Parms: * dev A pointer to the device structure of the adapter * for which the PHY needs determined. * * So far I've found that adapters which have external PHYs * may also use the internal PHY for part of the functionality. * (eg, AUI/Thinnet). This function finds out if this TLAN * chip has an internal PHY, and then finds the first external * PHY (starting from address 0) if it exists). * ********************************************************************/ void TLan_PhyDetect(struct nic *nic) { u16 control; u16 hi; u16 lo; u32 phy; if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY) { priv->phyNum = 0xFFFF; return; } TLan_MiiReadReg(nic, TLAN_PHY_MAX_ADDR, MII_PHYSID1, &hi); if (hi != 0xFFFF) { priv->phy[0] = TLAN_PHY_MAX_ADDR; } else { priv->phy[0] = TLAN_PHY_NONE; } priv->phy[1] = TLAN_PHY_NONE; for (phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++) { TLan_MiiReadReg(nic, phy, MII_BMCR, &control); TLan_MiiReadReg(nic, phy, MII_PHYSID1, &hi); TLan_MiiReadReg(nic, phy, MII_PHYSID2, &lo); if ((control != 0xFFFF) || (hi != 0xFFFF) || (lo != 0xFFFF)) { printf("PHY found at %hX %hX %hX %hX\n", (unsigned int) phy, control, hi, lo); if ((priv->phy[1] == TLAN_PHY_NONE) && (phy != TLAN_PHY_MAX_ADDR)) { priv->phy[1] = phy; } } } if (priv->phy[1] != TLAN_PHY_NONE) { priv->phyNum = 1; } else if (priv->phy[0] != TLAN_PHY_NONE) { priv->phyNum = 0; } else { printf ("TLAN: Cannot initialize device, no PHY was found!\n"); } } /* TLan_PhyDetect */ void TLan_PhyPowerDown(struct nic *nic) { u16 value; DBG ( "%s: Powering down PHY(s).\n", priv->nic_name ); value = BMCR_PDOWN | BMCR_LOOPBACK | BMCR_ISOLATE; TLan_MiiSync(BASE); TLan_MiiWriteReg(nic, priv->phy[priv->phyNum], MII_BMCR, value); if ((priv->phyNum == 0) && (priv->phy[1] != TLAN_PHY_NONE) && (!(tlan_pci_tbl[chip_idx]. flags & TLAN_ADAPTER_USE_INTERN_10))) { TLan_MiiSync(BASE); TLan_MiiWriteReg(nic, priv->phy[1], MII_BMCR, value); } /* Wait for 50 ms and powerup * This is abitrary. It is intended to make sure the * tranceiver settles. */ /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP ); */ mdelay(50); TLan_PhyPowerUp(nic); } /* TLan_PhyPowerDown */ void TLan_PhyPowerUp(struct nic *nic) { u16 value; DBG ( "%s: Powering up PHY.\n", priv->nic_name ); TLan_MiiSync(BASE); value = BMCR_LOOPBACK; TLan_MiiWriteReg(nic, priv->phy[priv->phyNum], MII_BMCR, value); TLan_MiiSync(BASE); /* Wait for 500 ms and reset the * tranceiver. The TLAN docs say both 50 ms and * 500 ms, so do the longer, just in case. */ mdelay(500); TLan_PhyReset(nic); /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET ); */ } /* TLan_PhyPowerUp */ void TLan_PhyReset(struct nic *nic) { u16 phy; u16 value; phy = priv->phy[priv->phyNum]; DBG ( "%s: Reseting PHY.\n", priv->nic_name ); TLan_MiiSync(BASE); value = BMCR_LOOPBACK | BMCR_RESET; TLan_MiiWriteReg(nic, phy, MII_BMCR, value); TLan_MiiReadReg(nic, phy, MII_BMCR, &value); while (value & BMCR_RESET) { TLan_MiiReadReg(nic, phy, MII_BMCR, &value); } /* Wait for 500 ms and initialize. * I don't remember why I wait this long. * I've changed this to 50ms, as it seems long enough. */ /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK ); */ mdelay(50); TLan_PhyStartLink(nic); } /* TLan_PhyReset */ void TLan_PhyStartLink(struct nic *nic) { u16 ability; u16 control; u16 data; u16 phy; u16 status; u16 tctl; phy = priv->phy[priv->phyNum]; DBG ( "%s: Trying to activate link.\n", priv->nic_name ); TLan_MiiReadReg(nic, phy, MII_BMSR, &status); TLan_MiiReadReg(nic, phy, MII_BMSR, &ability); if ((status & BMSR_ANEGCAPABLE) && (!priv->aui)) { ability = status >> 11; if (priv->speed == TLAN_SPEED_10 && priv->duplex == TLAN_DUPLEX_HALF) { TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x0000); } else if (priv->speed == TLAN_SPEED_10 && priv->duplex == TLAN_DUPLEX_FULL) { priv->tlanFullDuplex = TRUE; TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x0100); } else if (priv->speed == TLAN_SPEED_100 && priv->duplex == TLAN_DUPLEX_HALF) { TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x2000); } else if (priv->speed == TLAN_SPEED_100 && priv->duplex == TLAN_DUPLEX_FULL) { priv->tlanFullDuplex = TRUE; TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x2100); } else { /* Set Auto-Neg advertisement */ TLan_MiiWriteReg(nic, phy, MII_ADVERTISE, (ability << 5) | 1); /* Enablee Auto-Neg */ TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x1000); /* Restart Auto-Neg */ TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x1200); /* Wait for 4 sec for autonegotiation * to complete. The max spec time is less than this * but the card need additional time to start AN. * .5 sec should be plenty extra. */ DBG ( "TLAN: %s: Starting autonegotiation.\n", priv->nic_name ); mdelay(4000); TLan_PhyFinishAutoNeg(nic); /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN ); */ return; } } if ((priv->aui) && (priv->phyNum != 0)) { priv->phyNum = 0; data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN; TLan_DioWrite16(BASE, TLAN_NET_CONFIG, data); mdelay(50); /* TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN ); */ TLan_PhyPowerDown(nic); return; } else if (priv->phyNum == 0) { control = 0; TLan_MiiReadReg(nic, phy, TLAN_TLPHY_CTL, &tctl); if (priv->aui) { tctl |= TLAN_TC_AUISEL; } else { tctl &= ~TLAN_TC_AUISEL; if (priv->duplex == TLAN_DUPLEX_FULL) { control |= BMCR_FULLDPLX; priv->tlanFullDuplex = TRUE; } if (priv->speed == TLAN_SPEED_100) { control |= BMCR_SPEED100; } } TLan_MiiWriteReg(nic, phy, MII_BMCR, control); TLan_MiiWriteReg(nic, phy, TLAN_TLPHY_CTL, tctl); } /* Wait for 2 sec to give the tranceiver time * to establish link. */ /* TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET ); */ mdelay(2000); TLan_FinishReset(nic); } /* TLan_PhyStartLink */ void TLan_PhyFinishAutoNeg(struct nic *nic) { u16 an_adv; u16 an_lpa; u16 data; u16 mode; u16 phy; u16 status; phy = priv->phy[priv->phyNum]; TLan_MiiReadReg(nic, phy, MII_BMSR, &status); udelay(1000); TLan_MiiReadReg(nic, phy, MII_BMSR, &status); if (!(status & BMSR_ANEGCOMPLETE)) { /* Wait for 8 sec to give the process * more time. Perhaps we should fail after a while. */ if (!priv->neg_be_verbose++) { printf ("TLAN: Giving autonegotiation more time.\n"); printf ("TLAN: Please check that your adapter has\n"); printf ("TLAN: been properly connected to a HUB or Switch.\n"); printf ("TLAN: Trying to establish link in the background...\n"); } mdelay(8000); TLan_PhyFinishAutoNeg(nic); /* TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN ); */ return; } DBG ( "TLAN: %s: Autonegotiation complete.\n", priv->nic_name ); TLan_MiiReadReg(nic, phy, MII_ADVERTISE, &an_adv); TLan_MiiReadReg(nic, phy, MII_LPA, &an_lpa); mode = an_adv & an_lpa & 0x03E0; if (mode & 0x0100) { printf("Full Duplex\n"); priv->tlanFullDuplex = TRUE; } else if (!(mode & 0x0080) && (mode & 0x0040)) { priv->tlanFullDuplex = TRUE; printf("Full Duplex\n"); } if ((!(mode & 0x0180)) && (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_USE_INTERN_10) && (priv->phyNum != 0)) { priv->phyNum = 0; data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN; TLan_DioWrite16(BASE, TLAN_NET_CONFIG, data); /* TLan_SetTimer( nic, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN ); */ mdelay(400); TLan_PhyPowerDown(nic); return; } if (priv->phyNum == 0) { if ((priv->duplex == TLAN_DUPLEX_FULL) || (an_adv & an_lpa & 0x0040)) { TLan_MiiWriteReg(nic, phy, MII_BMCR, BMCR_ANENABLE | BMCR_FULLDPLX); DBG ( "TLAN: Starting internal PHY with FULL-DUPLEX\n" ); } else { TLan_MiiWriteReg(nic, phy, MII_BMCR, BMCR_ANENABLE); DBG ( "TLAN: Starting internal PHY with HALF-DUPLEX\n" ); } } /* Wait for 100 ms. No reason in partiticular. */ /* TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET ); */ mdelay(100); TLan_FinishReset(nic); } /* TLan_PhyFinishAutoNeg */ #ifdef MONITOR /********************************************************************* * * TLan_phyMonitor * * Returns: * None * * Params: * dev The device structure of this device. * * * This function monitors PHY condition by reading the status * register via the MII bus. This can be used to give info * about link changes (up/down), and possible switch to alternate * media. * ********************************************************************/ void TLan_PhyMonitor(struct net_device *dev) { TLanPrivateInfo *priv = dev->priv; u16 phy; u16 phy_status; phy = priv->phy[priv->phyNum]; /* Get PHY status register */ TLan_MiiReadReg(nic, phy, MII_BMSR, &phy_status); /* Check if link has been lost */ if (!(phy_status & BMSR_LSTATUS)) { if (priv->link) { priv->link = 0; printf("TLAN: %s has lost link\n", priv->nic_name); priv->flags &= ~IFF_RUNNING; mdelay(2000); TLan_PhyMonitor(nic); /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); */ return; } } /* Link restablished? */ if ((phy_status & BMSR_LSTATUS) && !priv->link) { priv->link = 1; printf("TLAN: %s has reestablished link\n", priv->nic_name); priv->flags |= IFF_RUNNING; } /* Setup a new monitor */ /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); */ mdelay(2000); TLan_PhyMonitor(nic); } #endif /* MONITOR */ static struct pci_device_id tlan_nics[] = { PCI_ROM(0x0e11, 0xae34, "netel10", "Compaq Netelligent 10 T PCI UTP", 0), PCI_ROM(0x0e11, 0xae32, "netel100","Compaq Netelligent 10/100 TX PCI UTP", 0), PCI_ROM(0x0e11, 0xae35, "netflex3i", "Compaq Integrated NetFlex-3/P", 0), PCI_ROM(0x0e11, 0xf130, "thunder", "Compaq NetFlex-3/P", 0), PCI_ROM(0x0e11, 0xf150, "netflex3b", "Compaq NetFlex-3/P", 0), PCI_ROM(0x0e11, 0xae43, "netel100pi", "Compaq Netelligent Integrated 10/100 TX UTP", 0), PCI_ROM(0x0e11, 0xae40, "netel100d", "Compaq Netelligent Dual 10/100 TX PCI UTP", 0), PCI_ROM(0x0e11, 0xb011, "netel100i", "Compaq Netelligent 10/100 TX Embedded UTP", 0), PCI_ROM(0x108d, 0x0013, "oc2183", "Olicom OC-2183/2185", 0), PCI_ROM(0x108d, 0x0012, "oc2325", "Olicom OC-2325", 0), PCI_ROM(0x108d, 0x0014, "oc2326", "Olicom OC-2326", 0), PCI_ROM(0x0e11, 0xb030, "netelligent_10_100_ws_5100", "Compaq Netelligent 10/100 TX UTP", 0), PCI_ROM(0x0e11, 0xb012, "netelligent_10_t2", "Compaq Netelligent 10 T/2 PCI UTP/Coax", 0), }; PCI_DRIVER ( tlan_driver, tlan_nics, PCI_NO_CLASS ); DRIVER ( "TLAN/PCI", nic_driver, pci_driver, tlan_driver, tlan_probe, tlan_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/etherfabric.h0000664000000000000000000005074512524662415021651 0ustar /************************************************************************** * * GPL net driver for Level 5 Etherfabric network cards * * Written by Michael Brown * * Copyright Fen Systems Ltd. 2005 * Copyright Level 5 Networks Inc. 2005 * * This software may be used and distributed according to the terms of * the GNU General Public License (GPL), incorporated herein by * reference. Drivers based on or derived from this code fall under * the GPL and must retain the authorship, copyright and license * notice. This file is not a complete program and may only be used * when the entire operating system is licensed under the GPL. * ************************************************************************** */ FILE_LICENCE ( GPL_ANY ); #ifndef EFAB_BITFIELD_H #define EFAB_BITFIELD_H /** @file * * Etherfabric bitfield access * * Etherfabric NICs make extensive use of bitfields up to 128 bits * wide. Since there is no native 128-bit datatype on most systems, * and since 64-bit datatypes are inefficient on 32-bit systems and * vice versa, we wrap accesses in a way that uses the most efficient * datatype. * * The NICs are PCI devices and therefore little-endian. Since most * of the quantities that we deal with are DMAed to/from host memory, * we define our datatypes (efab_oword_t, efab_qword_t and * efab_dword_t) to be little-endian. * * In the less common case of using PIO for individual register * writes, we construct the little-endian datatype in host memory and * then use non-swapping equivalents of writel/writeq, rather than * constructing a native-endian datatype and relying on the implicit * byte-swapping done by writel/writeq. (We use a similar strategy * for register reads.) */ /** Dummy field low bit number */ #define EFAB_DUMMY_FIELD_LBN 0 /** Dummy field width */ #define EFAB_DUMMY_FIELD_WIDTH 0 /** Dword 0 low bit number */ #define EFAB_DWORD_0_LBN 0 /** Dword 0 width */ #define EFAB_DWORD_0_WIDTH 32 /** Dword 1 low bit number */ #define EFAB_DWORD_1_LBN 32 /** Dword 1 width */ #define EFAB_DWORD_1_WIDTH 32 /** Dword 2 low bit number */ #define EFAB_DWORD_2_LBN 64 /** Dword 2 width */ #define EFAB_DWORD_2_WIDTH 32 /** Dword 3 low bit number */ #define EFAB_DWORD_3_LBN 96 /** Dword 3 width */ #define EFAB_DWORD_3_WIDTH 32 /** Specified attribute (e.g. LBN) of the specified field */ #define EFAB_VAL(field,attribute) field ## _ ## attribute /** Low bit number of the specified field */ #define EFAB_LOW_BIT( field ) EFAB_VAL ( field, LBN ) /** Bit width of the specified field */ #define EFAB_WIDTH( field ) EFAB_VAL ( field, WIDTH ) /** High bit number of the specified field */ #define EFAB_HIGH_BIT(field) ( EFAB_LOW_BIT(field) + EFAB_WIDTH(field) - 1 ) /** Mask equal in width to the specified field. * * For example, a field with width 5 would have a mask of 0x1f. * * The maximum width mask that can be generated is 64 bits. */ #define EFAB_MASK64( field ) \ ( EFAB_WIDTH(field) == 64 ? ~( ( uint64_t ) 0 ) : \ ( ( ( ( ( uint64_t ) 1 ) << EFAB_WIDTH(field) ) ) - 1 ) ) /** Mask equal in width to the specified field. * * For example, a field with width 5 would have a mask of 0x1f. * * The maximum width mask that can be generated is 32 bits. Use * EFAB_MASK64 for higher width fields. */ #define EFAB_MASK32( field ) \ ( EFAB_WIDTH(field) == 32 ? ~( ( uint32_t ) 0 ) : \ ( ( ( ( ( uint32_t ) 1 ) << EFAB_WIDTH(field) ) ) - 1 ) ) /** A doubleword (i.e. 4 byte) datatype * * This datatype is defined to be little-endian. */ typedef union efab_dword { uint32_t u32[1]; uint32_t opaque; /* For bitwise operations between two efab_dwords */ } efab_dword_t; /** A quadword (i.e. 8 byte) datatype * * This datatype is defined to be little-endian. */ typedef union efab_qword { uint64_t u64[1]; uint32_t u32[2]; efab_dword_t dword[2]; } efab_qword_t; /** * An octword (eight-word, i.e. 16 byte) datatype * * This datatype is defined to be little-endian. */ typedef union efab_oword { uint64_t u64[2]; efab_qword_t qword[2]; uint32_t u32[4]; efab_dword_t dword[4]; } efab_oword_t; /** Format string for printing an efab_dword_t */ #define EFAB_DWORD_FMT "%08x" /** Format string for printing an efab_qword_t */ #define EFAB_QWORD_FMT "%08x:%08x" /** Format string for printing an efab_oword_t */ #define EFAB_OWORD_FMT "%08x:%08x:%08x:%08x" /** printk parameters for printing an efab_dword_t */ #define EFAB_DWORD_VAL(dword) \ ( ( unsigned int ) le32_to_cpu ( (dword).u32[0] ) ) /** printk parameters for printing an efab_qword_t */ #define EFAB_QWORD_VAL(qword) \ ( ( unsigned int ) le32_to_cpu ( (qword).u32[1] ) ), \ ( ( unsigned int ) le32_to_cpu ( (qword).u32[0] ) ) /** printk parameters for printing an efab_oword_t */ #define EFAB_OWORD_VAL(oword) \ ( ( unsigned int ) le32_to_cpu ( (oword).u32[3] ) ), \ ( ( unsigned int ) le32_to_cpu ( (oword).u32[2] ) ), \ ( ( unsigned int ) le32_to_cpu ( (oword).u32[1] ) ), \ ( ( unsigned int ) le32_to_cpu ( (oword).u32[0] ) ) /** * Extract bit field portion [low,high) from the native-endian element * which contains bits [min,max). * * For example, suppose "element" represents the high 32 bits of a * 64-bit value, and we wish to extract the bits belonging to the bit * field occupying bits 28-45 of this 64-bit value. * * Then EFAB_EXTRACT ( element, 32, 63, 28, 45 ) would give * * ( element ) << 4 * * The result will contain the relevant bits filled in in the range * [0,high-low), with garbage in bits [high-low+1,...). */ #define EFAB_EXTRACT_NATIVE( native_element, min ,max ,low ,high ) \ ( ( ( low > max ) || ( high < min ) ) ? 0 : \ ( ( low > min ) ? \ ( (native_element) >> ( low - min ) ) : \ ( (native_element) << ( min - low ) ) ) ) /** * Extract bit field portion [low,high) from the 64-bit little-endian * element which contains bits [min,max) */ #define EFAB_EXTRACT64( element, min, max, low, high ) \ EFAB_EXTRACT_NATIVE ( le64_to_cpu(element), min, max, low, high ) /** * Extract bit field portion [low,high) from the 32-bit little-endian * element which contains bits [min,max) */ #define EFAB_EXTRACT32( element, min, max, low, high ) \ EFAB_EXTRACT_NATIVE ( le32_to_cpu(element), min, max, low, high ) #define EFAB_EXTRACT_OWORD64( oword, low, high ) \ ( EFAB_EXTRACT64 ( (oword).u64[0], 0, 63, low, high ) | \ EFAB_EXTRACT64 ( (oword).u64[1], 64, 127, low, high ) ) #define EFAB_EXTRACT_QWORD64( qword, low, high ) \ ( EFAB_EXTRACT64 ( (qword).u64[0], 0, 63, low, high ) ) #define EFAB_EXTRACT_OWORD32( oword, low, high ) \ ( EFAB_EXTRACT32 ( (oword).u32[0], 0, 31, low, high ) | \ EFAB_EXTRACT32 ( (oword).u32[1], 32, 63, low, high ) | \ EFAB_EXTRACT32 ( (oword).u32[2], 64, 95, low, high ) | \ EFAB_EXTRACT32 ( (oword).u32[3], 96, 127, low, high ) ) #define EFAB_EXTRACT_QWORD32( qword, low, high ) \ ( EFAB_EXTRACT32 ( (qword).u32[0], 0, 31, low, high ) | \ EFAB_EXTRACT32 ( (qword).u32[1], 32, 63, low, high ) ) #define EFAB_EXTRACT_DWORD( dword, low, high ) \ ( EFAB_EXTRACT32 ( (dword).u32[0], 0, 31, low, high ) ) #define EFAB_OWORD_FIELD64( oword, field ) \ ( EFAB_EXTRACT_OWORD64 ( oword, EFAB_LOW_BIT ( field ), \ EFAB_HIGH_BIT ( field ) ) & \ EFAB_MASK64 ( field ) ) #define EFAB_QWORD_FIELD64( qword, field ) \ ( EFAB_EXTRACT_QWORD64 ( qword, EFAB_LOW_BIT ( field ), \ EFAB_HIGH_BIT ( field ) ) & \ EFAB_MASK64 ( field ) ) #define EFAB_OWORD_FIELD32( oword, field ) \ ( EFAB_EXTRACT_OWORD32 ( oword, EFAB_LOW_BIT ( field ), \ EFAB_HIGH_BIT ( field ) ) & \ EFAB_MASK32 ( field ) ) #define EFAB_QWORD_FIELD32( qword, field ) \ ( EFAB_EXTRACT_QWORD32 ( qword, EFAB_LOW_BIT ( field ), \ EFAB_HIGH_BIT ( field ) ) & \ EFAB_MASK32 ( field ) ) #define EFAB_DWORD_FIELD( dword, field ) \ ( EFAB_EXTRACT_DWORD ( dword, EFAB_LOW_BIT ( field ), \ EFAB_HIGH_BIT ( field ) ) & \ EFAB_MASK32 ( field ) ) #define EFAB_OWORD_IS_ZERO64( oword ) \ ( ! ( (oword).u64[0] || (oword).u64[1] ) ) #define EFAB_QWORD_IS_ZERO64( qword ) \ ( ! ( (qword).u64[0] ) ) #define EFAB_OWORD_IS_ZERO32( oword ) \ ( ! ( (oword).u32[0] || (oword).u32[1] || \ (oword).u32[2] || (oword).u32[3] ) ) #define EFAB_QWORD_IS_ZERO32( qword ) \ ( ! ( (qword).u32[0] || (qword).u32[1] ) ) #define EFAB_DWORD_IS_ZERO( dword ) \ ( ! ( (dword).u32[0] ) ) #define EFAB_OWORD_IS_ALL_ONES64( oword ) \ ( ( (oword).u64[0] & (oword).u64[1] ) == ~( ( uint64_t ) 0 ) ) #define EFAB_QWORD_IS_ALL_ONES64( qword ) \ ( (qword).u64[0] == ~( ( uint64_t ) 0 ) ) #define EFAB_OWORD_IS_ALL_ONES32( oword ) \ ( ( (oword).u32[0] & (oword).u32[1] & \ (oword).u32[2] & (oword).u32[3] ) == ~( ( uint32_t ) 0 ) ) #define EFAB_QWORD_IS_ALL_ONES32( qword ) \ ( ( (qword).u32[0] & (qword).u32[1] ) == ~( ( uint32_t ) 0 ) ) #define EFAB_DWORD_IS_ALL_ONES( dword ) \ ( (dword).u32[0] == ~( ( uint32_t ) 0 ) ) #if ( BITS_PER_LONG == 64 ) #define EFAB_OWORD_FIELD EFAB_OWORD_FIELD64 #define EFAB_QWORD_FIELD EFAB_QWORD_FIELD64 #define EFAB_OWORD_IS_ZERO EFAB_OWORD_IS_ZERO64 #define EFAB_QWORD_IS_ZERO EFAB_QWORD_IS_ZERO64 #define EFAB_OWORD_IS_ALL_ONES EFAB_OWORD_IS_ALL_ONES64 #define EFAB_QWORD_IS_ALL_ONES EFAB_QWORD_IS_ALL_ONES64 #else #define EFAB_OWORD_FIELD EFAB_OWORD_FIELD32 #define EFAB_QWORD_FIELD EFAB_QWORD_FIELD32 #define EFAB_OWORD_IS_ZERO EFAB_OWORD_IS_ZERO32 #define EFAB_QWORD_IS_ZERO EFAB_QWORD_IS_ZERO32 #define EFAB_OWORD_IS_ALL_ONES EFAB_OWORD_IS_ALL_ONES32 #define EFAB_QWORD_IS_ALL_ONES EFAB_QWORD_IS_ALL_ONES32 #endif /** * Construct bit field portion * * Creates the portion of the bit field [low,high) that lies within * the range [min,max). */ #define EFAB_INSERT_NATIVE64( min, max, low, high, value ) \ ( ( ( low > max ) || ( high < min ) ) ? 0 : \ ( ( low > min ) ? \ ( ( ( uint64_t ) (value) ) << ( low - min ) ) : \ ( ( ( uint64_t ) (value) ) >> ( min - low ) ) ) ) #define EFAB_INSERT_NATIVE32( min, max, low, high, value ) \ ( ( ( low > max ) || ( high < min ) ) ? 0 : \ ( ( low > min ) ? \ ( ( ( uint32_t ) (value) ) << ( low - min ) ) : \ ( ( ( uint32_t ) (value) ) >> ( min - low ) ) ) ) #define EFAB_INSERT_NATIVE( min, max, low, high, value ) \ ( ( ( ( max - min ) >= 32 ) || \ ( ( high - low ) >= 32 ) ) \ ? EFAB_INSERT_NATIVE64 ( min, max, low, high, value ) \ : EFAB_INSERT_NATIVE32 ( min, max, low, high, value ) ) /** * Construct bit field portion * * Creates the portion of the named bit field that lies within the * range [min,max). */ #define EFAB_INSERT_FIELD_NATIVE( min, max, field, value ) \ EFAB_INSERT_NATIVE ( min, max, EFAB_LOW_BIT ( field ), \ EFAB_HIGH_BIT ( field ), value ) /** * Construct bit field * * Creates the portion of the named bit fields that lie within the * range [min,max). */ #define EFAB_INSERT_FIELDS_NATIVE( min, max, \ field1, value1, \ field2, value2, \ field3, value3, \ field4, value4, \ field5, value5, \ field6, value6, \ field7, value7, \ field8, value8, \ field9, value9, \ field10, value10 ) \ ( EFAB_INSERT_FIELD_NATIVE ( min, max, field1, value1 ) | \ EFAB_INSERT_FIELD_NATIVE ( min, max, field2, value2 ) | \ EFAB_INSERT_FIELD_NATIVE ( min, max, field3, value3 ) | \ EFAB_INSERT_FIELD_NATIVE ( min, max, field4, value4 ) | \ EFAB_INSERT_FIELD_NATIVE ( min, max, field5, value5 ) | \ EFAB_INSERT_FIELD_NATIVE ( min, max, field6, value6 ) | \ EFAB_INSERT_FIELD_NATIVE ( min, max, field7, value7 ) | \ EFAB_INSERT_FIELD_NATIVE ( min, max, field8, value8 ) | \ EFAB_INSERT_FIELD_NATIVE ( min, max, field9, value9 ) | \ EFAB_INSERT_FIELD_NATIVE ( min, max, field10, value10 ) ) #define EFAB_INSERT_FIELDS64( ... ) \ cpu_to_le64 ( EFAB_INSERT_FIELDS_NATIVE ( __VA_ARGS__ ) ) #define EFAB_INSERT_FIELDS32( ... ) \ cpu_to_le32 ( EFAB_INSERT_FIELDS_NATIVE ( __VA_ARGS__ ) ) #define EFAB_POPULATE_OWORD64( oword, ... ) do { \ (oword).u64[0] = EFAB_INSERT_FIELDS64 ( 0, 63, __VA_ARGS__ );\ (oword).u64[1] = EFAB_INSERT_FIELDS64 ( 64, 127, __VA_ARGS__ );\ } while ( 0 ) #define EFAB_POPULATE_QWORD64( qword, ... ) do { \ (qword).u64[0] = EFAB_INSERT_FIELDS64 ( 0, 63, __VA_ARGS__ );\ } while ( 0 ) #define EFAB_POPULATE_OWORD32( oword, ... ) do { \ (oword).u32[0] = EFAB_INSERT_FIELDS32 ( 0, 31, __VA_ARGS__ );\ (oword).u32[1] = EFAB_INSERT_FIELDS32 ( 32, 63, __VA_ARGS__ );\ (oword).u32[2] = EFAB_INSERT_FIELDS32 ( 64, 95, __VA_ARGS__ );\ (oword).u32[3] = EFAB_INSERT_FIELDS32 ( 96, 127, __VA_ARGS__ );\ } while ( 0 ) #define EFAB_POPULATE_QWORD32( qword, ... ) do { \ (qword).u32[0] = EFAB_INSERT_FIELDS32 ( 0, 31, __VA_ARGS__ );\ (qword).u32[1] = EFAB_INSERT_FIELDS32 ( 32, 63, __VA_ARGS__ );\ } while ( 0 ) #define EFAB_POPULATE_DWORD( dword, ... ) do { \ (dword).u32[0] = EFAB_INSERT_FIELDS32 ( 0, 31, __VA_ARGS__ );\ } while ( 0 ) #if ( BITS_PER_LONG == 64 ) #define EFAB_POPULATE_OWORD EFAB_POPULATE_OWORD64 #define EFAB_POPULATE_QWORD EFAB_POPULATE_QWORD64 #else #define EFAB_POPULATE_OWORD EFAB_POPULATE_OWORD32 #define EFAB_POPULATE_QWORD EFAB_POPULATE_QWORD32 #endif /* Populate an octword field with various numbers of arguments */ #define EFAB_POPULATE_OWORD_10 EFAB_POPULATE_OWORD #define EFAB_POPULATE_OWORD_9( oword, ... ) \ EFAB_POPULATE_OWORD_10 ( oword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_OWORD_8( oword, ... ) \ EFAB_POPULATE_OWORD_9 ( oword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_OWORD_7( oword, ... ) \ EFAB_POPULATE_OWORD_8 ( oword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_OWORD_6( oword, ... ) \ EFAB_POPULATE_OWORD_7 ( oword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_OWORD_5( oword, ... ) \ EFAB_POPULATE_OWORD_6 ( oword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_OWORD_4( oword, ... ) \ EFAB_POPULATE_OWORD_5 ( oword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_OWORD_3( oword, ... ) \ EFAB_POPULATE_OWORD_4 ( oword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_OWORD_2( oword, ... ) \ EFAB_POPULATE_OWORD_3 ( oword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_OWORD_1( oword, ... ) \ EFAB_POPULATE_OWORD_2 ( oword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_ZERO_OWORD( oword ) \ EFAB_POPULATE_OWORD_1 ( oword, EFAB_DUMMY_FIELD, 0 ) #define EFAB_SET_OWORD( oword ) \ EFAB_POPULATE_OWORD_4 ( oword, \ EFAB_DWORD_0, 0xffffffff, \ EFAB_DWORD_1, 0xffffffff, \ EFAB_DWORD_2, 0xffffffff, \ EFAB_DWORD_3, 0xffffffff ) /* Populate a quadword field with various numbers of arguments */ #define EFAB_POPULATE_QWORD_10 EFAB_POPULATE_QWORD #define EFAB_POPULATE_QWORD_9( qword, ... ) \ EFAB_POPULATE_QWORD_10 ( qword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_QWORD_8( qword, ... ) \ EFAB_POPULATE_QWORD_9 ( qword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_QWORD_7( qword, ... ) \ EFAB_POPULATE_QWORD_8 ( qword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_QWORD_6( qword, ... ) \ EFAB_POPULATE_QWORD_7 ( qword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_QWORD_5( qword, ... ) \ EFAB_POPULATE_QWORD_6 ( qword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_QWORD_4( qword, ... ) \ EFAB_POPULATE_QWORD_5 ( qword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_QWORD_3( qword, ... ) \ EFAB_POPULATE_QWORD_4 ( qword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_QWORD_2( qword, ... ) \ EFAB_POPULATE_QWORD_3 ( qword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_QWORD_1( qword, ... ) \ EFAB_POPULATE_QWORD_2 ( qword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_ZERO_QWORD( qword ) \ EFAB_POPULATE_QWORD_1 ( qword, EFAB_DUMMY_FIELD, 0 ) #define EFAB_SET_QWORD( qword ) \ EFAB_POPULATE_QWORD_2 ( qword, \ EFAB_DWORD_0, 0xffffffff, \ EFAB_DWORD_1, 0xffffffff ) /* Populate a dword field with various numbers of arguments */ #define EFAB_POPULATE_DWORD_10 EFAB_POPULATE_DWORD #define EFAB_POPULATE_DWORD_9( dword, ... ) \ EFAB_POPULATE_DWORD_10 ( dword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_DWORD_8( dword, ... ) \ EFAB_POPULATE_DWORD_9 ( dword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_DWORD_7( dword, ... ) \ EFAB_POPULATE_DWORD_8 ( dword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_DWORD_6( dword, ... ) \ EFAB_POPULATE_DWORD_7 ( dword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_DWORD_5( dword, ... ) \ EFAB_POPULATE_DWORD_6 ( dword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_DWORD_4( dword, ... ) \ EFAB_POPULATE_DWORD_5 ( dword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_DWORD_3( dword, ... ) \ EFAB_POPULATE_DWORD_4 ( dword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_DWORD_2( dword, ... ) \ EFAB_POPULATE_DWORD_3 ( dword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_POPULATE_DWORD_1( dword, ... ) \ EFAB_POPULATE_DWORD_2 ( dword, EFAB_DUMMY_FIELD, 0, __VA_ARGS__ ) #define EFAB_ZERO_DWORD( dword ) \ EFAB_POPULATE_DWORD_1 ( dword, EFAB_DUMMY_FIELD, 0 ) #define EFAB_SET_DWORD( dword ) \ EFAB_POPULATE_DWORD_1 ( dword, EFAB_DWORD_0, 0xffffffff ) /* * Modify a named field within an already-populated structure. Used * for read-modify-write operations. * */ #define EFAB_INSERT_FIELD64( ... ) \ cpu_to_le64 ( EFAB_INSERT_FIELD_NATIVE ( __VA_ARGS__ ) ) #define EFAB_INSERT_FIELD32( ... ) \ cpu_to_le32 ( EFAB_INSERT_FIELD_NATIVE ( __VA_ARGS__ ) ) #define EFAB_INPLACE_MASK64( min, max, field ) \ EFAB_INSERT_FIELD64 ( min, max, field, EFAB_MASK64 ( field ) ) #define EFAB_INPLACE_MASK32( min, max, field ) \ EFAB_INSERT_FIELD32 ( min, max, field, EFAB_MASK32 ( field ) ) #define EFAB_SET_OWORD_FIELD64( oword, field, value ) do { \ (oword).u64[0] = ( ( (oword).u64[0] \ & ~EFAB_INPLACE_MASK64 ( 0, 63, field ) ) \ | EFAB_INSERT_FIELD64 ( 0, 63, field, value ) ); \ (oword).u64[1] = ( ( (oword).u64[1] \ & ~EFAB_INPLACE_MASK64 ( 64, 127, field ) ) \ | EFAB_INSERT_FIELD64 ( 64, 127, field, value ) ); \ } while ( 0 ) #define EFAB_SET_QWORD_FIELD64( qword, field, value ) do { \ (qword).u64[0] = ( ( (qword).u64[0] \ & ~EFAB_INPLACE_MASK64 ( 0, 63, field ) ) \ | EFAB_INSERT_FIELD64 ( 0, 63, field, value ) ); \ } while ( 0 ) #define EFAB_SET_OWORD_FIELD32( oword, field, value ) do { \ (oword).u32[0] = ( ( (oword).u32[0] \ & ~EFAB_INPLACE_MASK32 ( 0, 31, field ) ) \ | EFAB_INSERT_FIELD32 ( 0, 31, field, value ) ); \ (oword).u32[1] = ( ( (oword).u32[1] \ & ~EFAB_INPLACE_MASK32 ( 32, 63, field ) ) \ | EFAB_INSERT_FIELD32 ( 32, 63, field, value ) ); \ (oword).u32[2] = ( ( (oword).u32[2] \ & ~EFAB_INPLACE_MASK32 ( 64, 95, field ) ) \ | EFAB_INSERT_FIELD32 ( 64, 95, field, value ) ); \ (oword).u32[3] = ( ( (oword).u32[3] \ & ~EFAB_INPLACE_MASK32 ( 96, 127, field ) ) \ | EFAB_INSERT_FIELD32 ( 96, 127, field, value ) ); \ } while ( 0 ) #define EFAB_SET_QWORD_FIELD32( qword, field, value ) do { \ (qword).u32[0] = ( ( (qword).u32[0] \ & ~EFAB_INPLACE_MASK32 ( 0, 31, field ) ) \ | EFAB_INSERT_FIELD32 ( 0, 31, field, value ) ); \ (qword).u32[1] = ( ( (qword).u32[1] \ & ~EFAB_INPLACE_MASK32 ( 32, 63, field ) ) \ | EFAB_INSERT_FIELD32 ( 32, 63, field, value ) ); \ } while ( 0 ) #define EFAB_SET_DWORD_FIELD( dword, field, value ) do { \ (dword).u32[0] = ( ( (dword).u32[0] \ & ~EFAB_INPLACE_MASK32 ( 0, 31, field ) ) \ | EFAB_INSERT_FIELD32 ( 0, 31, field, value ) ); \ } while ( 0 ) #if ( BITS_PER_LONG == 64 ) #define EFAB_SET_OWORD_FIELD EFAB_SET_OWORD_FIELD64 #define EFAB_SET_QWORD_FIELD EFAB_SET_QWORD_FIELD64 #else #define EFAB_SET_OWORD_FIELD EFAB_SET_OWORD_FIELD32 #define EFAB_SET_QWORD_FIELD EFAB_SET_QWORD_FIELD32 #endif /* Used to avoid compiler warnings about shift range exceeding width * of the data types when dma_addr_t is only 32 bits wide. */ #define DMA_ADDR_T_WIDTH ( 8 * sizeof ( dma_addr_t ) ) #define EFAB_DMA_TYPE_WIDTH( width ) \ ( ( (width) < DMA_ADDR_T_WIDTH ) ? (width) : DMA_ADDR_T_WIDTH ) #define EFAB_DMA_MAX_MASK ( ( DMA_ADDR_T_WIDTH == 64 ) ? \ ~( ( uint64_t ) 0 ) : ~( ( uint32_t ) 0 ) ) #define EFAB_DMA_MASK(mask) ( (mask) & EFAB_DMA_MAX_MASK ) #endif /* EFAB_BITFIELD_H */ /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/w89c840.c0000664000000000000000000007365512524662415020421 0ustar /* * Etherboot - BOOTP/TFTP Bootstrap Program * * w89c840.c -- This file implements the winbond-840 driver for etherboot. * */ /* * Adapted by Igor V. Kovalenko * -- * OR * -- * Initial adaptaion stage, including testing, completed 23 August 2000. */ /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); /* * date version by what * Written: Aug 20 2000 V0.10 iko Initial revision. * changes: Aug 22 2000 V0.90 iko Works! * Aug 23 2000 V0.91 iko Cleanup, posted to etherboot * maintainer. * Aug 26 2000 V0.92 iko Fixed Rx ring handling. * First Linux Kernel (TM) * successfully loaded using * this driver. * Jan 07 2001 V0.93 iko Transmitter timeouts are handled * using timer2 routines. Proposed * by Ken Yap to eliminate CPU speed * dependency. * Dec 12 2003 V0.94 timlegge Fixed issues in 5.2, removed * interrupt usage, enabled * multicast support * * This is the etherboot driver for cards based on Winbond W89c840F chip. * * It was written from skeleton source, with Donald Becker's winbond-840.c * kernel driver as a guideline. Mostly the w89c840 related definitions * and the lower level routines have been cut-and-pasted into this source. * * Frankly speaking, about 90% of the code was obtained using cut'n'paste * sequence :) while the remainder appeared while brainstorming * Linux Kernel 2.4.0-testX source code. Thanks, Donald and Linus! * * There was a demand for using this card in a rather large * remote boot environment at MSKP OVTI Lab of * Moscow Institute for Physics and Technology (MIPT) -- http://www.mipt.ru/ * so you may count that for motivation. * */ /* * If you want to see debugging output then define W89C840_DEBUG */ /* #define W89C840_DEBUG */ /* * Keep using IO_OPS for Etherboot driver! */ #define USE_IO_OPS #include "etherboot.h" #include "nic.h" #include #include static const char *w89c840_version = "driver Version 0.94 - December 12, 2003"; /* Linux support functions */ #define virt_to_le32desc(addr) virt_to_bus(addr) #define le32desc_to_virt(addr) bus_to_virt(addr) /* #define cpu_to_le32(val) (val) #define le32_to_cpu(val) (val) */ /* Operational parameters that are set at compile time. */ /* Keep the ring sizes a power of two for compile efficiency. The compiler will convert '%'<2^N> into a bit mask. Making the Tx ring too large decreases the effectiveness of channel bonding and packet priority. There are no ill effects from too-large receive rings. */ #define TX_RING_SIZE 2 #define RX_RING_SIZE 2 /* The presumed FIFO size for working around the Tx-FIFO-overflow bug. To avoid overflowing we don't queue again until we have room for a full-size packet. */ #define TX_FIFO_SIZE (2048) #define TX_BUG_FIFO_LIMIT (TX_FIFO_SIZE-1514-16) /* Operational parameters that usually are not changed. */ /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (10*1000) #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ /* * Used to be this much CPU loops on Celeron@400 (?), * now using real timer and TX_TIMEOUT! * #define TX_LOOP_COUNT 10000000 */ #if !defined(__OPTIMIZE__) #warning You must compile this file with the correct options! #warning See the last lines of the source file. #error You must compile this driver with "-O". #endif enum chip_capability_flags {CanHaveMII=1, HasBrokenTx=2}; #ifdef USE_IO_OPS #define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER) #else #define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER) #endif static u32 driver_flags = CanHaveMII | HasBrokenTx; /* This driver was written to use PCI memory space, however some x86 systems work only with I/O space accesses. Pass -DUSE_IO_OPS to use PCI I/O space accesses instead of memory space. */ #ifdef USE_IO_OPS #undef readb #undef readw #undef readl #undef writeb #undef writew #undef writel #define readb inb #define readw inw #define readl inl #define writeb outb #define writew outw #define writel outl #endif /* Offsets to the Command and Status Registers, "CSRs". While similar to the Tulip, these registers are longword aligned. Note: It's not useful to define symbolic names for every register bit in the device. The name can only partially document the semantics and make the driver longer and more difficult to read. */ enum w840_offsets { PCIBusCfg=0x00, TxStartDemand=0x04, RxStartDemand=0x08, RxRingPtr=0x0C, TxRingPtr=0x10, IntrStatus=0x14, NetworkConfig=0x18, IntrEnable=0x1C, RxMissed=0x20, EECtrl=0x24, MIICtrl=0x24, BootRom=0x28, GPTimer=0x2C, CurRxDescAddr=0x30, CurRxBufAddr=0x34, /* Debug use */ MulticastFilter0=0x38, MulticastFilter1=0x3C, StationAddr=0x40, CurTxDescAddr=0x4C, CurTxBufAddr=0x50, }; /* Bits in the interrupt status/enable registers. */ /* The bits in the Intr Status/Enable registers, mostly interrupt sources. */ enum intr_status_bits { NormalIntr=0x10000, AbnormalIntr=0x8000, IntrPCIErr=0x2000, TimerInt=0x800, IntrRxDied=0x100, RxNoBuf=0x80, IntrRxDone=0x40, TxFIFOUnderflow=0x20, RxErrIntr=0x10, TxIdle=0x04, IntrTxStopped=0x02, IntrTxDone=0x01, }; /* Bits in the NetworkConfig register. */ enum rx_mode_bits { AcceptErr=0x80, AcceptRunt=0x40, AcceptBroadcast=0x20, AcceptMulticast=0x10, AcceptAllPhys=0x08, AcceptMyPhys=0x02, }; enum mii_reg_bits { MDIO_ShiftClk=0x10000, MDIO_DataIn=0x80000, MDIO_DataOut=0x20000, MDIO_EnbOutput=0x40000, MDIO_EnbIn = 0x00000, }; /* The Tulip Rx and Tx buffer descriptors. */ struct w840_rx_desc { s32 status; s32 length; u32 buffer1; u32 next_desc; }; struct w840_tx_desc { s32 status; s32 length; u32 buffer1, buffer2; /* We use only buffer 1. */ }; /* Bits in network_desc.status */ enum desc_status_bits { DescOwn=0x80000000, DescEndRing=0x02000000, DescUseLink=0x01000000, DescWholePkt=0x60000000, DescStartPkt=0x20000000, DescEndPkt=0x40000000, DescIntr=0x80000000, }; #define PRIV_ALIGN 15 /* Required alignment mask */ #define PRIV_ALIGN_BYTES 32 static struct winbond_private { /* Descriptor rings first for alignment. */ struct w840_rx_desc rx_ring[RX_RING_SIZE]; struct w840_tx_desc tx_ring[TX_RING_SIZE]; struct net_device *next_module; /* Link for devices of this type. */ void *priv_addr; /* Unaligned address for kfree */ const char *product_name; /* Frequently used values: keep some adjacent for cache effect. */ int chip_id, drv_flags; struct pci_dev *pci_dev; int csr6; struct w840_rx_desc *rx_head_desc; unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */ unsigned int rx_buf_sz; /* Based on MTU+slack. */ unsigned int cur_tx, dirty_tx; int tx_q_bytes; unsigned int tx_full:1; /* The Tx queue is full. */ /* These values are keep track of the transceiver/media in use. */ unsigned int full_duplex:1; /* Full-duplex operation requested. */ unsigned int duplex_lock:1; unsigned int medialock:1; /* Do not sense media. */ unsigned int default_port:4; /* Last dev->if_port value. */ /* MII transceiver section. */ int mii_cnt; /* MII device addresses. */ u16 advertising; /* NWay media advertisement */ unsigned char phys[2]; /* MII device addresses. */ } w840private __attribute__ ((aligned (PRIV_ALIGN_BYTES))); /* NIC specific static variables go here */ static int ioaddr; static unsigned short eeprom [0x40]; struct { char rx_packet[PKT_BUF_SZ * RX_RING_SIZE]; char tx_packet[PKT_BUF_SZ * TX_RING_SIZE]; } w89c840_buf __shared; static int eeprom_read(long ioaddr, int location); static int mdio_read(int base_address, int phy_id, int location); #if 0 static void mdio_write(int base_address, int phy_id, int location, int value); #endif static void check_duplex(void); static void set_rx_mode(void); static void init_ring(void); #if defined(W89C840_DEBUG) static void decode_interrupt(u32 intr_status) { printf("Interrupt status: "); #define TRACE_INTR(_intr_) \ if (intr_status & (_intr_)) { printf (" " #_intr_); } TRACE_INTR(NormalIntr); TRACE_INTR(AbnormalIntr); TRACE_INTR(IntrPCIErr); TRACE_INTR(TimerInt); TRACE_INTR(IntrRxDied); TRACE_INTR(RxNoBuf); TRACE_INTR(IntrRxDone); TRACE_INTR(TxFIFOUnderflow); TRACE_INTR(RxErrIntr); TRACE_INTR(TxIdle); TRACE_INTR(IntrTxStopped); TRACE_INTR(IntrTxDone); printf("\n"); /*sleep(1);*/ } #endif /************************************************************************** w89c840_reset - Reset adapter ***************************************************************************/ static void w89c840_reset(struct nic *nic) { int i; /* Reset the chip to erase previous misconfiguration. No hold time required! */ writel(0x00000001, ioaddr + PCIBusCfg); init_ring(); writel(virt_to_bus(w840private.rx_ring), ioaddr + RxRingPtr); writel(virt_to_bus(w840private.tx_ring), ioaddr + TxRingPtr); for (i = 0; i < ETH_ALEN; i++) writeb(nic->node_addr[i], ioaddr + StationAddr + i); /* Initialize other registers. */ /* Configure the PCI bus bursts and FIFO thresholds. 486: Set 8 longword cache alignment, 8 longword burst. 586: Set 16 longword cache alignment, no burst limit. Cache alignment bits 15:14 Burst length 13:8 0000 0000 align to cache 0800 8 longwords 4000 8 longwords 0100 1 longword 1000 16 longwords 8000 16 longwords 0200 2 longwords 2000 32 longwords C000 32 longwords 0400 4 longwords Wait the specified 50 PCI cycles after a reset by initializing Tx and Rx queues and the address filter list. */ writel(0xE010, ioaddr + PCIBusCfg); writel(0, ioaddr + RxStartDemand); w840private.csr6 = 0x20022002; check_duplex(); set_rx_mode(); /* Do not enable the interrupts Etherboot doesn't need them */ /* writel(0x1A0F5, ioaddr + IntrStatus); writel(0x1A0F5, ioaddr + IntrEnable); */ #if defined(W89C840_DEBUG) printf("winbond-840 : Done reset.\n"); #endif } #if 0 static void handle_intr(u32 intr_stat) { if ((intr_stat & (NormalIntr|AbnormalIntr)) == 0) { /* we are polling, do not return now */ /*return 0;*/ } else { /* Acknowledge all of the current interrupt sources ASAP. */ writel(intr_stat & 0x001ffff, ioaddr + IntrStatus); } if (intr_stat & AbnormalIntr) { /* There was an abnormal interrupt */ printf("\n-=- Abnormal interrupt.\n"); #if defined(W89C840_DEBUG) decode_interrupt(intr_stat); #endif if (intr_stat & RxNoBuf) { /* There was an interrupt */ printf("-=- <=> No receive buffers available.\n"); writel(0, ioaddr + RxStartDemand); } } } #endif /************************************************************************** w89c840_poll - Wait for a frame ***************************************************************************/ static int w89c840_poll(struct nic *nic, int retrieve) { /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ /* nic->packetlen should contain length of data */ int packet_received = 0; #if defined(W89C840_DEBUG) u32 intr_status = readl(ioaddr + IntrStatus); #endif do { /* Code from netdev_rx(dev) */ int entry = w840private.cur_rx % RX_RING_SIZE; struct w840_rx_desc *desc = w840private.rx_head_desc; s32 status = desc->status; if (status & DescOwn) { /* DescOwn bit is still set, we should wait for RX to complete */ packet_received = 0; break; } if ( !retrieve ) { packet_received = 1; break; } if ((status & 0x38008300) != 0x0300) { if ((status & 0x38000300) != 0x0300) { /* Ingore earlier buffers. */ if ((status & 0xffff) != 0x7fff) { printf("winbond-840 : Oversized Ethernet frame spanned " "multiple buffers, entry %d status %X !\n", w840private.cur_rx, (unsigned int) status); } } else if (status & 0x8000) { /* There was a fatal error. */ #if defined(W89C840_DEBUG) printf("winbond-840 : Receive error, Rx status %X :", status); if (status & 0x0890) { printf(" RXLEN_ERROR"); } if (status & 0x004C) { printf(", FRAME_ERROR"); } if (status & 0x0002) { printf(", CRC_ERROR"); } printf("\n"); #endif /* Simpy do a reset now... */ w89c840_reset(nic); packet_received = 0; break; } } else { /* Omit the four octet CRC from the length. */ int pkt_len = ((status >> 16) & 0x7ff) - 4; #if defined(W89C840_DEBUG) printf(" netdev_rx() normal Rx pkt ring %d length %d status %X\n", entry, pkt_len, status); #endif nic->packetlen = pkt_len; /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ memcpy(nic->packet, le32desc_to_virt(w840private.rx_ring[entry].buffer1), pkt_len); packet_received = 1; /* Release buffer to NIC */ w840private.rx_ring[entry].status = DescOwn; #if defined(W89C840_DEBUG) /* You will want this info for the initial debug. */ printf(" Rx data %hhX:%hhX:%hhX:%hhX:%hhX:" "%hhX %hhX:%hhX:%hhX:%hhX:%hhX:%hhX %hhX%hhX " "%hhX.%hhX.%hhX.%hhX.\n", nic->packet[0], nic->packet[1], nic->packet[2], nic->packet[3], nic->packet[4], nic->packet[5], nic->packet[6], nic->packet[7], nic->packet[8], nic->packet[9], nic->packet[10], nic->packet[11], nic->packet[12], nic->packet[13], nic->packet[14], nic->packet[15], nic->packet[16], nic->packet[17]); #endif } entry = (++w840private.cur_rx) % RX_RING_SIZE; w840private.rx_head_desc = &w840private.rx_ring[entry]; } while (0); return packet_received; } /************************************************************************** w89c840_transmit - Transmit a frame ***************************************************************************/ static void w89c840_transmit( struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) /* Packet */ { /* send the packet to destination */ unsigned entry; int transmit_status; unsigned long ct; /* Caution: the write order is important here, set the field with the "ownership" bits last. */ /* Fill in our transmit buffer */ entry = w840private.cur_tx % TX_RING_SIZE; memcpy (w89c840_buf.tx_packet, d, ETH_ALEN); /* dst */ memcpy (w89c840_buf.tx_packet + ETH_ALEN, nic->node_addr, ETH_ALEN);/*src*/ *((char *) w89c840_buf.tx_packet + 12) = t >> 8; /* type */ *((char *) w89c840_buf.tx_packet + 13) = t; memcpy (w89c840_buf.tx_packet + ETH_HLEN, p, s); s += ETH_HLEN; while (s < ETH_ZLEN) *((char *) w89c840_buf.tx_packet + ETH_HLEN + (s++)) = 0; w840private.tx_ring[entry].buffer1 = virt_to_le32desc(w89c840_buf.tx_packet); w840private.tx_ring[entry].length = (DescWholePkt | (u32) s); if (entry >= TX_RING_SIZE-1) /* Wrap ring */ w840private.tx_ring[entry].length |= (DescIntr | DescEndRing); w840private.tx_ring[entry].status = (DescOwn); w840private.cur_tx++; w840private.tx_q_bytes = (u16) s; writel(0, ioaddr + TxStartDemand); /* Work around horrible bug in the chip by marking the queue as full when we do not have FIFO room for a maximum sized packet. */ if ((w840private.drv_flags & HasBrokenTx) && w840private.tx_q_bytes > TX_BUG_FIFO_LIMIT) { /* Actually this is left to help finding error tails later in debugging... * See Linux kernel driver in winbond-840.c for details. */ w840private.tx_full = 1; } #if defined(W89C840_DEBUG) printf("winbond-840 : Transmit frame # %d size %d queued in slot %d.\n", w840private.cur_tx, s, entry); #endif /* Now wait for TX to complete. */ transmit_status = w840private.tx_ring[entry].status; ct = currticks(); { #if defined W89C840_DEBUG u32 intr_stat = 0; #endif while (1) { #if defined(W89C840_DEBUG) decode_interrupt(intr_stat); #endif while ( (transmit_status & DescOwn) && ct + TX_TIMEOUT < currticks()) { transmit_status = w840private.tx_ring[entry].status; } break; } } if ((transmit_status & DescOwn) == 0) { #if defined(W89C840_DEBUG) printf("winbond-840 : transmission complete after wait loop iterations, status %X\n", w840private.tx_ring[entry].status); #endif return; } /* Transmit timed out... */ printf("winbond-840 : transmission TIMEOUT : status %X\n", (unsigned int) w840private.tx_ring[entry].status); return; } /************************************************************************** w89c840_disable - Turn off ethernet interface ***************************************************************************/ static void w89c840_disable ( struct nic *nic ) { w89c840_reset(nic); /* Don't know what to do to disable the board. Is this needed at all? */ /* Yes, a live NIC can corrupt the loaded memory later [Ken] */ /* Stop the chip's Tx and Rx processes. */ writel(w840private.csr6 &= ~0x20FA, ioaddr + NetworkConfig); } /************************************************************************** w89c840_irq - Enable, Disable, or Force interrupts ***************************************************************************/ static void w89c840_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } static struct nic_operations w89c840_operations = { .connect = dummy_connect, .poll = w89c840_poll, .transmit = w89c840_transmit, .irq = w89c840_irq, }; static struct pci_device_id w89c840_nics[] = { PCI_ROM(0x1050, 0x0840, "winbond840", "Winbond W89C840F", 0), PCI_ROM(0x11f6, 0x2011, "compexrl100atx", "Compex RL100ATX", 0), }; PCI_DRIVER ( w89c840_driver, w89c840_nics, PCI_NO_CLASS ); /************************************************************************** w89c840_probe - Look for an adapter, this routine's visible to the outside ***************************************************************************/ static int w89c840_probe ( struct nic *nic, struct pci_device *p ) { u16 sum = 0; int i, j; unsigned short value; if (p->ioaddr == 0) return 0; nic->ioaddr = p->ioaddr; nic->irqno = 0; #if defined(W89C840_DEBUG) printf("winbond-840: PCI bus %hhX device function %hhX: I/O address: %hX\n", p->bus, p->devfn, ioaddr); #endif ioaddr = ioaddr & ~3; /* Mask the bit that says "this is an io addr" */ #define PCI_DEVICE_ID_WINBOND2_89C840 0x0840 #define PCI_DEVICE_ID_COMPEX_RL100ATX 0x2011 /* From Matt Hortman */ if (p->vendor == PCI_VENDOR_ID_WINBOND2 && p->device == PCI_DEVICE_ID_WINBOND2_89C840) { /* detected "Winbond W89c840 Fast Ethernet PCI NIC" */ } else if ( p->vendor == PCI_VENDOR_ID_COMPEX && p->device == PCI_DEVICE_ID_COMPEX_RL100ATX) { /* detected "Compex RL100ATX Fast Ethernet PCI NIC" */ } else { /* Gee, guess what? They missed again. */ printf("device ID : %X - is not a Compex RL100ATX NIC.\n", p->device); return 0; } printf(" %s\n", w89c840_version); adjust_pci_device(p); /* Ok. Got one. Read the eeprom. */ for (j = 0, i = 0; i < 0x40; i++) { value = eeprom_read(ioaddr, i); eeprom[i] = value; sum += value; } for (i=0;inode_addr[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff; } DBG ( "Ethernet addr: %s\n", eth_ntoa ( nic->node_addr ) ); #if defined(W89C840_DEBUG) printf("winbond-840: EEPROM checksum %hX, got eeprom", sum); #endif /* Reset the chip to erase previous misconfiguration. No hold time required! */ writel(0x00000001, ioaddr + PCIBusCfg); if (driver_flags & CanHaveMII) { int phy, phy_idx = 0; for (phy = 1; phy < 32 && phy_idx < 4; phy++) { int mii_status = mdio_read(ioaddr, phy, 1); if (mii_status != 0xffff && mii_status != 0x0000) { w840private.phys[phy_idx++] = phy; w840private.advertising = mdio_read(ioaddr, phy, 4); #if defined(W89C840_DEBUG) printf("winbond-840 : MII PHY found at address %d, status " "%X advertising %hX.\n", phy, mii_status, w840private.advertising); #endif } } w840private.mii_cnt = phy_idx; if (phy_idx == 0) { printf("winbond-840 : MII PHY not found -- this device may not operate correctly.\n"); } } /* point to NIC specific routines */ nic->nic_op = &w89c840_operations; w89c840_reset(nic); return 1; } /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. These are often serial bit streams generated by the host processor. The example below is for the common 93c46 EEPROM, 64 16 bit words. */ /* Delay between EEPROM clock transitions. No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that made udelay() unreliable. The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is depricated. */ #define eeprom_delay(ee_addr) readl(ee_addr) enum EEPROM_Ctrl_Bits { EE_ShiftClk=0x02, EE_Write0=0x801, EE_Write1=0x805, EE_ChipSelect=0x801, EE_DataIn=0x08, }; /* The EEPROM commands include the alway-set leading bit. */ enum EEPROM_Cmds { EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6), }; static int eeprom_read(long addr, int location) { int i; int retval = 0; int ee_addr = addr + EECtrl; int read_cmd = location | EE_ReadCmd; writel(EE_ChipSelect, ee_addr); /* Shift the read command bits out. */ for (i = 10; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0; writel(dataval, ee_addr); eeprom_delay(ee_addr); writel(dataval | EE_ShiftClk, ee_addr); eeprom_delay(ee_addr); } writel(EE_ChipSelect, ee_addr); for (i = 16; i > 0; i--) { writel(EE_ChipSelect | EE_ShiftClk, ee_addr); eeprom_delay(ee_addr); retval = (retval << 1) | ((readl(ee_addr) & EE_DataIn) ? 1 : 0); writel(EE_ChipSelect, ee_addr); eeprom_delay(ee_addr); } /* Terminate the EEPROM access. */ writel(0, ee_addr); return retval; } /* MII transceiver control section. Read and write the MII registers using software-generated serial MDIO protocol. See the MII specifications or DP83840A data sheet for details. The maximum data clock rate is 2.5 Mhz. The minimum timing is usually met by back-to-back 33Mhz PCI cycles. */ #define mdio_delay(mdio_addr) readl(mdio_addr) /* Set iff a MII transceiver on any interface requires mdio preamble. This only set with older tranceivers, so the extra code size of a per-interface flag is not worthwhile. */ static char mii_preamble_required = 1; #define MDIO_WRITE0 (MDIO_EnbOutput) #define MDIO_WRITE1 (MDIO_DataOut | MDIO_EnbOutput) /* Generate the preamble required for initial synchronization and a few older transceivers. */ static void mdio_sync(long mdio_addr) { int bits = 32; /* Establish sync by sending at least 32 logic ones. */ while (--bits >= 0) { writel(MDIO_WRITE1, mdio_addr); mdio_delay(mdio_addr); writel(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr); mdio_delay(mdio_addr); } } static int mdio_read(int base_address, int phy_id, int location) { long mdio_addr = base_address + MIICtrl; int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location; int i, retval = 0; if (mii_preamble_required) mdio_sync(mdio_addr); /* Shift the read command bits out. */ for (i = 15; i >= 0; i--) { int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; writel(dataval, mdio_addr); mdio_delay(mdio_addr); writel(dataval | MDIO_ShiftClk, mdio_addr); mdio_delay(mdio_addr); } /* Read the two transition, 16 data, and wire-idle bits. */ for (i = 20; i > 0; i--) { writel(MDIO_EnbIn, mdio_addr); mdio_delay(mdio_addr); retval = (retval << 1) | ((readl(mdio_addr) & MDIO_DataIn) ? 1 : 0); writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr); mdio_delay(mdio_addr); } return (retval>>1) & 0xffff; } #if 0 static void mdio_write(int base_address, int phy_id, int location, int value) { long mdio_addr = base_address + MIICtrl; int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value; int i; if (location == 4 && phy_id == w840private.phys[0]) w840private.advertising = value; if (mii_preamble_required) mdio_sync(mdio_addr); /* Shift the command bits out. */ for (i = 31; i >= 0; i--) { int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; writel(dataval, mdio_addr); mdio_delay(mdio_addr); writel(dataval | MDIO_ShiftClk, mdio_addr); mdio_delay(mdio_addr); } /* Clear out extra bits. */ for (i = 2; i > 0; i--) { writel(MDIO_EnbIn, mdio_addr); mdio_delay(mdio_addr); writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr); mdio_delay(mdio_addr); } return; } #endif static void check_duplex(void) { int mii_reg5 = mdio_read(ioaddr, w840private.phys[0], 5); int negotiated = mii_reg5 & w840private.advertising; int duplex; if (w840private.duplex_lock || mii_reg5 == 0xffff) return; duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040; if (w840private.full_duplex != duplex) { w840private.full_duplex = duplex; #if defined(W89C840_DEBUG) printf("winbond-840 : Setting %s-duplex based on MII # %d negotiated capability %X\n", duplex ? "full" : "half", w840private.phys[0], negotiated); #endif w840private.csr6 &= ~0x200; w840private.csr6 |= duplex ? 0x200 : 0; } } static void set_rx_mode(void) { u32 mc_filter[2]; /* Multicast hash filter */ u32 rx_mode; /* Accept all multicasts from now on. */ memset(mc_filter, 0xff, sizeof(mc_filter)); /* * works OK with multicast enabled. */ rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast; writel(mc_filter[0], ioaddr + MulticastFilter0); writel(mc_filter[1], ioaddr + MulticastFilter1); w840private.csr6 &= ~0x00F8; w840private.csr6 |= rx_mode; writel(w840private.csr6, ioaddr + NetworkConfig); #if defined(W89C840_DEBUG) printf("winbond-840 : Done setting RX mode.\n"); #endif } /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void init_ring(void) { int i; char * p; w840private.tx_full = 0; w840private.tx_q_bytes = w840private.cur_rx = w840private.cur_tx = 0; w840private.dirty_rx = w840private.dirty_tx = 0; w840private.rx_buf_sz = PKT_BUF_SZ; w840private.rx_head_desc = &w840private.rx_ring[0]; /* Initial all Rx descriptors. Fill in the Rx buffers. */ p = &w89c840_buf.rx_packet[0]; for (i = 0; i < RX_RING_SIZE; i++) { w840private.rx_ring[i].length = w840private.rx_buf_sz; w840private.rx_ring[i].status = 0; w840private.rx_ring[i].next_desc = virt_to_le32desc(&w840private.rx_ring[i+1]); w840private.rx_ring[i].buffer1 = virt_to_le32desc(p + (PKT_BUF_SZ * i)); w840private.rx_ring[i].status = DescOwn | DescIntr; } /* Mark the last entry as wrapping the ring. */ w840private.rx_ring[i-1].length |= DescEndRing; w840private.rx_ring[i-1].next_desc = virt_to_le32desc(&w840private.rx_ring[0]); w840private.dirty_rx = (unsigned int)(i - RX_RING_SIZE); for (i = 0; i < TX_RING_SIZE; i++) { w840private.tx_ring[i].status = 0; } return; } DRIVER ( "W89C840F", nic_driver, pci_driver, w89c840_driver, w89c840_probe, w89c840_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/sis900.c0000664000000000000000000010600012524662415020377 0ustar /* -*- Mode:C; c-basic-offset:4; -*- */ /* sis900.c: An SiS 900/7016 PCI Fast Ethernet driver for Etherboot Copyright (C) 2001 Entity Cyber, Inc. Revision: 1.0 March 1, 2001 Author: Marty Connor (mdc@etherboot.org) Adapted from a Linux driver which was written by Donald Becker and modified by Ollie Lho and Chin-Shan Li of SiS Corporation. Rewritten for Etherboot by Marty Connor. This software may be used and distributed according to the terms of the GNU Public License (GPL), incorporated herein by reference. References: SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support, preliminary Rev. 1.0 Jan. 14, 1998 SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support, preliminary Rev. 1.0 Nov. 10, 1998 SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution, preliminary Rev. 1.0 Jan. 18, 1998 http://www.sis.com.tw/support/databook.htm */ FILE_LICENCE ( GPL_ANY ); /* Revision History */ /* 07 Dec 2003 timlegge - Enabled Multicast Support 06 Dec 2003 timlegge - Fixed relocation issue in 5.2 04 Jan 2002 Chien-Yu Chen, Doug Ambrisko, Marty Connor Patch to Etherboot 5.0.5 Added support for the SiS 630ET plus various bug fixes from linux kernel source 2.4.17. 01 March 2001 mdc 1.0 Initial Release. Tested with PCI based sis900 card and ThinkNIC computer. 20 March 2001 P.Koegel added support for sis630e and PHY ICS1893 and RTL8201 Testet with SIS730S chipset + ICS1893 */ /* Includes */ #include "etherboot.h" #include #include "nic.h" #include "sis900.h" /* Globals */ static struct nic_operations sis900_operations; static int sis900_debug = 0; static unsigned short vendor, dev_id; static unsigned long ioaddr; static u8 pci_revision; static unsigned int cur_phy; static unsigned int cur_rx; struct { BufferDesc txd; BufferDesc rxd[NUM_RX_DESC]; unsigned char txb[TX_BUF_SIZE]; unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]; } sis900_bufs __shared; #define txd sis900_bufs.txd #define rxd sis900_bufs.rxd #define txb sis900_bufs.txb #define rxb sis900_bufs.rxb #if 0 static struct mac_chip_info { const char *name; u16 vendor_id, device_id, flags; int io_size; } mac_chip_table[] = { { "SiS 900 PCI Fast Ethernet", PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900, PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE}, { "SiS 7016 PCI Fast Ethernet",PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016, PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE}, {0,0,0,0,0} /* 0 terminated list. */ }; #endif static void sis900_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex); static void amd79c901_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex); static void ics1893_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex); static void rtl8201_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex); static void vt6103_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex); static struct mii_chip_info { const char * name; u16 phy_id0; u16 phy_id1; void (*read_mode) (struct nic *nic, int phy_addr, int *speed, int *duplex); } mii_chip_table[] = { {"SiS 900 Internal MII PHY", 0x001d, 0x8000, sis900_read_mode}, {"SiS 7014 Physical Layer Solution", 0x0016, 0xf830,sis900_read_mode}, {"SiS 900 on Foxconn 661 7MI", 0x0143, 0xBC70, sis900_read_mode}, {"AMD 79C901 10BASE-T PHY", 0x0000, 0x6B70, amd79c901_read_mode}, {"AMD 79C901 HomePNA PHY", 0x0000, 0x6B90, amd79c901_read_mode}, {"ICS 1893 Integrated PHYceiver" , 0x0015, 0xf440,ics1893_read_mode}, // {"NS 83851 PHY",0x2000, 0x5C20, MIX }, {"RTL 8201 10/100Mbps Phyceiver" , 0x0000, 0x8200,rtl8201_read_mode}, {"VIA 6103 10/100Mbps Phyceiver", 0x0101, 0x8f20,vt6103_read_mode}, {0,0,0,0} }; static struct mii_phy { struct mii_phy * next; struct mii_chip_info * chip_info; int phy_addr; u16 status; } mii; #if 0 // PCI to ISA bridge for SIS640E access static struct pci_device_id pci_isa_bridge_list[] = { { .vendor = 0x1039, .device = 0x0008, .name = "SIS 85C503/5513 PCI to ISA bridge"}, }; PCI_DRIVER( sis_bridge_pci_driver, pci_isa_bridge_list, PCI_NO_CLASS ); static struct device_driver sis_bridge_driver = { .name = "SIS ISA bridge", .bus_driver = &pci_driver, .bus_driver_info = ( struct bus_driver_info * ) &sis_bridge_pci_driver, }; #endif /* Function Prototypes */ static int sis900_probe(struct nic *nic,struct pci_device *pci); static u16 sis900_read_eeprom(int location); static void sis900_mdio_reset(long mdio_addr); static void sis900_mdio_idle(long mdio_addr); static u16 sis900_mdio_read(int phy_id, int location); #if 0 static void sis900_mdio_write(int phy_id, int location, int val); #endif static void sis900_init(struct nic *nic); static void sis900_reset(struct nic *nic); static void sis900_init_rxfilter(struct nic *nic); static void sis900_init_txd(struct nic *nic); static void sis900_init_rxd(struct nic *nic); static void sis900_set_rx_mode(struct nic *nic); static void sis900_check_mode(struct nic *nic); static void sis900_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p); static int sis900_poll(struct nic *nic, int retrieve); static void sis900_disable(struct nic *nic); static void sis900_irq(struct nic *nic, irq_action_t action); /** * sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model * @pci_dev: the sis900 pci device * @net_dev: the net device to get address for * * Older SiS900 and friends, use EEPROM to store MAC address. * MAC address is read from read_eeprom() into @net_dev->dev_addr. */ static int sis900_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic) { u16 signature; int i; /* check to see if we have sane EEPROM */ signature = (u16) sis900_read_eeprom( EEPROMSignature); if (signature == 0xffff || signature == 0x0000) { printf ("sis900_probe: Error EERPOM read %hX\n", signature); return 0; } /* get MAC address from EEPROM */ for (i = 0; i < 3; i++) ((u16 *)(nic->node_addr))[i] = sis900_read_eeprom(i+EEPROMMACAddr); return 1; } /** * sis96x_get_mac_addr: - Get MAC address for SiS962 or SiS963 model * @pci_dev: the sis900 pci device * @net_dev: the net device to get address for * * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM * is shared by * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access * by LAN, otherwise is not. After MAC address is read from EEPROM, send * EEDONE signal to refuse EEPROM access by LAN. * The EEPROM map of SiS962 or SiS963 is different to SiS900. * The signature field in SiS962 or SiS963 spec is meaningless. * MAC address is read into @net_dev->dev_addr. */ static int sis96x_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic) { /* long ioaddr = net_dev->base_addr; */ long ee_addr = ioaddr + mear; u32 waittime = 0; int i; printf("Alternate function\n"); outl(EEREQ, ee_addr); while(waittime < 2000) { if(inl(ee_addr) & EEGNT) { /* get MAC address from EEPROM */ for (i = 0; i < 3; i++) ((u16 *)(nic->node_addr))[i] = sis900_read_eeprom(i+EEPROMMACAddr); outl(EEDONE, ee_addr); return 1; } else { udelay(1); waittime ++; } } outl(EEDONE, ee_addr); return 0; } /** * sis630e_get_mac_addr: - Get MAC address for SiS630E model * @pci_dev: the sis900 pci device * @net_dev: the net device to get address for * * SiS630E model, use APC CMOS RAM to store MAC address. * APC CMOS RAM is accessed through ISA bridge. * MAC address is read into @net_dev->dev_addr. */ static int sis630e_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic) { #if 0 u8 reg; int i; struct bus_loc bus_loc; union { struct bus_dev bus_dev; struct pci_device isa_bridge; } u; /* find PCI to ISA bridge */ memset(&bus_loc, 0, sizeof(bus_loc)); if ( ! find_by_driver ( &bus_loc, &u.bus_dev, &sis_bridge_driver, 0 ) ) return 0; pci_read_config_byte(&u.isa_bridge, 0x48, ®); pci_write_config_byte(&u.isa_bridge, 0x48, reg | 0x40); for (i = 0; i < ETH_ALEN; i++) { outb(0x09 + i, 0x70); ((u8 *)(nic->node_addr))[i] = inb(0x71); } pci_write_config_byte(&u.isa_bridge, 0x48, reg & ~0x40); return 1; #endif /* Does not work with current bus/device model */ memset ( nic->node_addr, 0, sizeof ( nic->node_addr ) ); return 0; } /** * sis630e_get_mac_addr: - Get MAC address for SiS630E model * @pci_dev: the sis900 pci device * @net_dev: the net device to get address for * * SiS630E model, use APC CMOS RAM to store MAC address. * APC CMOS RAM is accessed through ISA bridge. * MAC address is read into @net_dev->dev_addr. */ static int sis635_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic) { u32 rfcrSave; u32 i; rfcrSave = inl(rfcr + ioaddr); outl(rfcrSave | RELOAD, ioaddr + cr); outl(0, ioaddr + cr); /* disable packet filtering before setting filter */ outl(rfcrSave & ~RFEN, rfcr + ioaddr); /* load MAC addr to filter data register */ for (i = 0 ; i < 3 ; i++) { outl((i << RFADDR_shift), ioaddr + rfcr); *( ((u16 *)nic->node_addr) + i) = inw(ioaddr + rfdr); } /* enable packet filitering */ outl(rfcrSave | RFEN, rfcr + ioaddr); return 1; } /* * Function: sis900_probe * * Description: initializes initializes the NIC, retrieves the * MAC address of the card, and sets up some globals required by * other routines. * * Side effects: * leaves the ioaddress of the sis900 chip in the variable ioaddr. * leaves the sis900 initialized, and ready to recieve packets. * * Returns: struct nic *: pointer to NIC data structure */ static int sis900_probe ( struct nic *nic, struct pci_device *pci ) { int i; int found=0; int phy_addr; u8 revision; int ret; if (pci->ioaddr == 0) return 0; nic->irqno = 0; nic->ioaddr = pci->ioaddr; ioaddr = pci->ioaddr; vendor = pci->vendor; dev_id = pci->device; /* wakeup chip */ pci_write_config_dword(pci, 0x40, 0x00000000); adjust_pci_device(pci); /* get MAC address */ ret = 0; pci_read_config_byte(pci, PCI_REVISION, &revision); /* save for use later in sis900_reset() */ pci_revision = revision; if (revision == SIS630E_900_REV) ret = sis630e_get_mac_addr(pci, nic); else if ((revision > 0x81) && (revision <= 0x90)) ret = sis635_get_mac_addr(pci, nic); else if (revision == SIS96x_900_REV) ret = sis96x_get_mac_addr(pci, nic); else ret = sis900_get_mac_addr(pci, nic); if (ret == 0) { printf ("sis900_probe: Error MAC address not found\n"); return 0; } /* 630ET : set the mii access mode as software-mode */ if (revision == SIS630ET_900_REV) outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr); DBG( "sis900_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id ); /* probe for mii transceiver */ /* search for total of 32 possible mii phy addresses */ found = 0; for (phy_addr = 0; phy_addr < 32; phy_addr++) { u16 mii_status; u16 phy_id0, phy_id1; mii_status = sis900_mdio_read(phy_addr, MII_STATUS); if (mii_status == 0xffff || mii_status == 0x0000) /* the mii is not accessable, try next one */ continue; phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0); phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1); /* search our mii table for the current mii */ for (i = 0; mii_chip_table[i].phy_id1; i++) { if ((phy_id0 == mii_chip_table[i].phy_id0) && ((phy_id1 & 0xFFF0) == mii_chip_table[i].phy_id1)){ printf("sis900_probe: %s transceiver found at address %d.\n", mii_chip_table[i].name, phy_addr); mii.chip_info = &mii_chip_table[i]; mii.phy_addr = phy_addr; mii.status = sis900_mdio_read(phy_addr, MII_STATUS); mii.next = NULL; found=1; break; } } } if (found == 0) { printf("sis900_probe: No MII transceivers found!\n"); return 0; } /* Arbitrarily select the last PHY found as current PHY */ cur_phy = mii.phy_addr; printf("sis900_probe: Using %s as default\n", mii.chip_info->name); /* initialize device */ sis900_init(nic); nic->nic_op = &sis900_operations; return 1; } /* * EEPROM Routines: These functions read and write to EEPROM for * retrieving the MAC address and other configuration information about * the card. */ /* Delay between EEPROM clock transitions. */ #define eeprom_delay() inl(ee_addr) /* Function: sis900_read_eeprom * * Description: reads and returns a given location from EEPROM * * Arguments: int location: requested EEPROM location * * Returns: u16: contents of requested EEPROM location * */ /* Read Serial EEPROM through EEPROM Access Register, Note that location is in word (16 bits) unit */ static u16 sis900_read_eeprom(int location) { int i; u16 retval = 0; long ee_addr = ioaddr + mear; u32 read_cmd = location | EEread; outl(0, ee_addr); eeprom_delay(); outl(EECS, ee_addr); eeprom_delay(); /* Shift the read command (9) bits out. */ for (i = 8; i >= 0; i--) { u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS; outl(dataval, ee_addr); eeprom_delay(); outl(dataval | EECLK, ee_addr); eeprom_delay(); } outl(EECS, ee_addr); eeprom_delay(); /* read the 16-bits data in */ for (i = 16; i > 0; i--) { outl(EECS, ee_addr); eeprom_delay(); outl(EECS | EECLK, ee_addr); eeprom_delay(); retval = (retval << 1) | ((inl(ee_addr) & EEDO) ? 1 : 0); eeprom_delay(); } /* Terminate the EEPROM access. */ outl(0, ee_addr); eeprom_delay(); // outl(EECLK, ee_addr); return (retval); } #define sis900_mdio_delay() inl(mdio_addr) /* Read and write the MII management registers using software-generated serial MDIO protocol. Note that the command bits and data bits are send out seperately */ static void sis900_mdio_idle(long mdio_addr) { outl(MDIO | MDDIR, mdio_addr); sis900_mdio_delay(); outl(MDIO | MDDIR | MDC, mdio_addr); } /* Syncronize the MII management interface by shifting 32 one bits out. */ static void sis900_mdio_reset(long mdio_addr) { int i; for (i = 31; i >= 0; i--) { outl(MDDIR | MDIO, mdio_addr); sis900_mdio_delay(); outl(MDDIR | MDIO | MDC, mdio_addr); sis900_mdio_delay(); } return; } static u16 sis900_mdio_read(int phy_id, int location) { long mdio_addr = ioaddr + mear; int mii_cmd = MIIread|(phy_id<= 0; i--) { int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR; outl(dataval, mdio_addr); sis900_mdio_delay(); outl(dataval | MDC, mdio_addr); sis900_mdio_delay(); } /* Read the 16 data bits. */ for (i = 16; i > 0; i--) { outl(0, mdio_addr); sis900_mdio_delay(); retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0); outl(MDC, mdio_addr); sis900_mdio_delay(); } outl(0x00, mdio_addr); return retval; } #if 0 static void sis900_mdio_write(int phy_id, int location, int value) { long mdio_addr = ioaddr + mear; int mii_cmd = MIIwrite|(phy_id<= 0; i--) { int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR; outb(dataval, mdio_addr); sis900_mdio_delay(); outb(dataval | MDC, mdio_addr); sis900_mdio_delay(); } sis900_mdio_delay(); /* Shift the value bits out. */ for (i = 15; i >= 0; i--) { int dataval = (value & (1 << i)) ? MDDIR | MDIO : MDDIR; outl(dataval, mdio_addr); sis900_mdio_delay(); outl(dataval | MDC, mdio_addr); sis900_mdio_delay(); } sis900_mdio_delay(); /* Clear out extra bits. */ for (i = 2; i > 0; i--) { outb(0, mdio_addr); sis900_mdio_delay(); outb(MDC, mdio_addr); sis900_mdio_delay(); } outl(0x00, mdio_addr); return; } #endif /* Function: sis900_init * * Description: resets the ethernet controller chip and various * data structures required for sending and receiving packets. * * Arguments: struct nic *nic: NIC data structure * * returns: void. */ static void sis900_init(struct nic *nic) { /* Soft reset the chip. */ sis900_reset(nic); sis900_init_rxfilter(nic); sis900_init_txd(nic); sis900_init_rxd(nic); sis900_set_rx_mode(nic); sis900_check_mode(nic); outl(RxENA| inl(ioaddr + cr), ioaddr + cr); } /* * Function: sis900_reset * * Description: disables interrupts and soft resets the controller chip * * Arguments: struct nic *nic: NIC data structure * * Returns: void. */ static void sis900_reset(struct nic *nic __unused) { int i = 0; u32 status = TxRCMP | RxRCMP; outl(0, ioaddr + ier); outl(0, ioaddr + imr); outl(0, ioaddr + rfcr); outl(RxRESET | TxRESET | RESET | inl(ioaddr + cr), ioaddr + cr); /* Check that the chip has finished the reset. */ while (status && (i++ < 1000)) { status ^= (inl(isr + ioaddr) & status); } if( (pci_revision >= SIS635A_900_REV) || (pci_revision == SIS900B_900_REV) ) outl(PESEL | RND_CNT, ioaddr + cfg); else outl(PESEL, ioaddr + cfg); } /* Function: sis_init_rxfilter * * Description: sets receive filter address to our MAC address * * Arguments: struct nic *nic: NIC data structure * * returns: void. */ static void sis900_init_rxfilter(struct nic *nic) { u32 rfcrSave; int i; rfcrSave = inl(rfcr + ioaddr); /* disable packet filtering before setting filter */ outl(rfcrSave & ~RFEN, rfcr + ioaddr); /* load MAC addr to filter data register */ for (i = 0 ; i < 3 ; i++) { u32 w; w = (u32) *((u16 *)(nic->node_addr)+i); outl((i << RFADDR_shift), ioaddr + rfcr); outl(w, ioaddr + rfdr); if (sis900_debug > 0) printf("sis900_init_rxfilter: Receive Filter Addrss[%d]=%X\n", i, inl(ioaddr + rfdr)); } /* enable packet filitering */ outl(rfcrSave | RFEN, rfcr + ioaddr); } /* * Function: sis_init_txd * * Description: initializes the Tx descriptor * * Arguments: struct nic *nic: NIC data structure * * returns: void. */ static void sis900_init_txd(struct nic *nic __unused) { txd.link = (u32) 0; txd.cmdsts = (u32) 0; txd.bufptr = virt_to_bus(&txb[0]); /* load Transmit Descriptor Register */ outl(virt_to_bus(&txd), ioaddr + txdp); if (sis900_debug > 0) printf("sis900_init_txd: TX descriptor register loaded with: %X\n", inl(ioaddr + txdp)); } /* Function: sis_init_rxd * * Description: initializes the Rx descriptor ring * * Arguments: struct nic *nic: NIC data structure * * Returns: void. */ static void sis900_init_rxd(struct nic *nic __unused) { int i; cur_rx = 0; /* init RX descriptor */ for (i = 0; i < NUM_RX_DESC; i++) { rxd[i].link = virt_to_bus((i+1 < NUM_RX_DESC) ? &rxd[i+1] : &rxd[0]); rxd[i].cmdsts = (u32) RX_BUF_SIZE; rxd[i].bufptr = virt_to_bus(&rxb[i*RX_BUF_SIZE]); if (sis900_debug > 0) printf("sis900_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n", i, &rxd[i], (unsigned int) rxd[i].link, (unsigned int) rxd[i].cmdsts, (unsigned int) rxd[i].bufptr); } /* load Receive Descriptor Register */ outl(virt_to_bus(&rxd[0]), ioaddr + rxdp); if (sis900_debug > 0) printf("sis900_init_rxd: RX descriptor register loaded with: %X\n", inl(ioaddr + rxdp)); } /* Function: sis_init_rxd * * Description: * sets the receive mode to accept all broadcast packets and packets * with our MAC address, and reject all multicast packets. * * Arguments: struct nic *nic: NIC data structure * * Returns: void. */ static void sis900_set_rx_mode(struct nic *nic __unused) { int i, table_entries; u32 rx_mode; u16 mc_filter[16] = {0}; /* 256/128 bits multicast hash table */ if((pci_revision == SIS635A_900_REV) || (pci_revision == SIS900B_900_REV)) table_entries = 16; else table_entries = 8; /* accept all multicast packet */ rx_mode = RFAAB | RFAAM; for (i = 0; i < table_entries; i++) mc_filter[i] = 0xffff; /* update Multicast Hash Table in Receive Filter */ for (i = 0; i < table_entries; i++) { /* why plus 0x04? That makes the correct value for hash table. */ outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr); outl(mc_filter[i], ioaddr + rfdr); } /* Accept Broadcast and multicast packets, destination addresses that match our MAC address */ outl(RFEN | rx_mode, ioaddr + rfcr); return; } /* Function: sis900_check_mode * * Description: checks the state of transmit and receive * parameters on the NIC, and updates NIC registers to match * * Arguments: struct nic *nic: NIC data structure * * Returns: void. */ static void sis900_check_mode(struct nic *nic) { int speed, duplex; u32 tx_flags = 0, rx_flags = 0; mii.chip_info->read_mode(nic, cur_phy, &speed, &duplex); if( inl(ioaddr + cfg) & EDB_MASTER_EN ) { tx_flags = TxATP | (DMA_BURST_64 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift); rx_flags = DMA_BURST_64 << RxMXDMA_shift; } else { tx_flags = TxATP | (DMA_BURST_512 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift); rx_flags = DMA_BURST_512 << RxMXDMA_shift; } if (speed == HW_SPEED_HOME || speed == HW_SPEED_10_MBPS) { rx_flags |= (RxDRNT_10 << RxDRNT_shift); tx_flags |= (TxDRNT_10 << TxDRNT_shift); } else { rx_flags |= (RxDRNT_100 << RxDRNT_shift); tx_flags |= (TxDRNT_100 << TxDRNT_shift); } if (duplex == FDX_CAPABLE_FULL_SELECTED) { tx_flags |= (TxCSI | TxHBI); rx_flags |= RxATX; } outl (tx_flags, ioaddr + txcfg); outl (rx_flags, ioaddr + rxcfg); } /* Function: sis900_read_mode * * Description: retrieves and displays speed and duplex * parameters from the NIC * * Arguments: struct nic *nic: NIC data structure * * Returns: void. */ static void sis900_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex) { int i = 0; u32 status; u16 phy_id0, phy_id1; /* STSOUT register is Latched on Transition, read operation updates it */ do { status = sis900_mdio_read(phy_addr, MII_STSOUT); } while (i++ < 2); *speed = HW_SPEED_10_MBPS; *duplex = FDX_CAPABLE_HALF_SELECTED; if (status & (MII_NWAY_TX | MII_NWAY_TX_FDX)) *speed = HW_SPEED_100_MBPS; if (status & ( MII_NWAY_TX_FDX | MII_NWAY_T_FDX)) *duplex = FDX_CAPABLE_FULL_SELECTED; /* Workaround for Realtek RTL8201 PHY issue */ phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0); phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1); if((phy_id0 == 0x0000) && ((phy_id1 & 0xFFF0) == 0x8200)){ if(sis900_mdio_read(phy_addr, MII_CONTROL) & MII_CNTL_FDX) *duplex = FDX_CAPABLE_FULL_SELECTED; if(sis900_mdio_read(phy_addr, 0x0019) & 0x01) *speed = HW_SPEED_100_MBPS; } if (status & MII_STSOUT_LINK_FAIL) printf("sis900_read_mode: Media Link Off\n"); else printf("sis900_read_mode: Media Link On %s %s-duplex \n", *speed == HW_SPEED_100_MBPS ? "100mbps" : "10mbps", *duplex == FDX_CAPABLE_FULL_SELECTED ? "full" : "half"); } /* Function: amd79c901_read_mode * * Description: retrieves and displays speed and duplex * parameters from the NIC * * Arguments: struct nic *nic: NIC data structure * * Returns: void. */ static void amd79c901_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex) { int i; u16 status; for (i = 0; i < 2; i++) status = sis900_mdio_read(phy_addr, MII_STATUS); if (status & MII_STAT_CAN_AUTO) { /* 10BASE-T PHY */ for (i = 0; i < 2; i++) status = sis900_mdio_read(phy_addr, MII_STATUS_SUMMARY); if (status & MII_STSSUM_SPD) *speed = HW_SPEED_100_MBPS; else *speed = HW_SPEED_10_MBPS; if (status & MII_STSSUM_DPLX) *duplex = FDX_CAPABLE_FULL_SELECTED; else *duplex = FDX_CAPABLE_HALF_SELECTED; if (status & MII_STSSUM_LINK) printf("amd79c901_read_mode: Media Link On %s %s-duplex \n", *speed == HW_SPEED_100_MBPS ? "100mbps" : "10mbps", *duplex == FDX_CAPABLE_FULL_SELECTED ? "full" : "half"); else printf("amd79c901_read_mode: Media Link Off\n"); } else { /* HomePNA */ *speed = HW_SPEED_HOME; *duplex = FDX_CAPABLE_HALF_SELECTED; if (status & MII_STAT_LINK) printf("amd79c901_read_mode:Media Link On 1mbps half-duplex \n"); else printf("amd79c901_read_mode: Media Link Off\n"); } } /** * ics1893_read_mode: - read media mode for ICS1893 PHY * @net_dev: the net device to read mode for * @phy_addr: mii phy address * @speed: the transmit speed to be determined * @duplex: the duplex mode to be determined * * ICS1893 PHY use Quick Poll Detailed Status register * to determine the speed and duplex mode for sis900 */ static void ics1893_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex) { int i = 0; u32 status; /* MII_QPDSTS is Latched, read twice in succession will reflect the current state */ for (i = 0; i < 2; i++) status = sis900_mdio_read(phy_addr, MII_QPDSTS); if (status & MII_STSICS_SPD) *speed = HW_SPEED_100_MBPS; else *speed = HW_SPEED_10_MBPS; if (status & MII_STSICS_DPLX) *duplex = FDX_CAPABLE_FULL_SELECTED; else *duplex = FDX_CAPABLE_HALF_SELECTED; if (status & MII_STSICS_LINKSTS) printf("ics1893_read_mode: Media Link On %s %s-duplex \n", *speed == HW_SPEED_100_MBPS ? "100mbps" : "10mbps", *duplex == FDX_CAPABLE_FULL_SELECTED ? "full" : "half"); else printf("ics1893_read_mode: Media Link Off\n"); } /** * rtl8201_read_mode: - read media mode for rtl8201 phy * @nic: the net device to read mode for * @phy_addr: mii phy address * @speed: the transmit speed to be determined * @duplex: the duplex mode to be determined * * read MII_STATUS register from rtl8201 phy * to determine the speed and duplex mode for sis900 */ static void rtl8201_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex) { u32 status; status = sis900_mdio_read(phy_addr, MII_STATUS); if (status & MII_STAT_CAN_TX_FDX) { *speed = HW_SPEED_100_MBPS; *duplex = FDX_CAPABLE_FULL_SELECTED; } else if (status & MII_STAT_CAN_TX) { *speed = HW_SPEED_100_MBPS; *duplex = FDX_CAPABLE_HALF_SELECTED; } else if (status & MII_STAT_CAN_T_FDX) { *speed = HW_SPEED_10_MBPS; *duplex = FDX_CAPABLE_FULL_SELECTED; } else if (status & MII_STAT_CAN_T) { *speed = HW_SPEED_10_MBPS; *duplex = FDX_CAPABLE_HALF_SELECTED; } if (status & MII_STAT_LINK) printf("rtl8201_read_mode: Media Link On %s %s-duplex \n", *speed == HW_SPEED_100_MBPS ? "100mbps" : "10mbps", *duplex == FDX_CAPABLE_FULL_SELECTED ? "full" : "half"); else printf("rtl8201_read_config_mode: Media Link Off\n"); } /** * vt6103_read_mode: - read media mode for vt6103 phy * @nic: the net device to read mode for * @phy_addr: mii phy address * @speed: the transmit speed to be determined * @duplex: the duplex mode to be determined * * read MII_STATUS register from rtl8201 phy * to determine the speed and duplex mode for sis900 */ static void vt6103_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex) { u32 status; status = sis900_mdio_read(phy_addr, MII_STATUS); if (status & MII_STAT_CAN_TX_FDX) { *speed = HW_SPEED_100_MBPS; *duplex = FDX_CAPABLE_FULL_SELECTED; } else if (status & MII_STAT_CAN_TX) { *speed = HW_SPEED_100_MBPS; *duplex = FDX_CAPABLE_HALF_SELECTED; } else if (status & MII_STAT_CAN_T_FDX) { *speed = HW_SPEED_10_MBPS; *duplex = FDX_CAPABLE_FULL_SELECTED; } else if (status & MII_STAT_CAN_T) { *speed = HW_SPEED_10_MBPS; *duplex = FDX_CAPABLE_HALF_SELECTED; } if (status & MII_STAT_LINK) printf("vt6103_read_mode: Media Link On %s %s-duplex \n", *speed == HW_SPEED_100_MBPS ? "100mbps" : "10mbps", *duplex == FDX_CAPABLE_FULL_SELECTED ? "full" : "half"); else printf("vt6103_read_config_mode: Media Link Off\n"); } /* Function: sis900_transmit * * Description: transmits a packet and waits for completion or timeout. * * Arguments: char d[6]: destination ethernet address. * unsigned short t: ethernet protocol type. * unsigned short s: size of the data-part of the packet. * char *p: the data for the packet. * * Returns: void. */ static void sis900_transmit(struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) /* Packet */ { u32 to, nstype; volatile u32 tx_status; /* Stop the transmitter */ outl(TxDIS | inl(ioaddr + cr), ioaddr + cr); /* load Transmit Descriptor Register */ outl(virt_to_bus(&txd), ioaddr + txdp); if (sis900_debug > 1) printf("sis900_transmit: TX descriptor register loaded with: %X\n", inl(ioaddr + txdp)); memcpy(txb, d, ETH_ALEN); memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN); nstype = htons(t); memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2); memcpy(txb + ETH_HLEN, p, s); s += ETH_HLEN; s &= DSIZE; if (sis900_debug > 1) printf("sis900_transmit: sending %d bytes ethtype %hX\n", (int) s, t); /* pad to minimum packet size */ while (s < ETH_ZLEN) txb[s++] = '\0'; /* set the transmit buffer descriptor and enable Transmit State Machine */ txd.bufptr = virt_to_bus(&txb[0]); txd.cmdsts = (u32) OWN | s; /* restart the transmitter */ outl(TxENA | inl(ioaddr + cr), ioaddr + cr); if (sis900_debug > 1) printf("sis900_transmit: Queued Tx packet size %d.\n", (int) s); to = currticks() + TX_TIMEOUT; while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to)) /* wait */ ; if (currticks() >= to) { printf("sis900_transmit: TX Timeout! Tx status %X.\n", (unsigned int) tx_status); } if (tx_status & (ABORT | UNDERRUN | OWCOLL)) { /* packet unsuccessfully transmited */ printf("sis900_transmit: Transmit error, Tx status %X.\n", (unsigned int) tx_status); } /* Disable interrupts by clearing the interrupt mask. */ outl(0, ioaddr + imr); } /* Function: sis900_poll * * Description: checks for a received packet and returns it if found. * * Arguments: struct nic *nic: NIC data structure * * Returns: 1 if a packet was recieved. * 0 if no pacet was recieved. * * Side effects: * Returns (copies) the packet to the array nic->packet. * Returns the length of the packet in nic->packetlen. */ static int sis900_poll(struct nic *nic, int retrieve) { u32 rx_status = rxd[cur_rx].cmdsts; u32 intr_status; int retstat = 0; /* acknowledge interrupts by reading interrupt status register */ intr_status = inl(ioaddr + isr); if (sis900_debug > 2) printf("sis900_poll: cur_rx:%d, status:%X\n", cur_rx, (unsigned int) rx_status); if (!(rx_status & OWN)) return retstat; if (sis900_debug > 1) printf("sis900_poll: got a packet: cur_rx:%d, status:%X\n", cur_rx, (unsigned int) rx_status); if ( ! retrieve ) return 1; nic->packetlen = (rx_status & DSIZE) - CRC_SIZE; if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) { /* corrupted packet received */ printf("sis900_poll: Corrupted packet received, buffer status = %X\n", (unsigned int) rx_status); retstat = 0; } else { /* give packet to higher level routine */ memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen); retstat = 1; } /* return the descriptor and buffer to receive ring */ rxd[cur_rx].cmdsts = RX_BUF_SIZE; rxd[cur_rx].bufptr = virt_to_bus(&rxb[cur_rx*RX_BUF_SIZE]); if (++cur_rx == NUM_RX_DESC) cur_rx = 0; /* re-enable the potentially idle receive state machine */ outl(RxENA | inl(ioaddr + cr), ioaddr + cr); return retstat; } /* Function: sis900_disable * * Description: Turns off interrupts and stops Tx and Rx engines * * Arguments: struct nic *nic: NIC data structure * * Returns: void. */ static void sis900_disable ( struct nic *nic ) { sis900_init(nic); /* Disable interrupts by clearing the interrupt mask. */ outl(0, ioaddr + imr); outl(0, ioaddr + ier); /* Stop the chip's Tx and Rx Status Machine */ outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr); } /* Function: sis900_irq * * Description: Enable, Disable, or Force, interrupts * * Arguments: struct nic *nic: NIC data structure * irq_action_t action: Requested action * * Returns: void. */ static void sis900_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : outl(0, ioaddr + imr); break; case ENABLE : outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr); break; case FORCE : break; } } static struct nic_operations sis900_operations = { .connect = dummy_connect, .poll = sis900_poll, .transmit = sis900_transmit, .irq = sis900_irq, }; static struct pci_device_id sis900_nics[] = { PCI_ROM(0x1039, 0x0900, "sis900", "SIS900", 0), PCI_ROM(0x1039, 0x7016, "sis7016", "SIS7016", 0), }; PCI_DRIVER ( sis900_driver, sis900_nics, PCI_NO_CLASS ); DRIVER ( "SIS900", nic_driver, pci_driver, sis900_driver, sis900_probe, sis900_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/ne2k_isa.c0000664000000000000000000003063512524662415021055 0ustar /************************************************************************** ETHERBOOT - BOOTP/TFTP Bootstrap Program Author: Martin Renters Date: May/94 This code is based heavily on David Greenman's if_ed.c driver Copyright (C) 1993-1994, David Greenman, Martin Renters. This software may be used, modified, copied, distributed, and sold, in both source and binary form provided that the above copyright and these terms are retained. Under no circumstances are the authors responsible for the proper functioning of this software, nor do the authors assume any responsibility for damages incurred with its use. Multicast support added by Timothy Legge (timlegge@users.sourceforge.net) 09/28/2003 Relocation support added by Ken Yap (ken_yap@users.sourceforge.net) 28/12/02 Card Detect support adapted from the eCos driver (Christian Plessl ) Extracted from ns8390.c and adapted by Pantelis Koukousoulas **************************************************************************/ FILE_LICENCE ( BSD2 ); #include "ns8390.h" #include "etherboot.h" #include "nic.h" #include #include #include #define ASIC_PIO NE_DATA static unsigned char eth_vendor, eth_flags; static unsigned short eth_nic_base, eth_asic_base; static unsigned char eth_memsize, eth_rx_start, eth_tx_start; static Address eth_bmem, eth_rmem; static unsigned char eth_drain_receiver; static struct nic_operations ne_operations; static void ne_reset(struct nic *nic, struct isa_device *isa); static isa_probe_addr_t ne_probe_addrs[] = { 0x300, 0x280, 0x320, 0x340, 0x380, 0x220, }; /************************************************************************** ETH_PIO_READ - Read a frame via Programmed I/O **************************************************************************/ static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt) { outb(D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); outb(cnt, eth_nic_base + D8390_P0_RBCR0); outb(cnt >> 8, eth_nic_base + D8390_P0_RBCR1); outb(src, eth_nic_base + D8390_P0_RSAR0); outb(src >> 8, eth_nic_base + D8390_P0_RSAR1); outb(D8390_COMMAND_RD0 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); if (eth_flags & FLAG_16BIT) cnt = (cnt + 1) >> 1; while (cnt--) { if (eth_flags & FLAG_16BIT) { *((unsigned short *) dst) = inw(eth_asic_base + ASIC_PIO); dst += 2; } else *(dst++) = inb(eth_asic_base + ASIC_PIO); } } /************************************************************************** ETH_PIO_WRITE - Write a frame via Programmed I/O **************************************************************************/ static void eth_pio_write(const unsigned char *src, unsigned int dst, unsigned int cnt) { outb(D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); outb(D8390_ISR_RDC, eth_nic_base + D8390_P0_ISR); outb(cnt, eth_nic_base + D8390_P0_RBCR0); outb(cnt >> 8, eth_nic_base + D8390_P0_RBCR1); outb(dst, eth_nic_base + D8390_P0_RSAR0); outb(dst >> 8, eth_nic_base + D8390_P0_RSAR1); outb(D8390_COMMAND_RD1 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); if (eth_flags & FLAG_16BIT) cnt = (cnt + 1) >> 1; while (cnt--) { if (eth_flags & FLAG_16BIT) { outw(*((unsigned short *) src), eth_asic_base + ASIC_PIO); src += 2; } else outb(*(src++), eth_asic_base + ASIC_PIO); } } /************************************************************************** enable_multicast - Enable Multicast **************************************************************************/ static void enable_multicast(unsigned short eth_nic_base) { unsigned char mcfilter[8]; int i; memset(mcfilter, 0xFF, 8); outb(4, eth_nic_base + D8390_P0_RCR); outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS1, eth_nic_base + D8390_P0_COMMAND); for (i = 0; i < 8; i++) { outb(mcfilter[i], eth_nic_base + 8 + i); if (inb(eth_nic_base + 8 + i) != mcfilter[i]) DBG("Error SMC 83C690 Multicast filter read/write mishap %d\n", i); } outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS0, eth_nic_base + D8390_P0_COMMAND); outb(4 | 0x08, eth_nic_base + D8390_P0_RCR); } /************************************************************************** NE_PROBE1 - Look for an adapter on the ISA bus **************************************************************************/ static int ne_probe1(isa_probe_addr_t ioaddr) { //From the eCos driver unsigned int regd; unsigned int state; state = inb(ioaddr); outb(ioaddr, D8390_COMMAND_RD2 | D8390_COMMAND_PS1 | D8390_COMMAND_STP); regd = inb(ioaddr + D8390_P0_TCR); if (inb(ioaddr + D8390_P0_TCR)) { outb(ioaddr, state); outb(ioaddr + 0x0d, regd); return 0; } return 1; } /************************************************************************** NE_PROBE - Initialize an adapter ??? **************************************************************************/ static int ne_probe(struct nic *nic, struct isa_device *isa) { int i; unsigned char c; unsigned char romdata[16]; unsigned char testbuf[32]; eth_vendor = VENDOR_NONE; eth_drain_receiver = 0; nic->irqno = 0; nic->ioaddr = isa->ioaddr; eth_nic_base = isa->ioaddr; /****************************************************************** Search for NE1000/2000 if no WD/SMC or 3com cards ******************************************************************/ if (eth_vendor == VENDOR_NONE) { static unsigned char test[] = "NE*000 memory"; eth_bmem = 0; /* No shared memory */ eth_flags = FLAG_PIO; eth_asic_base = eth_nic_base + NE_ASIC_OFFSET; eth_memsize = MEM_16384; eth_tx_start = 32; eth_rx_start = 32 + D8390_TXBUF_SIZE; c = inb(eth_asic_base + NE_RESET); outb(c, eth_asic_base + NE_RESET); (void) inb(0x84); outb(D8390_COMMAND_STP | D8390_COMMAND_RD2, eth_nic_base + D8390_P0_COMMAND); outb(D8390_RCR_MON, eth_nic_base + D8390_P0_RCR); outb(D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR); outb(MEM_8192, eth_nic_base + D8390_P0_PSTART); outb(MEM_16384, eth_nic_base + D8390_P0_PSTOP); eth_pio_write((unsigned char *) test, 8192, sizeof(test)); eth_pio_read(8192, testbuf, sizeof(test)); if (!memcmp(test, testbuf, sizeof(test))) goto out; eth_flags |= FLAG_16BIT; eth_memsize = MEM_32768; eth_tx_start = 64; eth_rx_start = 64 + D8390_TXBUF_SIZE; outb(D8390_DCR_WTS | D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR); outb(MEM_16384, eth_nic_base + D8390_P0_PSTART); outb(MEM_32768, eth_nic_base + D8390_P0_PSTOP); eth_pio_write((unsigned char *) test, 16384, sizeof(test)); eth_pio_read(16384, testbuf, sizeof(test)); if (!memcmp(testbuf, test, sizeof(test))) goto out; out: if (eth_nic_base == 0) return (0); if (eth_nic_base > ISA_MAX_ADDR) /* PCI probably */ eth_flags |= FLAG_16BIT; eth_vendor = VENDOR_NOVELL; eth_pio_read(0, romdata, sizeof(romdata)); for (i = 0; i < ETH_ALEN; i++) { nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)]; } nic->ioaddr = eth_nic_base; DBG("\nNE%c000 base %4.4x, MAC Addr %s\n", (eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base, eth_ntoa( nic->node_addr)); } if (eth_vendor == VENDOR_NONE) return (0); if (eth_vendor != VENDOR_3COM) eth_rmem = eth_bmem; ne_reset(nic, isa); nic->nic_op = &ne_operations; return 1; } /************************************************************************** NE_DISABLE - Turn off adapter **************************************************************************/ static void ne_disable(struct nic *nic, struct isa_device *isa) { ne_reset(nic, isa); } /************************************************************************** NE_RESET - Reset adapter **************************************************************************/ static void ne_reset(struct nic *nic, struct isa_device *isa __unused) { int i; eth_drain_receiver = 0; outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); if (eth_flags & FLAG_16BIT) outb(0x49, eth_nic_base+D8390_P0_DCR); else outb(0x48, eth_nic_base+D8390_P0_DCR); outb(0, eth_nic_base+D8390_P0_RBCR0); outb(0, eth_nic_base+D8390_P0_RBCR1); outb(0x20, eth_nic_base+D8390_P0_RCR); /* monitor mode */ outb(2, eth_nic_base+D8390_P0_TCR); outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR); outb(eth_rx_start, eth_nic_base+D8390_P0_PSTART); outb(eth_memsize, eth_nic_base+D8390_P0_PSTOP); outb(eth_memsize - 1, eth_nic_base+D8390_P0_BOUND); outb(0xFF, eth_nic_base+D8390_P0_ISR); outb(0, eth_nic_base+D8390_P0_IMR); outb(D8390_COMMAND_PS1 | D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); for (i=0; inode_addr[i], eth_nic_base+D8390_P1_PAR0+i); for (i=0; i= eth_memsize) next = eth_rx_start; outb(D8390_COMMAND_PS1, eth_nic_base+D8390_P0_COMMAND); curr = inb(eth_nic_base+D8390_P1_CURR); outb(D8390_COMMAND_PS0, eth_nic_base+D8390_P0_COMMAND); if (curr >= eth_memsize) curr=eth_rx_start; if (curr == next) return(0); if ( ! retrieve ) return 1; pktoff = next << 8; if (eth_flags & FLAG_PIO) eth_pio_read(pktoff, (unsigned char *)&pkthdr, 4); else memcpy(&pkthdr, bus_to_virt(eth_rmem + pktoff), 4); pktoff += sizeof(pkthdr); /* incoming length includes FCS so must sub 4 */ len = pkthdr.len - 4; if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || len < ETH_ZLEN || len> ETH_FRAME_LEN) { DBG("Bogus packet, ignoring\n"); return (0); } else { p = nic->packet; nic->packetlen = len; /* available to caller */ frag = (eth_memsize << 8) - pktoff; if (len> frag) { /* We have a wrap-around */ /* read first part */ if (eth_flags & FLAG_PIO) eth_pio_read(pktoff, p, frag); else memcpy(p, bus_to_virt(eth_rmem + pktoff), frag); pktoff = eth_rx_start << 8; p += frag; len -= frag; } /* read second part */ if (eth_flags & FLAG_PIO) eth_pio_read(pktoff, p, len); else memcpy(p, bus_to_virt(eth_rmem + pktoff), len); ret = 1; } next = pkthdr.next; /* frame number of next packet */ if (next == eth_rx_start) next = eth_memsize; outb(next-1, eth_nic_base+D8390_P0_BOUND); return(ret); } /************************************************************************** NE_TRANSMIT - Transmit a frame **************************************************************************/ static void ne_transmit(struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) { /* Packet */ /* Programmed I/O */ unsigned short type; type = (t >> 8) | (t << 8); eth_pio_write((unsigned char *) d, eth_tx_start << 8, ETH_ALEN); eth_pio_write(nic->node_addr, (eth_tx_start << 8) + ETH_ALEN, ETH_ALEN); /* bcc generates worse code without (const+const) below */ eth_pio_write((unsigned char *) &type, (eth_tx_start << 8) + (ETH_ALEN + ETH_ALEN), 2); eth_pio_write((unsigned char *) p, (eth_tx_start << 8) + ETH_HLEN, s); s += ETH_HLEN; if (s < ETH_ZLEN) s = ETH_ZLEN; outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); outb(eth_tx_start, eth_nic_base + D8390_P0_TPSR); outb(s, eth_nic_base + D8390_P0_TBCR0); outb(s >> 8, eth_nic_base + D8390_P0_TBCR1); outb(D8390_COMMAND_PS0 | D8390_COMMAND_TXP | D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); } static struct nic_operations ne_operations = { .connect = dummy_connect, .poll = ne_poll, .transmit = ne_transmit, .irq = dummy_irq, }; ISA_DRIVER ( ne_driver, ne_probe_addrs, ne_probe1, GENERIC_ISAPNP_VENDOR, 0x0600 ); DRIVER ( "ne", nic_driver, isapnp_driver, ne_driver, ne_probe, ne_disable ); ISA_ROM("ne","NE1000/2000 and clones"); debian/grub-extras/disabled/gpxe/src/drivers/net/ns8390.h0000664000000000000000000001762512524662415020337 0ustar /************************************************************************** ETHERBOOT - BOOTP/TFTP Bootstrap Program Author: Martin Renters Date: Jun/94 **************************************************************************/ FILE_LICENCE ( BSD2 ); #define VENDOR_NONE 0 #define VENDOR_WD 1 #define VENDOR_NOVELL 2 #define VENDOR_3COM 3 #define FLAG_PIO 0x01 #define FLAG_16BIT 0x02 #define FLAG_790 0x04 #define MEM_8192 32 #define MEM_16384 64 #define MEM_32768 128 #define ISA_MAX_ADDR 0x400 /************************************************************************** Western Digital/SMC Board Definitions **************************************************************************/ #define WD_LOW_BASE 0x200 #define WD_HIGH_BASE 0x3e0 #ifndef WD_DEFAULT_MEM #define WD_DEFAULT_MEM 0xD0000 #endif #define WD_NIC_ADDR 0x10 /************************************************************************** Western Digital/SMC ASIC Addresses **************************************************************************/ #define WD_MSR 0x00 #define WD_ICR 0x01 #define WD_IAR 0x02 #define WD_BIO 0x03 #define WD_IRR 0x04 #define WD_LAAR 0x05 #define WD_IJR 0x06 #define WD_GP2 0x07 #define WD_LAR 0x08 #define WD_BID 0x0E #define WD_ICR_16BIT 0x01 #define WD_MSR_MENB 0x40 #define WD_LAAR_L16EN 0x40 #define WD_LAAR_M16EN 0x80 #define WD_SOFTCONFIG 0x20 /************************************************************************** Western Digital/SMC Board Types **************************************************************************/ #define TYPE_WD8003S 0x02 #define TYPE_WD8003E 0x03 #define TYPE_WD8013EBT 0x05 #define TYPE_WD8003W 0x24 #define TYPE_WD8003EB 0x25 #define TYPE_WD8013W 0x26 #define TYPE_WD8013EP 0x27 #define TYPE_WD8013WC 0x28 #define TYPE_WD8013EPC 0x29 #define TYPE_SMC8216T 0x2a #define TYPE_SMC8216C 0x2b #define TYPE_SMC8416T 0x00 /* Bogus entries: the 8416 generates the */ #define TYPE_SMC8416C 0x00 /* the same codes as the 8216. */ #define TYPE_SMC8013EBP 0x2c /************************************************************************** 3com 3c503 definitions **************************************************************************/ #ifndef _3COM_BASE #define _3COM_BASE 0x300 #endif #define _3COM_TX_PAGE_OFFSET_8BIT 0x20 #define _3COM_TX_PAGE_OFFSET_16BIT 0x0 #define _3COM_RX_PAGE_OFFSET_16BIT 0x20 #define _3COM_ASIC_OFFSET 0x400 #define _3COM_NIC_OFFSET 0x0 #define _3COM_PSTR 0 #define _3COM_PSPR 1 #define _3COM_BCFR 3 #define _3COM_BCFR_2E0 0x01 #define _3COM_BCFR_2A0 0x02 #define _3COM_BCFR_280 0x04 #define _3COM_BCFR_250 0x08 #define _3COM_BCFR_350 0x10 #define _3COM_BCFR_330 0x20 #define _3COM_BCFR_310 0x40 #define _3COM_BCFR_300 0x80 #define _3COM_PCFR 4 #define _3COM_PCFR_PIO 0 #define _3COM_PCFR_C8000 0x10 #define _3COM_PCFR_CC000 0x20 #define _3COM_PCFR_D8000 0x40 #define _3COM_PCFR_DC000 0x80 #define _3COM_CR 6 #define _3COM_CR_RST 0x01 /* Reset GA and NIC */ #define _3COM_CR_XSEL 0x02 /* Transceiver select. BNC=1(def) AUI=0 */ #define _3COM_CR_EALO 0x04 /* window EA PROM 0-15 to I/O base */ #define _3COM_CR_EAHI 0x08 /* window EA PROM 16-31 to I/O base */ #define _3COM_CR_SHARE 0x10 /* select interrupt sharing option */ #define _3COM_CR_DBSEL 0x20 /* Double buffer select */ #define _3COM_CR_DDIR 0x40 /* DMA direction select */ #define _3COM_CR_START 0x80 /* Start DMA controller */ #define _3COM_GACFR 5 #define _3COM_GACFR_MBS0 0x01 #define _3COM_GACFR_MBS1 0x02 #define _3COM_GACFR_MBS2 0x04 #define _3COM_GACFR_RSEL 0x08 /* enable shared memory */ #define _3COM_GACFR_TEST 0x10 /* for GA testing */ #define _3COM_GACFR_OWS 0x20 /* select 0WS access to GA */ #define _3COM_GACFR_TCM 0x40 /* Mask DMA interrupts */ #define _3COM_GACFR_NIM 0x80 /* Mask NIC interrupts */ #define _3COM_STREG 7 #define _3COM_STREG_REV 0x07 /* GA revision */ #define _3COM_STREG_DIP 0x08 /* DMA in progress */ #define _3COM_STREG_DTC 0x10 /* DMA terminal count */ #define _3COM_STREG_OFLW 0x20 /* Overflow */ #define _3COM_STREG_UFLW 0x40 /* Underflow */ #define _3COM_STREG_DPRDY 0x80 /* Data port ready */ #define _3COM_IDCFR 8 #define _3COM_IDCFR_DRQ0 0x01 /* DMA request 1 select */ #define _3COM_IDCFR_DRQ1 0x02 /* DMA request 2 select */ #define _3COM_IDCFR_DRQ2 0x04 /* DMA request 3 select */ #define _3COM_IDCFR_UNUSED 0x08 /* not used */ #define _3COM_IDCFR_IRQ2 0x10 /* Interrupt request 2 select */ #define _3COM_IDCFR_IRQ3 0x20 /* Interrupt request 3 select */ #define _3COM_IDCFR_IRQ4 0x40 /* Interrupt request 4 select */ #define _3COM_IDCFR_IRQ5 0x80 /* Interrupt request 5 select */ #define _3COM_IRQ2 2 #define _3COM_IRQ3 3 #define _3COM_IRQ4 4 #define _3COM_IRQ5 5 #define _3COM_DAMSB 9 #define _3COM_DALSB 0x0a #define _3COM_VPTR2 0x0b #define _3COM_VPTR1 0x0c #define _3COM_VPTR0 0x0d #define _3COM_RFMSB 0x0e #define _3COM_RFLSB 0x0f /************************************************************************** NE1000/2000 definitions **************************************************************************/ #define NE_ASIC_OFFSET 0x10 #define NE_RESET 0x0F /* Used to reset card */ #define NE_DATA 0x00 /* Used to read/write NIC mem */ #define COMPEX_RL2000_TRIES 200 /************************************************************************** 8390 Register Definitions **************************************************************************/ #define D8390_P0_COMMAND 0x00 #define D8390_P0_PSTART 0x01 #define D8390_P0_PSTOP 0x02 #define D8390_P0_BOUND 0x03 #define D8390_P0_TSR 0x04 #define D8390_P0_TPSR 0x04 #define D8390_P0_TBCR0 0x05 #define D8390_P0_TBCR1 0x06 #define D8390_P0_ISR 0x07 #define D8390_P0_RSAR0 0x08 #define D8390_P0_RSAR1 0x09 #define D8390_P0_RBCR0 0x0A #define D8390_P0_RBCR1 0x0B #define D8390_P0_RSR 0x0C #define D8390_P0_RCR 0x0C #define D8390_P0_TCR 0x0D #define D8390_P0_DCR 0x0E #define D8390_P0_IMR 0x0F #define D8390_P1_COMMAND 0x00 #define D8390_P1_PAR0 0x01 #define D8390_P1_PAR1 0x02 #define D8390_P1_PAR2 0x03 #define D8390_P1_PAR3 0x04 #define D8390_P1_PAR4 0x05 #define D8390_P1_PAR5 0x06 #define D8390_P1_CURR 0x07 #define D8390_P1_MAR0 0x08 #define D8390_COMMAND_PS0 0x0 /* Page 0 select */ #define D8390_COMMAND_PS1 0x40 /* Page 1 select */ #define D8390_COMMAND_PS2 0x80 /* Page 2 select */ #define D8390_COMMAND_RD2 0x20 /* Remote DMA control */ #define D8390_COMMAND_RD1 0x10 #define D8390_COMMAND_RD0 0x08 #define D8390_COMMAND_TXP 0x04 /* transmit packet */ #define D8390_COMMAND_STA 0x02 /* start */ #define D8390_COMMAND_STP 0x01 /* stop */ #define D8390_RCR_MON 0x20 /* monitor mode */ #define D8390_DCR_FT1 0x40 #define D8390_DCR_LS 0x08 /* Loopback select */ #define D8390_DCR_WTS 0x01 /* Word transfer select */ #define D8390_ISR_PRX 0x01 /* successful recv */ #define D8390_ISR_PTX 0x02 /* successful xmit */ #define D8390_ISR_RXE 0x04 /* receive error */ #define D8390_ISR_TXE 0x08 /* transmit error */ #define D8390_ISR_OVW 0x10 /* Overflow */ #define D8390_ISR_CNT 0x20 /* Counter overflow */ #define D8390_ISR_RDC 0x40 /* Remote DMA complete */ #define D8390_ISR_RST 0x80 /* reset */ #define D8390_RSTAT_PRX 0x01 /* successful recv */ #define D8390_RSTAT_CRC 0x02 /* CRC error */ #define D8390_RSTAT_FAE 0x04 /* Frame alignment error */ #define D8390_RSTAT_OVER 0x08 /* FIFO overrun */ #define D8390_TXBUF_SIZE 6 #define D8390_RXBUF_END 32 #define D8390_PAGE_SIZE 256 struct ringbuffer { unsigned char status; unsigned char next; unsigned short len; }; /* * Local variables: * c-basic-offset: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/amd8111e.c0000664000000000000000000004207512524662415020604 0ustar /* Advanced Micro Devices Inc. AMD8111E Linux Network Driver * Copyright (C) 2004 Advanced Micro Devices * Copyright (C) 2005 Liu Tao [etherboot port] * * Copyright 2001,2002 Jeff Garzik [ 8139cp.c,tg3.c ] * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)[ tg3.c] * Copyright 1996-1999 Thomas Bogendoerfer [ pcnet32.c ] * Derived from the lance driver written 1993,1994,1995 by Donald Becker. * Copyright 1993 United States Government as represented by the * Director, National Security Agency.[ pcnet32.c ] * Carsten Langgaard, carstenl@mips.com [ pcnet32.c ] * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ FILE_LICENCE ( GPL2_OR_LATER ); #include "etherboot.h" #include "nic.h" #include "mii.h" #include #include #include "string.h" #include "stdint.h" #include "amd8111e.h" /* driver definitions */ #define NUM_TX_SLOTS 2 #define NUM_RX_SLOTS 4 #define TX_SLOTS_MASK 1 #define RX_SLOTS_MASK 3 #define TX_BUF_LEN 1536 #define RX_BUF_LEN 1536 #define TX_PKT_LEN_MAX (ETH_FRAME_LEN - ETH_HLEN) #define RX_PKT_LEN_MIN 60 #define RX_PKT_LEN_MAX ETH_FRAME_LEN #define TX_TIMEOUT 3000 #define TX_PROCESS_TIME 10 #define TX_RETRY (TX_TIMEOUT / TX_PROCESS_TIME) #define PHY_RW_RETRY 10 struct amd8111e_tx_desc { u16 buf_len; u16 tx_flags; u16 tag_ctrl_info; u16 tag_ctrl_cmd; u32 buf_phy_addr; u32 reserved; }; struct amd8111e_rx_desc { u32 reserved; u16 msg_len; u16 tag_ctrl_info; u16 buf_len; u16 rx_flags; u32 buf_phy_addr; }; struct eth_frame { u8 dst_addr[ETH_ALEN]; u8 src_addr[ETH_ALEN]; u16 type; u8 data[ETH_FRAME_LEN - ETH_HLEN]; } __attribute__((packed)); struct amd8111e_priv { struct amd8111e_tx_desc tx_ring[NUM_TX_SLOTS]; struct amd8111e_rx_desc rx_ring[NUM_RX_SLOTS]; unsigned char tx_buf[NUM_TX_SLOTS][TX_BUF_LEN]; unsigned char rx_buf[NUM_RX_SLOTS][RX_BUF_LEN]; unsigned long tx_idx, rx_idx; int tx_consistent; char opened; char link; char speed; char duplex; int ext_phy_addr; u32 ext_phy_id; struct pci_device *pdev; struct nic *nic; void *mmio; }; static struct amd8111e_priv amd8111e; /******************************************************** * locale functions * ********************************************************/ static void amd8111e_init_hw_default(struct amd8111e_priv *lp); static int amd8111e_start(struct amd8111e_priv *lp); static int amd8111e_read_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 *val); #if 0 static int amd8111e_write_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 val); #endif static void amd8111e_probe_ext_phy(struct amd8111e_priv *lp); static void amd8111e_disable_interrupt(struct amd8111e_priv *lp); static void amd8111e_enable_interrupt(struct amd8111e_priv *lp); static void amd8111e_force_interrupt(struct amd8111e_priv *lp); static int amd8111e_get_mac_address(struct amd8111e_priv *lp); static int amd8111e_init_rx_ring(struct amd8111e_priv *lp); static int amd8111e_init_tx_ring(struct amd8111e_priv *lp); static int amd8111e_wait_tx_ring(struct amd8111e_priv *lp, unsigned int index); static void amd8111e_wait_link(struct amd8111e_priv *lp); static void amd8111e_poll_link(struct amd8111e_priv *lp); static void amd8111e_restart(struct amd8111e_priv *lp); /* * This function clears necessary the device registers. */ static void amd8111e_init_hw_default(struct amd8111e_priv *lp) { unsigned int reg_val; void *mmio = lp->mmio; /* stop the chip */ writel(RUN, mmio + CMD0); /* Clear RCV_RING_BASE_ADDR */ writel(0, mmio + RCV_RING_BASE_ADDR0); /* Clear XMT_RING_BASE_ADDR */ writel(0, mmio + XMT_RING_BASE_ADDR0); writel(0, mmio + XMT_RING_BASE_ADDR1); writel(0, mmio + XMT_RING_BASE_ADDR2); writel(0, mmio + XMT_RING_BASE_ADDR3); /* Clear CMD0 */ writel(CMD0_CLEAR, mmio + CMD0); /* Clear CMD2 */ writel(CMD2_CLEAR, mmio + CMD2); /* Clear CMD7 */ writel(CMD7_CLEAR, mmio + CMD7); /* Clear DLY_INT_A and DLY_INT_B */ writel(0x0, mmio + DLY_INT_A); writel(0x0, mmio + DLY_INT_B); /* Clear FLOW_CONTROL */ writel(0x0, mmio + FLOW_CONTROL); /* Clear INT0 write 1 to clear register */ reg_val = readl(mmio + INT0); writel(reg_val, mmio + INT0); /* Clear STVAL */ writel(0x0, mmio + STVAL); /* Clear INTEN0 */ writel(INTEN0_CLEAR, mmio + INTEN0); /* Clear LADRF */ writel(0x0, mmio + LADRF); /* Set SRAM_SIZE & SRAM_BOUNDARY registers */ writel(0x80010, mmio + SRAM_SIZE); /* Clear RCV_RING0_LEN */ writel(0x0, mmio + RCV_RING_LEN0); /* Clear XMT_RING0/1/2/3_LEN */ writel(0x0, mmio + XMT_RING_LEN0); writel(0x0, mmio + XMT_RING_LEN1); writel(0x0, mmio + XMT_RING_LEN2); writel(0x0, mmio + XMT_RING_LEN3); /* Clear XMT_RING_LIMIT */ writel(0x0, mmio + XMT_RING_LIMIT); /* Clear MIB */ writew(MIB_CLEAR, mmio + MIB_ADDR); /* Clear LARF */ writel( 0, mmio + LADRF); writel( 0, mmio + LADRF + 4); /* SRAM_SIZE register */ reg_val = readl(mmio + SRAM_SIZE); /* Set default value to CTRL1 Register */ writel(CTRL1_DEFAULT, mmio + CTRL1); /* To avoid PCI posting bug */ readl(mmio + CMD2); } /* * This function initializes the device registers and starts the device. */ static int amd8111e_start(struct amd8111e_priv *lp) { struct nic *nic = lp->nic; void *mmio = lp->mmio; int i, reg_val; /* stop the chip */ writel(RUN, mmio + CMD0); /* AUTOPOLL0 Register *//*TBD default value is 8100 in FPS */ writew(0x8100 | lp->ext_phy_addr, mmio + AUTOPOLL0); /* enable the port manager and set auto negotiation always */ writel(VAL1 | EN_PMGR, mmio + CMD3 ); writel(XPHYANE | XPHYRST, mmio + CTRL2); /* set control registers */ reg_val = readl(mmio + CTRL1); reg_val &= ~XMTSP_MASK; writel(reg_val | XMTSP_128 | CACHE_ALIGN, mmio + CTRL1); /* initialize tx and rx ring base addresses */ amd8111e_init_tx_ring(lp); amd8111e_init_rx_ring(lp); writel(virt_to_bus(lp->tx_ring), mmio + XMT_RING_BASE_ADDR0); writel(virt_to_bus(lp->rx_ring), mmio + RCV_RING_BASE_ADDR0); writew(NUM_TX_SLOTS, mmio + XMT_RING_LEN0); writew(NUM_RX_SLOTS, mmio + RCV_RING_LEN0); /* set default IPG to 96 */ writew(DEFAULT_IPG, mmio + IPG); writew(DEFAULT_IPG - IFS1_DELTA, mmio + IFS1); /* AutoPAD transmit, Retransmit on Underflow */ writel(VAL0 | APAD_XMT | REX_RTRY | REX_UFLO, mmio + CMD2); /* JUMBO disabled */ writel(JUMBO, mmio + CMD3); /* Setting the MAC address to the device */ for(i = 0; i < ETH_ALEN; i++) writeb(nic->node_addr[i], mmio + PADR + i); /* set RUN bit to start the chip, interrupt not enabled */ writel(VAL2 | RDMD0 | VAL0 | RUN, mmio + CMD0); /* To avoid PCI posting bug */ readl(mmio + CMD0); return 0; } /* This function will read the PHY registers. */ static int amd8111e_read_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 *val) { void *mmio = lp->mmio; unsigned int reg_val; unsigned int retry = PHY_RW_RETRY; reg_val = readl(mmio + PHY_ACCESS); while (reg_val & PHY_CMD_ACTIVE) reg_val = readl(mmio + PHY_ACCESS); writel(PHY_RD_CMD | ((phy_addr & 0x1f) << 21) | ((reg & 0x1f) << 16), mmio + PHY_ACCESS); do { reg_val = readl(mmio + PHY_ACCESS); udelay(30); /* It takes 30 us to read/write data */ } while (--retry && (reg_val & PHY_CMD_ACTIVE)); if (reg_val & PHY_RD_ERR) { *val = 0; return -1; } *val = reg_val & 0xffff; return 0; } /* This function will write into PHY registers. */ #if 0 static int amd8111e_write_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 val) { void *mmio = lp->mmio; unsigned int reg_val; unsigned int retry = PHY_RW_RETRY; reg_val = readl(mmio + PHY_ACCESS); while (reg_val & PHY_CMD_ACTIVE) reg_val = readl(mmio + PHY_ACCESS); writel(PHY_WR_CMD | ((phy_addr & 0x1f) << 21) | ((reg & 0x1f) << 16) | val, mmio + PHY_ACCESS); do { reg_val = readl(mmio + PHY_ACCESS); udelay(30); /* It takes 30 us to read/write the data */ } while (--retry && (reg_val & PHY_CMD_ACTIVE)); if(reg_val & PHY_RD_ERR) return -1; return 0; } #endif static void amd8111e_probe_ext_phy(struct amd8111e_priv *lp) { int i; lp->ext_phy_id = 0; lp->ext_phy_addr = 1; for (i = 0x1e; i >= 0; i--) { u32 id1, id2; if (amd8111e_read_phy(lp, i, MII_PHYSID1, &id1)) continue; if (amd8111e_read_phy(lp, i, MII_PHYSID2, &id2)) continue; lp->ext_phy_id = (id1 << 16) | id2; lp->ext_phy_addr = i; break; } if (lp->ext_phy_id) printf("Found MII PHY ID 0x%08x at address 0x%02x\n", (unsigned int) lp->ext_phy_id, lp->ext_phy_addr); else printf("Couldn't detect MII PHY, assuming address 0x01\n"); } static void amd8111e_disable_interrupt(struct amd8111e_priv *lp) { void *mmio = lp->mmio; unsigned int int0; writel(INTREN, mmio + CMD0); writel(INTEN0_CLEAR, mmio + INTEN0); int0 = readl(mmio + INT0); writel(int0, mmio + INT0); readl(mmio + INT0); } static void amd8111e_enable_interrupt(struct amd8111e_priv *lp) { void *mmio = lp->mmio; writel(VAL3 | LCINTEN | VAL1 | TINTEN0 | VAL0 | RINTEN0, mmio + INTEN0); writel(VAL0 | INTREN, mmio + CMD0); readl(mmio + CMD0); } static void amd8111e_force_interrupt(struct amd8111e_priv *lp) { void *mmio = lp->mmio; writel(VAL0 | UINTCMD, mmio + CMD0); readl(mmio + CMD0); } static int amd8111e_get_mac_address(struct amd8111e_priv *lp) { struct nic *nic = lp->nic; void *mmio = lp->mmio; int i; /* BIOS should have set mac address to PADR register, * so we read PADR to get it. */ for (i = 0; i < ETH_ALEN; i++) nic->node_addr[i] = readb(mmio + PADR + i); DBG ( "Ethernet addr: %s\n", eth_ntoa ( nic->node_addr ) ); return 0; } static int amd8111e_init_rx_ring(struct amd8111e_priv *lp) { int i; lp->rx_idx = 0; /* Initilaizing receive descriptors */ for (i = 0; i < NUM_RX_SLOTS; i++) { lp->rx_ring[i].buf_phy_addr = cpu_to_le32(virt_to_bus(lp->rx_buf[i])); lp->rx_ring[i].buf_len = cpu_to_le16(RX_BUF_LEN); wmb(); lp->rx_ring[i].rx_flags = cpu_to_le16(OWN_BIT); } return 0; } static int amd8111e_init_tx_ring(struct amd8111e_priv *lp) { int i; lp->tx_idx = 0; lp->tx_consistent = 1; /* Initializing transmit descriptors */ for (i = 0; i < NUM_TX_SLOTS; i++) { lp->tx_ring[i].tx_flags = 0; lp->tx_ring[i].buf_phy_addr = 0; lp->tx_ring[i].buf_len = 0; } return 0; } static int amd8111e_wait_tx_ring(struct amd8111e_priv *lp, unsigned int index) { volatile u16 status; int retry = TX_RETRY; status = le16_to_cpu(lp->tx_ring[index].tx_flags); while (--retry && (status & OWN_BIT)) { mdelay(TX_PROCESS_TIME); status = le16_to_cpu(lp->tx_ring[index].tx_flags); } if (status & OWN_BIT) { printf("Error: tx slot %d timeout, stat = 0x%x\n", index, status); amd8111e_restart(lp); return -1; } return 0; } static void amd8111e_wait_link(struct amd8111e_priv *lp) { unsigned int status; u32 reg_val; do { /* read phy to update STAT0 register */ amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMCR, ®_val); amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMSR, ®_val); amd8111e_read_phy(lp, lp->ext_phy_addr, MII_ADVERTISE, ®_val); amd8111e_read_phy(lp, lp->ext_phy_addr, MII_LPA, ®_val); status = readl(lp->mmio + STAT0); } while (!(status & AUTONEG_COMPLETE) || !(status & LINK_STATS)); } static void amd8111e_poll_link(struct amd8111e_priv *lp) { unsigned int status, speed; u32 reg_val; if (!lp->link) { /* read phy to update STAT0 register */ amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMCR, ®_val); amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMSR, ®_val); amd8111e_read_phy(lp, lp->ext_phy_addr, MII_ADVERTISE, ®_val); amd8111e_read_phy(lp, lp->ext_phy_addr, MII_LPA, ®_val); status = readl(lp->mmio + STAT0); if (status & LINK_STATS) { lp->link = 1; speed = (status & SPEED_MASK) >> 7; if (speed == PHY_SPEED_100) lp->speed = 1; else lp->speed = 0; if (status & FULL_DPLX) lp->duplex = 1; else lp->duplex = 0; printf("Link is up: %s Mbps %s duplex\n", lp->speed ? "100" : "10", lp->duplex ? "full" : "half"); } } else { status = readl(lp->mmio + STAT0); if (!(status & LINK_STATS)) { lp->link = 0; printf("Link is down\n"); } } } static void amd8111e_restart(struct amd8111e_priv *lp) { printf("\nStarting nic...\n"); amd8111e_disable_interrupt(lp); amd8111e_init_hw_default(lp); amd8111e_probe_ext_phy(lp); amd8111e_get_mac_address(lp); amd8111e_start(lp); printf("Waiting link up...\n"); lp->link = 0; amd8111e_wait_link(lp); amd8111e_poll_link(lp); } /******************************************************** * Interface Functions * ********************************************************/ static void amd8111e_transmit(struct nic *nic, const char *dst_addr, unsigned int type, unsigned int size, const char *packet) { struct amd8111e_priv *lp = nic->priv_data; struct eth_frame *frame; unsigned int index; /* check packet size */ if (size > TX_PKT_LEN_MAX) { printf("amd8111e_transmit(): too large packet, drop\n"); return; } /* get tx slot */ index = lp->tx_idx; if (amd8111e_wait_tx_ring(lp, index)) return; /* fill frame */ frame = (struct eth_frame *)lp->tx_buf[index]; memset(frame->data, 0, TX_PKT_LEN_MAX); memcpy(frame->dst_addr, dst_addr, ETH_ALEN); memcpy(frame->src_addr, nic->node_addr, ETH_ALEN); frame->type = htons(type); memcpy(frame->data, packet, size); /* start xmit */ lp->tx_ring[index].buf_len = cpu_to_le16(ETH_HLEN + size); lp->tx_ring[index].buf_phy_addr = cpu_to_le32(virt_to_bus(frame)); wmb(); lp->tx_ring[index].tx_flags = cpu_to_le16(OWN_BIT | STP_BIT | ENP_BIT | ADD_FCS_BIT | LTINT_BIT); writel(VAL1 | TDMD0, lp->mmio + CMD0); readl(lp->mmio + CMD0); /* update slot pointer */ lp->tx_idx = (lp->tx_idx + 1) & TX_SLOTS_MASK; } static int amd8111e_poll(struct nic *nic, int retrieve) { /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ /* nic->packetlen should contain length of data */ struct amd8111e_priv *lp = nic->priv_data; u16 status, pkt_len; unsigned int index, pkt_ok; amd8111e_poll_link(lp); index = lp->rx_idx; status = le16_to_cpu(lp->rx_ring[index].rx_flags); pkt_len = le16_to_cpu(lp->rx_ring[index].msg_len) - 4; /* remove 4bytes FCS */ if (status & OWN_BIT) return 0; if (status & ERR_BIT) pkt_ok = 0; else if (!(status & STP_BIT)) pkt_ok = 0; else if (!(status & ENP_BIT)) pkt_ok = 0; else if (pkt_len < RX_PKT_LEN_MIN) pkt_ok = 0; else if (pkt_len > RX_PKT_LEN_MAX) pkt_ok = 0; else pkt_ok = 1; if (pkt_ok) { if (!retrieve) return 1; nic->packetlen = pkt_len; memcpy(nic->packet, lp->rx_buf[index], nic->packetlen); } lp->rx_ring[index].buf_phy_addr = cpu_to_le32(virt_to_bus(lp->rx_buf[index])); lp->rx_ring[index].buf_len = cpu_to_le16(RX_BUF_LEN); wmb(); lp->rx_ring[index].rx_flags = cpu_to_le16(OWN_BIT); writel(VAL2 | RDMD0, lp->mmio + CMD0); readl(lp->mmio + CMD0); lp->rx_idx = (lp->rx_idx + 1) & RX_SLOTS_MASK; return pkt_ok; } static void amd8111e_disable(struct nic *nic) { struct amd8111e_priv *lp = nic->priv_data; /* disable interrupt */ amd8111e_disable_interrupt(lp); /* stop chip */ amd8111e_init_hw_default(lp); /* unmap mmio */ iounmap(lp->mmio); /* update status */ lp->opened = 0; } static void amd8111e_irq(struct nic *nic, irq_action_t action) { struct amd8111e_priv *lp = nic->priv_data; switch (action) { case DISABLE: amd8111e_disable_interrupt(lp); break; case ENABLE: amd8111e_enable_interrupt(lp); break; case FORCE: amd8111e_force_interrupt(lp); break; } } static struct nic_operations amd8111e_operations = { .connect = dummy_connect, .poll = amd8111e_poll, .transmit = amd8111e_transmit, .irq = amd8111e_irq, }; static int amd8111e_probe(struct nic *nic, struct pci_device *pdev) { struct amd8111e_priv *lp = &amd8111e; unsigned long mmio_start, mmio_len; nic->ioaddr = pdev->ioaddr; nic->irqno = pdev->irq; mmio_start = pci_bar_start(pdev, PCI_BASE_ADDRESS_0); mmio_len = pci_bar_size(pdev, PCI_BASE_ADDRESS_0); memset(lp, 0, sizeof(*lp)); lp->pdev = pdev; lp->nic = nic; lp->mmio = ioremap(mmio_start, mmio_len); lp->opened = 1; adjust_pci_device(pdev); nic->priv_data = lp; amd8111e_restart(lp); nic->nic_op = &amd8111e_operations; return 1; } static struct pci_device_id amd8111e_nics[] = { PCI_ROM(0x1022, 0x7462, "amd8111e", "AMD8111E", 0), }; PCI_DRIVER ( amd8111e_driver, amd8111e_nics, PCI_NO_CLASS ); DRIVER ( "AMD8111E", nic_driver, pci_driver, amd8111e_driver, amd8111e_probe, amd8111e_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/epic100.c0000664000000000000000000003417212524662415020523 0ustar /* epic100.c: A SMC 83c170 EPIC/100 fast ethernet driver for Etherboot */ FILE_LICENCE ( GPL2_OR_LATER ); /* 05/06/2003 timlegge Fixed relocation and implemented Multicast */ #define LINUX_OUT_MACROS #include "etherboot.h" #include #include #include "nic.h" #include "console.h" #include "epic100.h" /* Condensed operations for readability */ #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) #define TX_RING_SIZE 2 /* use at least 2 buffers for TX */ #define RX_RING_SIZE 2 #define PKT_BUF_SZ 1536 /* Size of each temporary Tx/Rx buffer.*/ /* #define DEBUG_RX #define DEBUG_TX #define DEBUG_EEPROM */ #define EPIC_DEBUG 0 /* debug level */ /* The EPIC100 Rx and Tx buffer descriptors. */ struct epic_rx_desc { unsigned long status; unsigned long bufaddr; unsigned long buflength; unsigned long next; }; /* description of the tx descriptors control bits commonly used */ #define TD_STDFLAGS TD_LASTDESC struct epic_tx_desc { unsigned long status; unsigned long bufaddr; unsigned long buflength; unsigned long next; }; #define delay(nanosec) do { int _i = 3; while (--_i > 0) \ { __SLOW_DOWN_IO; }} while (0) static void epic100_open(void); static void epic100_init_ring(void); static void epic100_disable(struct nic *nic); static int epic100_poll(struct nic *nic, int retrieve); static void epic100_transmit(struct nic *nic, const char *destaddr, unsigned int type, unsigned int len, const char *data); #ifdef DEBUG_EEPROM static int read_eeprom(int location); #endif static int mii_read(int phy_id, int location); static void epic100_irq(struct nic *nic, irq_action_t action); static struct nic_operations epic100_operations; static int ioaddr; static int command; static int intstat; static int intmask; static int genctl ; static int eectl ; static int test ; static int mmctl ; static int mmdata ; static int lan0 ; static int mc0 ; static int rxcon ; static int txcon ; static int prcdar ; static int ptcdar ; static int eththr ; static unsigned int cur_rx, cur_tx; /* The next free ring entry */ #ifdef DEBUG_EEPROM static unsigned short eeprom[64]; #endif static signed char phys[4]; /* MII device addresses. */ struct { struct epic_rx_desc rx_ring[RX_RING_SIZE] __attribute__ ((aligned(4))); struct epic_tx_desc tx_ring[TX_RING_SIZE] __attribute__ ((aligned(4))); unsigned char rx_packet[PKT_BUF_SZ * RX_RING_SIZE]; unsigned char tx_packet[PKT_BUF_SZ * TX_RING_SIZE]; } epic100_bufs __shared; #define rx_ring epic100_bufs.rx_ring #define tx_ring epic100_bufs.tx_ring #define rx_packet epic100_bufs.rx_packet #define tx_packet epic100_bufs.tx_packet /***********************************************************************/ /* Externally visible functions */ /***********************************************************************/ static int epic100_probe ( struct nic *nic, struct pci_device *pci ) { int i; unsigned short* ap; unsigned int phy, phy_idx; if (pci->ioaddr == 0) return 0; /* Ideally we would detect all network cards in slot order. That would be best done a central PCI probe dispatch, which wouldn't work well with the current structure. So instead we detect just the Epic cards in slot order. */ ioaddr = pci->ioaddr; nic->irqno = 0; nic->ioaddr = pci->ioaddr & ~3; /* compute all used static epic100 registers address */ command = ioaddr + COMMAND; /* Control Register */ intstat = ioaddr + INTSTAT; /* Interrupt Status */ intmask = ioaddr + INTMASK; /* Interrupt Mask */ genctl = ioaddr + GENCTL; /* General Control */ eectl = ioaddr + EECTL; /* EEPROM Control */ test = ioaddr + TEST; /* Test register (clocks) */ mmctl = ioaddr + MMCTL; /* MII Management Interface Control */ mmdata = ioaddr + MMDATA; /* MII Management Interface Data */ lan0 = ioaddr + LAN0; /* MAC address. (0x40-0x48) */ mc0 = ioaddr + MC0; /* Multicast Control */ rxcon = ioaddr + RXCON; /* Receive Control */ txcon = ioaddr + TXCON; /* Transmit Control */ prcdar = ioaddr + PRCDAR; /* PCI Receive Current Descr Address */ ptcdar = ioaddr + PTCDAR; /* PCI Transmit Current Descr Address */ eththr = ioaddr + ETHTHR; /* Early Transmit Threshold */ /* Reset the chip & bring it out of low-power mode. */ outl(GC_SOFT_RESET, genctl); /* Disable ALL interrupts by setting the interrupt mask. */ outl(INTR_DISABLE, intmask); /* * set the internal clocks: * Application Note 7.15 says: * In order to set the CLOCK TEST bit in the TEST register, * perform the following: * * Write 0x0008 to the test register at least sixteen * consecutive times. * * The CLOCK TEST bit is Write-Only. Writing it several times * consecutively insures a successful write to the bit... */ for (i = 0; i < 16; i++) { outl(0x00000008, test); } #ifdef DEBUG_EEPROM { unsigned short sum = 0; unsigned short value; for (i = 0; i < 64; i++) { value = read_eeprom(i); eeprom[i] = value; sum += value; } } #if (EPIC_DEBUG > 1) printf("EEPROM contents\n"); for (i = 0; i < 64; i++) { printf(" %hhX%s", eeprom[i], i % 16 == 15 ? "\n" : ""); } #endif #endif /* This could also be read from the EEPROM. */ ap = (unsigned short*)nic->node_addr; for (i = 0; i < 3; i++) *ap++ = inw(lan0 + i*4); DBG ( " I/O %4.4x %s ", ioaddr, eth_ntoa ( nic->node_addr ) ); /* Find the connected MII xcvrs. */ for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(phys); phy++) { int mii_status = mii_read(phy, 0); if (mii_status != 0xffff && mii_status != 0x0000) { phys[phy_idx++] = phy; #if (EPIC_DEBUG > 1) printf("MII transceiver found at address %d.\n", phy); #endif } } if (phy_idx == 0) { #if (EPIC_DEBUG > 1) printf("***WARNING***: No MII transceiver found!\n"); #endif /* Use the known PHY address of the EPII. */ phys[0] = 3; } epic100_open(); nic->nic_op = &epic100_operations; return 1; } static void set_rx_mode(void) { unsigned char mc_filter[8]; int i; memset(mc_filter, 0xff, sizeof(mc_filter)); outl(0x0C, rxcon); for(i = 0; i < 4; i++) outw(((unsigned short *)mc_filter)[i], mc0 + i*4); return; } static void epic100_open(void) { int mii_reg5; int full_duplex = 0; unsigned long tmp; epic100_init_ring(); /* Pull the chip out of low-power mode, and set for PCI read multiple. */ outl(GC_RX_FIFO_THR_64 | GC_MRC_READ_MULT | GC_ONE_COPY, genctl); outl(TX_FIFO_THRESH, eththr); tmp = TC_EARLY_TX_ENABLE | TX_SLOT_TIME; mii_reg5 = mii_read(phys[0], 5); if (mii_reg5 != 0xffff && (mii_reg5 & 0x0100)) { full_duplex = 1; printf(" full-duplex mode"); tmp |= TC_LM_FULL_DPX; } else tmp |= TC_LM_NORMAL; outl(tmp, txcon); /* Give adress of RX and TX ring to the chip */ outl(virt_to_le32desc(&rx_ring), prcdar); outl(virt_to_le32desc(&tx_ring), ptcdar); /* Start the chip's Rx process: receive unicast and broadcast */ set_rx_mode(); outl(CR_START_RX | CR_QUEUE_RX, command); putchar('\n'); } /* Initialize the Rx and Tx rings. */ static void epic100_init_ring(void) { int i; cur_rx = cur_tx = 0; for (i = 0; i < RX_RING_SIZE; i++) { rx_ring[i].status = cpu_to_le32(RRING_OWN); /* Owned by Epic chip */ rx_ring[i].buflength = cpu_to_le32(PKT_BUF_SZ); rx_ring[i].bufaddr = virt_to_bus(&rx_packet[i * PKT_BUF_SZ]); rx_ring[i].next = virt_to_le32desc(&rx_ring[i + 1]) ; } /* Mark the last entry as wrapping the ring. */ rx_ring[i-1].next = virt_to_le32desc(&rx_ring[0]); /* *The Tx buffer descriptor is filled in as needed, * but we do need to clear the ownership bit. */ for (i = 0; i < TX_RING_SIZE; i++) { tx_ring[i].status = 0x0000; /* Owned by CPU */ tx_ring[i].buflength = 0x0000 | cpu_to_le32(TD_STDFLAGS << 16); tx_ring[i].bufaddr = virt_to_bus(&tx_packet[i * PKT_BUF_SZ]); tx_ring[i].next = virt_to_le32desc(&tx_ring[i + 1]); } tx_ring[i-1].next = virt_to_le32desc(&tx_ring[0]); } /* function: epic100_transmit * This transmits a packet. * * Arguments: char d[6]: destination ethernet address. * unsigned short t: ethernet protocol type. * unsigned short s: size of the data-part of the packet. * char *p: the data for the packet. * returns: void. */ static void epic100_transmit(struct nic *nic, const char *destaddr, unsigned int type, unsigned int len, const char *data) { unsigned short nstype; unsigned char *txp; int entry; unsigned long ct; /* Calculate the next Tx descriptor entry. */ entry = cur_tx % TX_RING_SIZE; if ((tx_ring[entry].status & TRING_OWN) == TRING_OWN) { printf("eth_transmit: Unable to transmit. status=%4.4lx. Resetting...\n", tx_ring[entry].status); epic100_open(); return; } txp = tx_packet + (entry * PKT_BUF_SZ); memcpy(txp, destaddr, ETH_ALEN); memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN); nstype = htons(type); memcpy(txp + 12, (char*)&nstype, 2); memcpy(txp + ETH_HLEN, data, len); len += ETH_HLEN; len &= 0x0FFF; while(len < ETH_ZLEN) txp[len++] = '\0'; /* * Caution: the write order is important here, * set the base address with the "ownership" * bits last. */ tx_ring[entry].buflength |= cpu_to_le32(len); tx_ring[entry].status = cpu_to_le32(len << 16) | cpu_to_le32(TRING_OWN); /* Pass ownership to the chip. */ cur_tx++; /* Trigger an immediate transmit demand. */ outl(CR_QUEUE_TX, command); ct = currticks(); /* timeout 10 ms for transmit */ while ((le32_to_cpu(tx_ring[entry].status) & (TRING_OWN)) && ct + 10*1000 < currticks()) /* Wait */; if ((le32_to_cpu(tx_ring[entry].status) & TRING_OWN) != 0) printf("Oops, transmitter timeout, status=%4.4lX\n", tx_ring[entry].status); } /* function: epic100_poll / eth_poll * This receives a packet from the network. * * Arguments: none * * returns: 1 if a packet was received. * 0 if no pacet was received. * side effects: * returns the packet in the array nic->packet. * returns the length of the packet in nic->packetlen. */ static int epic100_poll(struct nic *nic, int retrieve) { int entry; int retcode; int status; entry = cur_rx % RX_RING_SIZE; if ((rx_ring[entry].status & cpu_to_le32(RRING_OWN)) == RRING_OWN) return (0); if ( ! retrieve ) return 1; status = le32_to_cpu(rx_ring[entry].status); /* We own the next entry, it's a new packet. Send it up. */ #if (EPIC_DEBUG > 4) printf("epic_poll: entry %d status %hX\n", entry, status); #endif cur_rx++; if (status & 0x2000) { printf("epic_poll: Giant packet\n"); retcode = 0; } else if (status & 0x0006) { /* Rx Frame errors are counted in hardware. */ printf("epic_poll: Frame received with errors\n"); retcode = 0; } else { /* Omit the four octet CRC from the length. */ nic->packetlen = le32_to_cpu((rx_ring[entry].buflength))- 4; memcpy(nic->packet, &rx_packet[entry * PKT_BUF_SZ], nic->packetlen); retcode = 1; } /* Clear all error sources. */ outl(status & INTR_CLEARERRS, intstat); /* Give the descriptor back to the chip */ rx_ring[entry].status = RRING_OWN; /* Restart Receiver */ outl(CR_START_RX | CR_QUEUE_RX, command); return retcode; } static void epic100_disable ( struct nic *nic __unused ) { /* Soft reset the chip. */ outl(GC_SOFT_RESET, genctl); } static void epic100_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } #ifdef DEBUG_EEPROM /* Serial EEPROM section. */ /* EEPROM_Ctrl bits. */ #define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */ #define EE_CS 0x02 /* EEPROM chip select. */ #define EE_DATA_WRITE 0x08 /* EEPROM chip data in. */ #define EE_WRITE_0 0x01 #define EE_WRITE_1 0x09 #define EE_DATA_READ 0x10 /* EEPROM chip data out. */ #define EE_ENB (0x0001 | EE_CS) /* The EEPROM commands include the alway-set leading bit. */ #define EE_WRITE_CMD (5 << 6) #define EE_READ_CMD (6 << 6) #define EE_ERASE_CMD (7 << 6) #define eeprom_delay(n) delay(n) static int read_eeprom(int location) { int i; int retval = 0; int read_cmd = location | EE_READ_CMD; outl(EE_ENB & ~EE_CS, eectl); outl(EE_ENB, eectl); /* Shift the read command bits out. */ for (i = 10; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; outl(EE_ENB | dataval, eectl); eeprom_delay(100); outl(EE_ENB | dataval | EE_SHIFT_CLK, eectl); eeprom_delay(150); outl(EE_ENB | dataval, eectl); /* Finish EEPROM a clock tick. */ eeprom_delay(250); } outl(EE_ENB, eectl); for (i = 16; i > 0; i--) { outl(EE_ENB | EE_SHIFT_CLK, eectl); eeprom_delay(100); retval = (retval << 1) | ((inl(eectl) & EE_DATA_READ) ? 1 : 0); outl(EE_ENB, eectl); eeprom_delay(100); } /* Terminate the EEPROM access. */ outl(EE_ENB & ~EE_CS, eectl); return retval; } #endif #define MII_READOP 1 #define MII_WRITEOP 2 static int mii_read(int phy_id, int location) { int i; outl((phy_id << 9) | (location << 4) | MII_READOP, mmctl); /* Typical operation takes < 50 ticks. */ for (i = 4000; i > 0; i--) if ((inl(mmctl) & MII_READOP) == 0) break; return inw(mmdata); } static struct nic_operations epic100_operations = { .connect = dummy_connect, .poll = epic100_poll, .transmit = epic100_transmit, .irq = epic100_irq, }; static struct pci_device_id epic100_nics[] = { PCI_ROM(0x10b8, 0x0005, "epic100", "SMC EtherPowerII", 0), /* SMC 83c170 EPIC/100 */ PCI_ROM(0x10b8, 0x0006, "smc-83c175", "SMC EPIC/C 83c175", 0), }; PCI_DRIVER ( epic100_driver, epic100_nics, PCI_NO_CLASS ); DRIVER ( "EPIC100", nic_driver, pci_driver, epic100_driver, epic100_probe, epic100_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/smc9000.c0000664000000000000000000006431312524662415020455 0ustar #ifdef ALLMULTI #error multicast support is not yet implemented #endif /*------------------------------------------------------------------------ * smc9000.c * This is a Etherboot driver for SMC's 9000 series of Ethernet cards. * * Copyright (C) 1998 Daniel Engstrm * Based on the Linux SMC9000 driver, smc9194.c by Eric Stahlman * Copyright (C) 1996 by Erik Stahlman * * This software may be used and distributed according to the terms * of the GNU Public License, incorporated herein by reference. * * "Features" of the SMC chip: * 4608 byte packet memory. ( for the 91C92/4. Others have more ) * EEPROM for configuration * AUI/TP selection * * Authors * Erik Stahlman * Daniel Engstrm * * History * 98-09-25 Daniel Engstrm Etherboot driver crated from Eric's * Linux driver. * *---------------------------------------------------------------------------*/ FILE_LICENCE ( GPL_ANY ); #define LINUX_OUT_MACROS 1 #define SMC9000_DEBUG 0 #if SMC9000_DEBUG > 1 #define PRINTK2 printf #else #define PRINTK2(args...) #endif #include #include #include "etherboot.h" #include "nic.h" #include #include "smc9000.h" # define _outb outb # define _outw outw static const char smc9000_version[] = "Version 0.99 98-09-30"; static const char *interfaces[ 2 ] = { "TP", "AUI" }; static const char *chip_ids[ 15 ] = { NULL, NULL, NULL, /* 3 */ "SMC91C90/91C92", /* 4 */ "SMC91C94", /* 5 */ "SMC91C95", NULL, /* 7 */ "SMC91C100", /* 8 */ "SMC91C100FD", /* 9 */ "SMC91C11xFD", NULL, NULL, NULL, NULL, NULL }; static const char smc91c96_id[] = "SMC91C96"; /*------------------------------------------------------------ . Reads a register from the MII Management serial interface .-------------------------------------------------------------*/ static word smc_read_phy_register(int ioaddr, byte phyaddr, byte phyreg) { int oldBank; unsigned int i; byte mask; word mii_reg; byte bits[64]; int clk_idx = 0; int input_idx; word phydata; // 32 consecutive ones on MDO to establish sync for (i = 0; i < 32; ++i) bits[clk_idx++] = MII_MDOE | MII_MDO; // Start code <01> bits[clk_idx++] = MII_MDOE; bits[clk_idx++] = MII_MDOE | MII_MDO; // Read command <10> bits[clk_idx++] = MII_MDOE | MII_MDO; bits[clk_idx++] = MII_MDOE; // Output the PHY address, msb first mask = (byte)0x10; for (i = 0; i < 5; ++i) { if (phyaddr & mask) bits[clk_idx++] = MII_MDOE | MII_MDO; else bits[clk_idx++] = MII_MDOE; // Shift to next lowest bit mask >>= 1; } // Output the phy register number, msb first mask = (byte)0x10; for (i = 0; i < 5; ++i) { if (phyreg & mask) bits[clk_idx++] = MII_MDOE | MII_MDO; else bits[clk_idx++] = MII_MDOE; // Shift to next lowest bit mask >>= 1; } // Tristate and turnaround (2 bit times) bits[clk_idx++] = 0; //bits[clk_idx++] = 0; // Input starts at this bit time input_idx = clk_idx; // Will input 16 bits for (i = 0; i < 16; ++i) bits[clk_idx++] = 0; // Final clock bit bits[clk_idx++] = 0; // Save the current bank oldBank = inw( ioaddr+BANK_SELECT ); // Select bank 3 SMC_SELECT_BANK(ioaddr, 3); // Get the current MII register value mii_reg = inw( ioaddr+MII_REG ); // Turn off all MII Interface bits mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO); // Clock all 64 cycles for (i = 0; i < sizeof(bits); ++i) { // Clock Low - output data outw( mii_reg | bits[i], ioaddr+MII_REG ); udelay(50); // Clock Hi - input data outw( mii_reg | bits[i] | MII_MCLK, ioaddr+MII_REG ); udelay(50); bits[i] |= inw( ioaddr+MII_REG ) & MII_MDI; } // Return to idle state // Set clock to low, data to low, and output tristated outw( mii_reg, ioaddr+MII_REG ); udelay(50); // Restore original bank select SMC_SELECT_BANK(ioaddr, oldBank); // Recover input data phydata = 0; for (i = 0; i < 16; ++i) { phydata <<= 1; if (bits[input_idx++] & MII_MDI) phydata |= 0x0001; } #if (SMC_DEBUG > 2 ) printf("smc_read_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n", phyaddr, phyreg, phydata); #endif return(phydata); } /*------------------------------------------------------------ . Writes a register to the MII Management serial interface .-------------------------------------------------------------*/ static void smc_write_phy_register(int ioaddr, byte phyaddr, byte phyreg, word phydata) { int oldBank; unsigned int i; word mask; word mii_reg; byte bits[65]; int clk_idx = 0; // 32 consecutive ones on MDO to establish sync for (i = 0; i < 32; ++i) bits[clk_idx++] = MII_MDOE | MII_MDO; // Start code <01> bits[clk_idx++] = MII_MDOE; bits[clk_idx++] = MII_MDOE | MII_MDO; // Write command <01> bits[clk_idx++] = MII_MDOE; bits[clk_idx++] = MII_MDOE | MII_MDO; // Output the PHY address, msb first mask = (byte)0x10; for (i = 0; i < 5; ++i) { if (phyaddr & mask) bits[clk_idx++] = MII_MDOE | MII_MDO; else bits[clk_idx++] = MII_MDOE; // Shift to next lowest bit mask >>= 1; } // Output the phy register number, msb first mask = (byte)0x10; for (i = 0; i < 5; ++i) { if (phyreg & mask) bits[clk_idx++] = MII_MDOE | MII_MDO; else bits[clk_idx++] = MII_MDOE; // Shift to next lowest bit mask >>= 1; } // Tristate and turnaround (2 bit times) bits[clk_idx++] = 0; bits[clk_idx++] = 0; // Write out 16 bits of data, msb first mask = 0x8000; for (i = 0; i < 16; ++i) { if (phydata & mask) bits[clk_idx++] = MII_MDOE | MII_MDO; else bits[clk_idx++] = MII_MDOE; // Shift to next lowest bit mask >>= 1; } // Final clock bit (tristate) bits[clk_idx++] = 0; // Save the current bank oldBank = inw( ioaddr+BANK_SELECT ); // Select bank 3 SMC_SELECT_BANK(ioaddr, 3); // Get the current MII register value mii_reg = inw( ioaddr+MII_REG ); // Turn off all MII Interface bits mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO); // Clock all cycles for (i = 0; i < sizeof(bits); ++i) { // Clock Low - output data outw( mii_reg | bits[i], ioaddr+MII_REG ); udelay(50); // Clock Hi - input data outw( mii_reg | bits[i] | MII_MCLK, ioaddr+MII_REG ); udelay(50); bits[i] |= inw( ioaddr+MII_REG ) & MII_MDI; } // Return to idle state // Set clock to low, data to low, and output tristated outw( mii_reg, ioaddr+MII_REG ); udelay(50); // Restore original bank select SMC_SELECT_BANK(ioaddr, oldBank); #if (SMC_DEBUG > 2 ) printf("smc_write_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n", phyaddr, phyreg, phydata); #endif } /*------------------------------------------------------------ . Finds and reports the PHY address .-------------------------------------------------------------*/ static int smc_detect_phy(int ioaddr, byte *pphyaddr) { word phy_id1; word phy_id2; int phyaddr; int found = 0; // Scan all 32 PHY addresses if necessary for (phyaddr = 0; phyaddr < 32; ++phyaddr) { // Read the PHY identifiers phy_id1 = smc_read_phy_register(ioaddr, phyaddr, PHY_ID1_REG); phy_id2 = smc_read_phy_register(ioaddr, phyaddr, PHY_ID2_REG); // Make sure it is a valid identifier if ((phy_id2 > 0x0000) && (phy_id2 < 0xffff) && (phy_id1 > 0x0000) && (phy_id1 < 0xffff)) { if ((phy_id1 != 0x8000) && (phy_id2 != 0x8000)) { // Save the PHY's address *pphyaddr = phyaddr; found = 1; break; } } } if (!found) { printf("No PHY found\n"); return(0); } // Set the PHY type if ( (phy_id1 == 0x0016) && ((phy_id2 & 0xFFF0) == 0xF840 ) ) { printf("PHY=LAN83C183 (LAN91C111 Internal)\n"); } if ( (phy_id1 == 0x0282) && ((phy_id2 & 0xFFF0) == 0x1C50) ) { printf("PHY=LAN83C180\n"); } return(1); } /*------------------------------------------------------------ . Configures the specified PHY using Autonegotiation. Calls . smc_phy_fixed() if the user has requested a certain config. .-------------------------------------------------------------*/ static void smc_phy_configure(int ioaddr) { int timeout; byte phyaddr; word my_phy_caps; // My PHY capabilities word my_ad_caps; // My Advertised capabilities word status; int failed = 0; int rpc_cur_mode = RPC_DEFAULT; int lastPhy18; // Find the address and type of our phy if (!smc_detect_phy(ioaddr, &phyaddr)) { return; } // Reset the PHY, setting all other bits to zero smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_RST); // Wait for the reset to complete, or time out timeout = 6; // Wait up to 3 seconds while (timeout--) { if (!(smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG) & PHY_CNTL_RST)) { // reset complete break; } mdelay(500); // wait 500 millisecs } if (timeout < 1) { PRINTK2("PHY reset timed out\n"); return; } // Read PHY Register 18, Status Output lastPhy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG); // Enable PHY Interrupts (for register 18) // Interrupts listed here are disabled smc_write_phy_register(ioaddr, phyaddr, PHY_MASK_REG, PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD | PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB | PHY_INT_SPDDET | PHY_INT_DPLXDET); /* Configure the Receive/Phy Control register */ SMC_SELECT_BANK(ioaddr, 0); outw( rpc_cur_mode, ioaddr + RPC_REG ); // Copy our capabilities from PHY_STAT_REG to PHY_AD_REG my_phy_caps = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG); my_ad_caps = PHY_AD_CSMA; // I am CSMA capable if (my_phy_caps & PHY_STAT_CAP_T4) my_ad_caps |= PHY_AD_T4; if (my_phy_caps & PHY_STAT_CAP_TXF) my_ad_caps |= PHY_AD_TX_FDX; if (my_phy_caps & PHY_STAT_CAP_TXH) my_ad_caps |= PHY_AD_TX_HDX; if (my_phy_caps & PHY_STAT_CAP_TF) my_ad_caps |= PHY_AD_10_FDX; if (my_phy_caps & PHY_STAT_CAP_TH) my_ad_caps |= PHY_AD_10_HDX; // Update our Auto-Neg Advertisement Register smc_write_phy_register(ioaddr, phyaddr, PHY_AD_REG, my_ad_caps); PRINTK2("phy caps=%x\n", my_phy_caps); PRINTK2("phy advertised caps=%x\n", my_ad_caps); // Restart auto-negotiation process in order to advertise my caps smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST ); // Wait for the auto-negotiation to complete. This may take from // 2 to 3 seconds. // Wait for the reset to complete, or time out timeout = 20; // Wait up to 10 seconds while (timeout--) { status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG); if (status & PHY_STAT_ANEG_ACK) { // auto-negotiate complete break; } mdelay(500); // wait 500 millisecs // Restart auto-negotiation if remote fault if (status & PHY_STAT_REM_FLT) { PRINTK2("PHY remote fault detected\n"); // Restart auto-negotiation PRINTK2("PHY restarting auto-negotiation\n"); smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST | PHY_CNTL_SPEED | PHY_CNTL_DPLX); } } if (timeout < 1) { PRINTK2("PHY auto-negotiate timed out\n"); failed = 1; } // Fail if we detected an auto-negotiate remote fault if (status & PHY_STAT_REM_FLT) { PRINTK2("PHY remote fault detected\n"); failed = 1; } // Set our sysctl parameters to match auto-negotiation results if ( lastPhy18 & PHY_INT_SPDDET ) { PRINTK2("PHY 100BaseT\n"); rpc_cur_mode |= RPC_SPEED; } else { PRINTK2("PHY 10BaseT\n"); rpc_cur_mode &= ~RPC_SPEED; } if ( lastPhy18 & PHY_INT_DPLXDET ) { PRINTK2("PHY Full Duplex\n"); rpc_cur_mode |= RPC_DPLX; } else { PRINTK2("PHY Half Duplex\n"); rpc_cur_mode &= ~RPC_DPLX; } // Re-Configure the Receive/Phy Control register outw( rpc_cur_mode, ioaddr + RPC_REG ); } /* * Function: smc_reset( int ioaddr ) * Purpose: * This sets the SMC91xx chip to its normal state, hopefully from whatever * mess that any other DOS driver has put it in. * * Maybe I should reset more registers to defaults in here? SOFTRESET should * do that for me. * * Method: * 1. send a SOFT RESET * 2. wait for it to finish * 3. reset the memory management unit * 4. clear all interrupts * */ static void smc_reset(int ioaddr) { /* This resets the registers mostly to defaults, but doesn't * affect EEPROM. That seems unnecessary */ SMC_SELECT_BANK(ioaddr, 0); _outw( RCR_SOFTRESET, ioaddr + RCR ); /* this should pause enough for the chip to be happy */ SMC_DELAY(ioaddr); /* Set the transmit and receive configuration registers to * default values */ _outw(RCR_CLEAR, ioaddr + RCR); _outw(TCR_CLEAR, ioaddr + TCR); /* Reset the MMU */ SMC_SELECT_BANK(ioaddr, 2); _outw( MC_RESET, ioaddr + MMU_CMD ); /* Note: It doesn't seem that waiting for the MMU busy is needed here, * but this is a place where future chipsets _COULD_ break. Be wary * of issuing another MMU command right after this */ _outb(0, ioaddr + INT_MASK); } /*---------------------------------------------------------------------- * Function: smc9000_probe_addr( int ioaddr ) * * Purpose: * Tests to see if a given ioaddr points to an SMC9xxx chip. * Returns a 1 on success * * Algorithm: * (1) see if the high byte of BANK_SELECT is 0x33 * (2) compare the ioaddr with the base register's address * (3) see if I recognize the chip ID in the appropriate register * * --------------------------------------------------------------------- */ static int smc9000_probe_addr( isa_probe_addr_t ioaddr ) { word bank; word revision_register; word base_address_register; /* First, see if the high byte is 0x33 */ bank = inw(ioaddr + BANK_SELECT); if ((bank & 0xFF00) != 0x3300) { return 0; } /* The above MIGHT indicate a device, but I need to write to further * test this. */ _outw(0x0, ioaddr + BANK_SELECT); bank = inw(ioaddr + BANK_SELECT); if ((bank & 0xFF00) != 0x3300) { return 0; } /* well, we've already written once, so hopefully another time won't * hurt. This time, I need to switch the bank register to bank 1, * so I can access the base address register */ SMC_SELECT_BANK(ioaddr, 1); base_address_register = inw(ioaddr + BASE); if (ioaddr != (base_address_register >> 3 & 0x3E0)) { DBG("SMC9000: IOADDR %hX doesn't match configuration (%hX)." "Probably not a SMC chip\n", ioaddr, base_address_register >> 3 & 0x3E0); /* well, the base address register didn't match. Must not have * been a SMC chip after all. */ return 0; } /* check if the revision register is something that I recognize. * These might need to be added to later, as future revisions * could be added. */ SMC_SELECT_BANK(ioaddr, 3); revision_register = inw(ioaddr + REVISION); if (!chip_ids[(revision_register >> 4) & 0xF]) { /* I don't recognize this chip, so... */ DBG( "SMC9000: IO %hX: Unrecognized revision register:" " %hX, Contact author.\n", ioaddr, revision_register ); return 0; } /* at this point I'll assume that the chip is an SMC9xxx. * It might be prudent to check a listing of MAC addresses * against the hardware address, or do some other tests. */ return 1; } /************************************************************************** * ETH_TRANSMIT - Transmit a frame ***************************************************************************/ static void smc9000_transmit( struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) /* Packet */ { word length; /* real, length incl. header */ word numPages; unsigned long time_out; byte packet_no; word status; int i; /* We dont pad here since we can have the hardware doing it for us */ length = (s + ETH_HLEN + 1)&~1; /* convert to MMU pages */ numPages = length / 256; if (numPages > 7 ) { DBG("SMC9000: Far too big packet error. \n"); return; } /* dont try more than, say 30 times */ for (i=0;i<30;i++) { /* now, try to allocate the memory */ SMC_SELECT_BANK(nic->ioaddr, 2); _outw(MC_ALLOC | numPages, nic->ioaddr + MMU_CMD); status = 0; /* wait for the memory allocation to finnish */ for (time_out = currticks() + 5*TICKS_PER_SEC; currticks() < time_out; ) { status = inb(nic->ioaddr + INTERRUPT); if ( status & IM_ALLOC_INT ) { /* acknowledge the interrupt */ _outb(IM_ALLOC_INT, nic->ioaddr + INTERRUPT); break; } } if ((status & IM_ALLOC_INT) != 0 ) { /* We've got the memory */ break; } else { printf("SMC9000: Memory allocation timed out, resetting MMU.\n"); _outw(MC_RESET, nic->ioaddr + MMU_CMD); } } /* If I get here, I _know_ there is a packet slot waiting for me */ packet_no = inb(nic->ioaddr + PNR_ARR + 1); if (packet_no & 0x80) { /* or isn't there? BAD CHIP! */ printf("SMC9000: Memory allocation failed. \n"); return; } /* we have a packet address, so tell the card to use it */ _outb(packet_no, nic->ioaddr + PNR_ARR); /* point to the beginning of the packet */ _outw(PTR_AUTOINC, nic->ioaddr + POINTER); #if SMC9000_DEBUG > 2 printf("Trying to xmit packet of length %hX\n", length ); #endif /* send the packet length ( +6 for status, length and ctl byte ) * and the status word ( set to zeros ) */ _outw(0, nic->ioaddr + DATA_1 ); /* send the packet length ( +6 for status words, length, and ctl) */ _outb((length+6) & 0xFF, nic->ioaddr + DATA_1); _outb((length+6) >> 8 , nic->ioaddr + DATA_1); /* Write the contents of the packet */ /* The ethernet header first... */ outsw(nic->ioaddr + DATA_1, d, ETH_ALEN >> 1); outsw(nic->ioaddr + DATA_1, nic->node_addr, ETH_ALEN >> 1); _outw(htons(t), nic->ioaddr + DATA_1); /* ... the data ... */ outsw(nic->ioaddr + DATA_1 , p, s >> 1); /* ... and the last byte, if there is one. */ if ((s & 1) == 0) { _outw(0, nic->ioaddr + DATA_1); } else { _outb(p[s-1], nic->ioaddr + DATA_1); _outb(0x20, nic->ioaddr + DATA_1); } /* and let the chipset deal with it */ _outw(MC_ENQUEUE , nic->ioaddr + MMU_CMD); status = 0; time_out = currticks() + 5*TICKS_PER_SEC; do { status = inb(nic->ioaddr + INTERRUPT); if ((status & IM_TX_INT ) != 0) { word tx_status; /* ack interrupt */ _outb(IM_TX_INT, nic->ioaddr + INTERRUPT); packet_no = inw(nic->ioaddr + FIFO_PORTS); packet_no &= 0x7F; /* select this as the packet to read from */ _outb( packet_no, nic->ioaddr + PNR_ARR ); /* read the first word from this packet */ _outw( PTR_AUTOINC | PTR_READ, nic->ioaddr + POINTER ); tx_status = inw( nic->ioaddr + DATA_1 ); if (0 == (tx_status & TS_SUCCESS)) { DBG("SMC9000: TX FAIL STATUS: %hX \n", tx_status); /* re-enable transmit */ SMC_SELECT_BANK(nic->ioaddr, 0); _outw(inw(nic->ioaddr + TCR ) | TCR_ENABLE, nic->ioaddr + TCR ); } /* kill the packet */ SMC_SELECT_BANK(nic->ioaddr, 2); _outw(MC_FREEPKT, nic->ioaddr + MMU_CMD); return; } }while(currticks() < time_out); printf("SMC9000: TX timed out, resetting board\n"); smc_reset(nic->ioaddr); return; } /************************************************************************** * ETH_POLL - Wait for a frame ***************************************************************************/ static int smc9000_poll(struct nic *nic, int retrieve) { SMC_SELECT_BANK(nic->ioaddr, 2); if (inw(nic->ioaddr + FIFO_PORTS) & FP_RXEMPTY) return 0; if ( ! retrieve ) return 1; /* start reading from the start of the packet */ _outw(PTR_READ | PTR_RCV | PTR_AUTOINC, nic->ioaddr + POINTER); /* First read the status and check that we're ok */ if (!(inw(nic->ioaddr + DATA_1) & RS_ERRORS)) { /* Next: read the packet length and mask off the top bits */ nic->packetlen = (inw(nic->ioaddr + DATA_1) & 0x07ff); /* the packet length includes the 3 extra words */ nic->packetlen -= 6; #if SMC9000_DEBUG > 2 printf(" Reading %d words (and %d byte(s))\n", (nic->packetlen >> 1), nic->packetlen & 1); #endif /* read the packet (and the last "extra" word) */ insw(nic->ioaddr + DATA_1, nic->packet, (nic->packetlen+2) >> 1); /* is there an odd last byte ? */ if (nic->packet[nic->packetlen+1] & 0x20) nic->packetlen++; /* error or good, tell the card to get rid of this packet */ _outw(MC_RELEASE, nic->ioaddr + MMU_CMD); return 1; } printf("SMC9000: RX error\n"); /* error or good, tell the card to get rid of this packet */ _outw(MC_RELEASE, nic->ioaddr + MMU_CMD); return 0; } static void smc9000_disable ( struct nic *nic, struct isa_device *isa __unused ) { smc_reset(nic->ioaddr); /* no more interrupts for me */ SMC_SELECT_BANK(nic->ioaddr, 2); _outb( 0, nic->ioaddr + INT_MASK); /* and tell the card to stay away from that nasty outside world */ SMC_SELECT_BANK(nic->ioaddr, 0); _outb( RCR_CLEAR, nic->ioaddr + RCR ); _outb( TCR_CLEAR, nic->ioaddr + TCR ); } static void smc9000_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } static struct nic_operations smc9000_operations = { .connect = dummy_connect, .poll = smc9000_poll, .transmit = smc9000_transmit, .irq = smc9000_irq, }; /************************************************************************** * ETH_PROBE - Look for an adapter ***************************************************************************/ static int smc9000_probe ( struct nic *nic, struct isa_device *isa ) { unsigned short revision; int memory; int media; const char * version_string; const char * if_string; int i; nic->irqno = 0; nic->ioaddr = isa->ioaddr; /* * Get the MAC address ( bank 1, regs 4 - 9 ) */ SMC_SELECT_BANK(nic->ioaddr, 1); for ( i = 0; i < 6; i += 2 ) { word address; address = inw(nic->ioaddr + ADDR0 + i); nic->node_addr[i+1] = address >> 8; nic->node_addr[i] = address & 0xFF; } /* get the memory information */ SMC_SELECT_BANK(nic->ioaddr, 0); memory = ( inw(nic->ioaddr + MCR) >> 9 ) & 0x7; /* multiplier */ memory *= 256 * (inw(nic->ioaddr + MIR) & 0xFF); /* * Now, I want to find out more about the chip. This is sort of * redundant, but it's cleaner to have it in both, rather than having * one VERY long probe procedure. */ SMC_SELECT_BANK(nic->ioaddr, 3); revision = inw(nic->ioaddr + REVISION); version_string = chip_ids[(revision >> 4) & 0xF]; if (((revision & 0xF0) >> 4 == CHIP_9196) && ((revision & 0x0F) >= REV_9196)) { /* This is a 91c96. 'c96 has the same chip id as 'c94 (4) but * a revision starting at 6 */ version_string = smc91c96_id; } if ( !version_string ) { /* I shouldn't get here because this call was done before.... */ return 0; } /* is it using AUI or 10BaseT ? */ SMC_SELECT_BANK(nic->ioaddr, 1); if (inw(nic->ioaddr + CONFIG) & CFG_AUI_SELECT) media = 2; else media = 1; if_string = interfaces[media - 1]; /* now, reset the chip, and put it into a known state */ smc_reset(nic->ioaddr); printf("SMC9000 %s\n", smc9000_version); DBG("Copyright (C) 1998 Daniel Engstr\x94m\n"); DBG("Copyright (C) 1996 Eric Stahlman\n"); printf("%s rev:%d I/O port:%hX Interface:%s RAM:%d bytes \n", version_string, revision & 0xF, nic->ioaddr, if_string, memory ); DBG ( "Ethernet MAC address: %s\n", eth_ntoa ( nic->node_addr ) ); SMC_SELECT_BANK(nic->ioaddr, 0); /* see the header file for options in TCR/RCR NORMAL*/ _outw(TCR_NORMAL, nic->ioaddr + TCR); _outw(RCR_NORMAL, nic->ioaddr + RCR); /* Select which interface to use */ SMC_SELECT_BANK(nic->ioaddr, 1); if ( media == 1 ) { _outw( inw( nic->ioaddr + CONFIG ) & ~CFG_AUI_SELECT, nic->ioaddr + CONFIG ); } else if ( media == 2 ) { _outw( inw( nic->ioaddr + CONFIG ) | CFG_AUI_SELECT, nic->ioaddr + CONFIG ); } smc_phy_configure(nic->ioaddr); nic->nic_op = &smc9000_operations; return 1; } /* * The SMC9000 can be at any of the following port addresses. To * change for a slightly different card, you can add it to the array. * */ static isa_probe_addr_t smc9000_probe_addrs[] = { 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, }; ISA_DRIVER ( smc9000_driver, smc9000_probe_addrs, smc9000_probe_addr, GENERIC_ISAPNP_VENDOR, 0x8228 ); DRIVER ( "SMC9000", nic_driver, isa_driver, smc9000_driver, smc9000_probe, smc9000_disable ); ISA_ROM ( "smc9000", "SMC9000" ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/tlan.h0000664000000000000000000003234112524662415020321 0ustar /************************************************************************** * * tlan.c -- Etherboot device driver for the Texas Instruments ThunderLAN * Written 2003-2003 by Timothy Legge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Portions of this code (almost all) based on: * tlan.c: Linux ThunderLan Driver: * * by James Banks * * (C) 1997-1998 Caldera, Inc. * (C) 1998 James Banks * (C) 1999-2001 Torben Mathiasen * (C) 2002 Samuel Chessman * * REVISION HISTORY: * ================ * v1.0 07-08-2003 timlegge Initial not quite working version * * Indent Style: indent -kr -i8 ***************************************************************************/ FILE_LICENCE ( GPL2_OR_LATER ); /***************************************************************** * TLan Definitions * ****************************************************************/ #define FALSE 0 #define TRUE 1 #define TLAN_MIN_FRAME_SIZE 64 #define TLAN_MAX_FRAME_SIZE 1600 #define TLAN_NUM_RX_LISTS 4 #define TLAN_NUM_TX_LISTS 2 #define TLAN_IGNORE 0 #define TLAN_RECORD 1 /* #define TLAN_DBG(lvl, format, args...) if (debug&lvl) printf("TLAN: " format, ##args ); */ #define TLAN_DEBUG_GNRL 0x0001 #define TLAN_DEBUG_TX 0x0002 #define TLAN_DEBUG_RX 0x0004 #define TLAN_DEBUG_LIST 0x0008 #define TLAN_DEBUG_PROBE 0x0010 #define TX_TIMEOUT (10*HZ) /* We need time for auto-neg */ #define MAX_TLAN_BOARDS 8 /* Max number of boards installed at a time */ /***************************************************************** * Device Identification Definitions * ****************************************************************/ #define PCI_DEVICE_ID_NETELLIGENT_10_T2 0xB012 #define PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100 0xB030 #ifndef PCI_DEVICE_ID_OLICOM_OC2183 #define PCI_DEVICE_ID_OLICOM_OC2183 0x0013 #endif #ifndef PCI_DEVICE_ID_OLICOM_OC2325 #define PCI_DEVICE_ID_OLICOM_OC2325 0x0012 #endif #ifndef PCI_DEVICE_ID_OLICOM_OC2326 #define PCI_DEVICE_ID_OLICOM_OC2326 0x0014 #endif typedef struct tlan_adapter_entry { u16 vendorId; u16 deviceId; char *deviceLabel; u32 flags; u16 addrOfs; } TLanAdapterEntry; #define TLAN_ADAPTER_NONE 0x00000000 #define TLAN_ADAPTER_UNMANAGED_PHY 0x00000001 #define TLAN_ADAPTER_BIT_RATE_PHY 0x00000002 #define TLAN_ADAPTER_USE_INTERN_10 0x00000004 #define TLAN_ADAPTER_ACTIVITY_LED 0x00000008 #define TLAN_SPEED_DEFAULT 0 #define TLAN_SPEED_10 10 #define TLAN_SPEED_100 100 #define TLAN_DUPLEX_DEFAULT 0 #define TLAN_DUPLEX_HALF 1 #define TLAN_DUPLEX_FULL 2 /***************************************************************** * EISA Definitions * ****************************************************************/ #define EISA_ID 0xc80 /* EISA ID Registers */ #define EISA_ID0 0xc80 /* EISA ID Register 0 */ #define EISA_ID1 0xc81 /* EISA ID Register 1 */ #define EISA_ID2 0xc82 /* EISA ID Register 2 */ #define EISA_ID3 0xc83 /* EISA ID Register 3 */ #define EISA_CR 0xc84 /* EISA Control Register */ #define EISA_REG0 0xc88 /* EISA Configuration Register 0 */ #define EISA_REG1 0xc89 /* EISA Configuration Register 1 */ #define EISA_REG2 0xc8a /* EISA Configuration Register 2 */ #define EISA_REG3 0xc8f /* EISA Configuration Register 3 */ #define EISA_APROM 0xc90 /* Ethernet Address PROM */ /***************************************************************** * Rx/Tx List Definitions * ****************************************************************/ #define TLAN_BUFFERS_PER_LIST 10 #define TLAN_LAST_BUFFER 0x80000000 #define TLAN_CSTAT_UNUSED 0x8000 #define TLAN_CSTAT_FRM_CMP 0x4000 #define TLAN_CSTAT_READY 0x3000 #define TLAN_CSTAT_EOC 0x0800 #define TLAN_CSTAT_RX_ERROR 0x0400 #define TLAN_CSTAT_PASS_CRC 0x0200 #define TLAN_CSTAT_DP_PR 0x0100 /***************************************************************** * PHY definitions * ****************************************************************/ #define TLAN_PHY_MAX_ADDR 0x1F #define TLAN_PHY_NONE 0x20 /***************************************************************** * TLan Driver Timer Definitions * ****************************************************************/ #define TLAN_TIMER_LINK_BEAT 1 #define TLAN_TIMER_ACTIVITY 2 #define TLAN_TIMER_PHY_PDOWN 3 #define TLAN_TIMER_PHY_PUP 4 #define TLAN_TIMER_PHY_RESET 5 #define TLAN_TIMER_PHY_START_LINK 6 #define TLAN_TIMER_PHY_FINISH_AN 7 #define TLAN_TIMER_FINISH_RESET 8 #define TLAN_TIMER_ACT_DELAY (HZ/10) /***************************************************************** * TLan Driver Eeprom Definitions * ****************************************************************/ #define TLAN_EEPROM_ACK 0 #define TLAN_EEPROM_STOP 1 /***************************************************************** * Host Register Offsets and Contents * ****************************************************************/ #define TLAN_HOST_CMD 0x00 #define TLAN_HC_GO 0x80000000 #define TLAN_HC_STOP 0x40000000 #define TLAN_HC_ACK 0x20000000 #define TLAN_HC_CS_MASK 0x1FE00000 #define TLAN_HC_EOC 0x00100000 #define TLAN_HC_RT 0x00080000 #define TLAN_HC_NES 0x00040000 #define TLAN_HC_AD_RST 0x00008000 #define TLAN_HC_LD_TMR 0x00004000 #define TLAN_HC_LD_THR 0x00002000 #define TLAN_HC_REQ_INT 0x00001000 #define TLAN_HC_INT_OFF 0x00000800 #define TLAN_HC_INT_ON 0x00000400 #define TLAN_HC_AC_MASK 0x000000FF #define TLAN_CH_PARM 0x04 #define TLAN_DIO_ADR 0x08 #define TLAN_DA_ADR_INC 0x8000 #define TLAN_DA_RAM_ADR 0x4000 #define TLAN_HOST_INT 0x0A #define TLAN_HI_IV_MASK 0x1FE0 #define TLAN_HI_IT_MASK 0x001C #define TLAN_DIO_DATA 0x0C /* ThunderLAN Internal Register DIO Offsets */ #define TLAN_NET_CMD 0x00 #define TLAN_NET_CMD_NRESET 0x80 #define TLAN_NET_CMD_NWRAP 0x40 #define TLAN_NET_CMD_CSF 0x20 #define TLAN_NET_CMD_CAF 0x10 #define TLAN_NET_CMD_NOBRX 0x08 #define TLAN_NET_CMD_DUPLEX 0x04 #define TLAN_NET_CMD_TRFRAM 0x02 #define TLAN_NET_CMD_TXPACE 0x01 #define TLAN_NET_SIO 0x01 #define TLAN_NET_SIO_MINTEN 0x80 #define TLAN_NET_SIO_ECLOK 0x40 #define TLAN_NET_SIO_ETXEN 0x20 #define TLAN_NET_SIO_EDATA 0x10 #define TLAN_NET_SIO_NMRST 0x08 #define TLAN_NET_SIO_MCLK 0x04 #define TLAN_NET_SIO_MTXEN 0x02 #define TLAN_NET_SIO_MDATA 0x01 #define TLAN_NET_STS 0x02 #define TLAN_NET_STS_MIRQ 0x80 #define TLAN_NET_STS_HBEAT 0x40 #define TLAN_NET_STS_TXSTOP 0x20 #define TLAN_NET_STS_RXSTOP 0x10 #define TLAN_NET_STS_RSRVD 0x0F #define TLAN_NET_MASK 0x03 #define TLAN_NET_MASK_MASK7 0x80 #define TLAN_NET_MASK_MASK6 0x40 #define TLAN_NET_MASK_MASK5 0x20 #define TLAN_NET_MASK_MASK4 0x10 #define TLAN_NET_MASK_RSRVD 0x0F #define TLAN_NET_CONFIG 0x04 #define TLAN_NET_CFG_RCLK 0x8000 #define TLAN_NET_CFG_TCLK 0x4000 #define TLAN_NET_CFG_BIT 0x2000 #define TLAN_NET_CFG_RXCRC 0x1000 #define TLAN_NET_CFG_PEF 0x0800 #define TLAN_NET_CFG_1FRAG 0x0400 #define TLAN_NET_CFG_1CHAN 0x0200 #define TLAN_NET_CFG_MTEST 0x0100 #define TLAN_NET_CFG_PHY_EN 0x0080 #define TLAN_NET_CFG_MSMASK 0x007F #define TLAN_MAN_TEST 0x06 #define TLAN_DEF_VENDOR_ID 0x08 #define TLAN_DEF_DEVICE_ID 0x0A #define TLAN_DEF_REVISION 0x0C #define TLAN_DEF_SUBCLASS 0x0D #define TLAN_DEF_MIN_LAT 0x0E #define TLAN_DEF_MAX_LAT 0x0F #define TLAN_AREG_0 0x10 #define TLAN_AREG_1 0x16 #define TLAN_AREG_2 0x1C #define TLAN_AREG_3 0x22 #define TLAN_HASH_1 0x28 #define TLAN_HASH_2 0x2C #define TLAN_GOOD_TX_FRMS 0x30 #define TLAN_TX_UNDERUNS 0x33 #define TLAN_GOOD_RX_FRMS 0x34 #define TLAN_RX_OVERRUNS 0x37 #define TLAN_DEFERRED_TX 0x38 #define TLAN_CRC_ERRORS 0x3A #define TLAN_CODE_ERRORS 0x3B #define TLAN_MULTICOL_FRMS 0x3C #define TLAN_SINGLECOL_FRMS 0x3E #define TLAN_EXCESSCOL_FRMS 0x40 #define TLAN_LATE_COLS 0x41 #define TLAN_CARRIER_LOSS 0x42 #define TLAN_ACOMMIT 0x43 #define TLAN_LED_REG 0x44 #define TLAN_LED_ACT 0x10 #define TLAN_LED_LINK 0x01 #define TLAN_BSIZE_REG 0x45 #define TLAN_MAX_RX 0x46 #define TLAN_INT_DIS 0x48 #define TLAN_ID_TX_EOC 0x04 #define TLAN_ID_RX_EOF 0x02 #define TLAN_ID_RX_EOC 0x01 /* ThunderLAN Interrupt Codes */ #define TLAN_INT_NUMBER_OF_INTS 8 #define TLAN_INT_NONE 0x0000 #define TLAN_INT_TX_EOF 0x0001 #define TLAN_INT_STAT_OVERFLOW 0x0002 #define TLAN_INT_RX_EOF 0x0003 #define TLAN_INT_DUMMY 0x0004 #define TLAN_INT_TX_EOC 0x0005 #define TLAN_INT_STATUS_CHECK 0x0006 #define TLAN_INT_RX_EOC 0x0007 /* ThunderLAN MII Registers */ /* ThunderLAN Specific MII/PHY Registers */ #define TLAN_TLPHY_ID 0x10 #define TLAN_TLPHY_CTL 0x11 #define TLAN_TC_IGLINK 0x8000 #define TLAN_TC_SWAPOL 0x4000 #define TLAN_TC_AUISEL 0x2000 #define TLAN_TC_SQEEN 0x1000 #define TLAN_TC_MTEST 0x0800 #define TLAN_TC_RESERVED 0x07F8 #define TLAN_TC_NFEW 0x0004 #define TLAN_TC_INTEN 0x0002 #define TLAN_TC_TINT 0x0001 #define TLAN_TLPHY_STS 0x12 #define TLAN_TS_MINT 0x8000 #define TLAN_TS_PHOK 0x4000 #define TLAN_TS_POLOK 0x2000 #define TLAN_TS_TPENERGY 0x1000 #define TLAN_TS_RESERVED 0x0FFF #define TLAN_TLPHY_PAR 0x19 #define TLAN_PHY_CIM_STAT 0x0020 #define TLAN_PHY_SPEED_100 0x0040 #define TLAN_PHY_DUPLEX_FULL 0x0080 #define TLAN_PHY_AN_EN_STAT 0x0400 /* National Sem. & Level1 PHY id's */ #define NAT_SEM_ID1 0x2000 #define NAT_SEM_ID2 0x5C01 #define LEVEL1_ID1 0x7810 #define LEVEL1_ID2 0x0000 #define CIRC_INC( a, b ) if ( ++a >= b ) a = 0 /* Routines to access internal registers. */ static inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); return (inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3))); } /* TLan_DioRead8 */ static inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); return (inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2))); } /* TLan_DioRead16 */ static inline u32 TLan_DioRead32(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); return (inl(base_addr + TLAN_DIO_DATA)); } /* TLan_DioRead32 */ static inline void TLan_DioWrite8(u16 base_addr, u16 internal_addr, u8 data) { outw(internal_addr, base_addr + TLAN_DIO_ADR); outb(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x3)); } static inline void TLan_DioWrite16(u16 base_addr, u16 internal_addr, u16 data) { outw(internal_addr, base_addr + TLAN_DIO_ADR); outw(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2)); } static inline void TLan_DioWrite32(u16 base_addr, u16 internal_addr, u32 data) { outw(internal_addr, base_addr + TLAN_DIO_ADR); outl(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2)); } #if 0 static inline void TLan_ClearBit(u8 bit, u16 port) { outb_p(inb_p(port) & ~bit, port); } static inline int TLan_GetBit(u8 bit, u16 port) { return ((int) (inb_p(port) & bit)); } static inline void TLan_SetBit(u8 bit, u16 port) { outb_p(inb_p(port) | bit, port); } #endif #define TLan_ClearBit( bit, port ) outb_p(inb_p(port) & ~bit, port) #define TLan_GetBit( bit, port ) ((int) (inb_p(port) & bit)) #define TLan_SetBit( bit, port ) outb_p(inb_p(port) | bit, port) #ifdef I_LIKE_A_FAST_HASH_FUNCTION /* given 6 bytes, view them as 8 6-bit numbers and return the XOR of those */ /* the code below is about seven times as fast as the original code */ static inline u32 TLan_HashFunc(u8 * a) { u8 hash; hash = (a[0] ^ a[3]); /* & 077 */ hash ^= ((a[0] ^ a[3]) >> 6); /* & 003 */ hash ^= ((a[1] ^ a[4]) << 2); /* & 074 */ hash ^= ((a[1] ^ a[4]) >> 4); /* & 017 */ hash ^= ((a[2] ^ a[5]) << 4); /* & 060 */ hash ^= ((a[2] ^ a[5]) >> 2); /* & 077 */ return (hash & 077); } #else /* original code */ static inline u32 xor(u32 a, u32 b) { return ((a && !b) || (!a && b)); } #define XOR8( a, b, c, d, e, f, g, h ) xor( a, xor( b, xor( c, xor( d, xor( e, xor( f, xor( g, h ) ) ) ) ) ) ) #define DA( a, bit ) ( ( (u8) a[bit/8] ) & ( (u8) ( 1 << bit%8 ) ) ) static inline u32 TLan_HashFunc(u8 * a) { u32 hash; hash = XOR8(DA(a, 0), DA(a, 6), DA(a, 12), DA(a, 18), DA(a, 24), DA(a, 30), DA(a, 36), DA(a, 42)); hash |= XOR8(DA(a, 1), DA(a, 7), DA(a, 13), DA(a, 19), DA(a, 25), DA(a, 31), DA(a, 37), DA(a, 43)) << 1; hash |= XOR8(DA(a, 2), DA(a, 8), DA(a, 14), DA(a, 20), DA(a, 26), DA(a, 32), DA(a, 38), DA(a, 44)) << 2; hash |= XOR8(DA(a, 3), DA(a, 9), DA(a, 15), DA(a, 21), DA(a, 27), DA(a, 33), DA(a, 39), DA(a, 45)) << 3; hash |= XOR8(DA(a, 4), DA(a, 10), DA(a, 16), DA(a, 22), DA(a, 28), DA(a, 34), DA(a, 40), DA(a, 46)) << 4; hash |= XOR8(DA(a, 5), DA(a, 11), DA(a, 17), DA(a, 23), DA(a, 29), DA(a, 35), DA(a, 41), DA(a, 47)) << 5; return hash; } #endif /* I_LIKE_A_FAST_HASH_FUNCTION */ debian/grub-extras/disabled/gpxe/src/drivers/net/eepro100.c0000664000000000000000000006503112524662415020713 0ustar /* * eepro100.c -- This file implements the eepro100 driver for etherboot. * * * Copyright (C) AW Computer Systems. * written by R.E.Wolff -- R.E.Wolff@BitWizard.nl * * * AW Computer Systems is contributing to the free software community * by paying for this driver and then putting the result under GPL. * * If you need a Linux device driver, please contact BitWizard for a * quote. * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * date version by what * Written: May 29 1997 V0.10 REW Initial revision. * changes: May 31 1997 V0.90 REW Works! * Jun 1 1997 V0.91 REW Cleanup * Jun 2 1997 V0.92 REW Add some code documentation * Jul 25 1997 V1.00 REW Tested by AW to work in a PROM * Cleanup for publication * Dez 11 2004 V1.10 Kiszka Add RX ring buffer support * * This is the etherboot intel etherexpress Pro/100B driver. * * It was written from scratch, with Donald Beckers eepro100.c kernel * driver as a guideline. Mostly the 82557 related definitions and the * lower level routines have been cut-and-pasted into this source. * * The driver was finished before Intel got the NDA out of the closet. * I still don't have the docs. * * * Datasheet is now published and available from * ftp://download.intel.com/design/network/manuals/8255X_OpenSDM.pdf * - Michael Brown * */ FILE_LICENCE ( GPL2_OR_LATER ); /* Philosophy of this driver. * * Probing: * * Using the pci.c functions of the Etherboot code, the 82557 chip is detected. * It is verified that the BIOS initialized everything properly and if * something is missing it is done now. * * * Initialization: * * * The chip is then initialized to "know" its ethernet address, and to * start recieving packets. The Linux driver has a whole transmit and * recieve ring of buffers. This is neat if you need high performance: * you can write the buffers asynchronously to the chip reading the * buffers and transmitting them over the network. Performance is NOT * an issue here. We can boot a 400k kernel in about two * seconds. (Theory: 0.4 seconds). Booting a system is going to take * about half a minute anyway, so getting 10 times closer to the * theoretical limit is going to make a difference of a few percent. */ /* Not totally true: busy networks can cause packet drops due to RX * buffer overflows. Fixed in V1.10 of this driver. [Kiszka] */ /* * * Transmitting and recieving. * * We have only one transmit descriptor. It has two buffer descriptors: * one for the header, and the other for the data. * We have multiple receive buffers (currently: 4). The chip is told to * receive packets and suspend itself once it ran on the last free buffer. * The recieve (poll) routine simply looks at the current recieve buffer, * picks the packet if any, and releases this buffer again (classic ring * buffer concept). This helps to avoid packet drops on busy networks. * * Caveats: * * The Etherboot framework moves the code to the 48k segment from * 0x94000 to 0xa0000. There is just a little room between the end of * this driver and the 0xa0000 address. If you compile in too many * features, this will overflow. * The number under "hex" in the output of size that scrolls by while * compiling should be less than 8000. Maybe even the stack is up there, * so that you need even more headroom. */ /* The etherboot authors seem to dislike the argument ordering in * outb macros that Linux uses. I disklike the confusion that this * has caused even more.... This file uses the Linux argument ordering. */ /* Sorry not us. It's inherited code from FreeBSD. [The authors] */ #include "etherboot.h" #include "nic.h" #include #include static int ioaddr; enum speedo_offsets { SCBStatus = 0, SCBCmd = 2, /* Rx/Command Unit command and status. */ SCBPointer = 4, /* General purpose pointer. */ SCBPort = 8, /* Misc. commands and operands. */ SCBflash = 12, SCBeeprom = 14, /* EEPROM and flash memory control. */ SCBCtrlMDI = 16, /* MDI interface control. */ SCBEarlyRx = 20, /* Early receive byte count. */ }; enum SCBCmdBits { SCBMaskCmdDone=0x8000, SCBMaskRxDone=0x4000, SCBMaskCmdIdle=0x2000, SCBMaskRxSuspend=0x1000, SCBMaskEarlyRx=0x0800, SCBMaskFlowCtl=0x0400, SCBTriggerIntr=0x0200, SCBMaskAll=0x0100, /* The rest are Rx and Tx commands. */ CUStart=0x0010, CUResume=0x0020, CUStatsAddr=0x0040, CUShowStats=0x0050, CUCmdBase=0x0060, /* CU Base address (set to zero) . */ CUDumpStats=0x0070, /* Dump then reset stats counters. */ RxStart=0x0001, RxResume=0x0002, RxAbort=0x0004, RxAddrLoad=0x0006, RxResumeNoResources=0x0007, }; static int do_eeprom_cmd(int cmd, int cmd_len); void hd(void *where, int n); /***********************************************************************/ /* I82557 related defines */ /***********************************************************************/ /* Serial EEPROM section. A "bit" grungy, but we work our way through bit-by-bit :->. */ /* EEPROM_Ctrl bits. */ #define EE_SHIFT_CLK 0x01 /* EEPROM shift clock. */ #define EE_CS 0x02 /* EEPROM chip select. */ #define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ #define EE_DATA_READ 0x08 /* EEPROM chip data out. */ #define EE_WRITE_0 0x4802 #define EE_WRITE_1 0x4806 #define EE_ENB (0x4800 | EE_CS) /* The EEPROM commands include the alway-set leading bit. */ #define EE_READ_CMD 6 /* The SCB accepts the following controls for the Tx and Rx units: */ #define CU_START 0x0010 #define CU_RESUME 0x0020 #define CU_STATSADDR 0x0040 #define CU_SHOWSTATS 0x0050 /* Dump statistics counters. */ #define CU_CMD_BASE 0x0060 /* Base address to add to add CU commands. */ #define CU_DUMPSTATS 0x0070 /* Dump then reset stats counters. */ #define RX_START 0x0001 #define RX_RESUME 0x0002 #define RX_ABORT 0x0004 #define RX_ADDR_LOAD 0x0006 #define RX_RESUMENR 0x0007 #define INT_MASK 0x0100 #define DRVR_INT 0x0200 /* Driver generated interrupt. */ enum phy_chips { NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240, S80C24, PhyUndefined, DP83840A=10, }; /* Commands that can be put in a command list entry. */ enum commands { CmdNOp = 0, CmdIASetup = 1, CmdConfigure = 2, CmdMulticastList = 3, CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7, /* And some extra flags: */ CmdSuspend = 0x4000, /* Suspend after completion. */ CmdIntr = 0x2000, /* Interrupt after completion. */ CmdTxFlex = 0x0008, /* Use "Flexible mode" for CmdTx command. */ }; /* How to wait for the command unit to accept a command. Typically this takes 0 ticks. */ static inline void wait_for_cmd_done(int cmd_ioaddr) { int wait = 0; int delayed_cmd; do if (inb(cmd_ioaddr) == 0) return; while(++wait <= 100); delayed_cmd = inb(cmd_ioaddr); do if (inb(cmd_ioaddr) == 0) break; while(++wait <= 10000); printf("Command %2.2x was not immediately accepted, %d ticks!\n", delayed_cmd, wait); } /* Elements of the dump_statistics block. This block must be lword aligned. */ static struct speedo_stats { u32 tx_good_frames; u32 tx_coll16_errs; u32 tx_late_colls; u32 tx_underruns; u32 tx_lost_carrier; u32 tx_deferred; u32 tx_one_colls; u32 tx_multi_colls; u32 tx_total_colls; u32 rx_good_frames; u32 rx_crc_errs; u32 rx_align_errs; u32 rx_resource_errs; u32 rx_overrun_errs; u32 rx_colls_errs; u32 rx_runt_errs; u32 done_marker; } lstats; /* A speedo3 TX buffer descriptor with two buffers... */ static struct TxFD { volatile s16 status; s16 command; u32 link; /* void * */ u32 tx_desc_addr; /* (almost) Always points to the tx_buf_addr element. */ s32 count; /* # of TBD (=2), Tx start thresh., etc. */ /* This constitutes two "TBD" entries: hdr and data */ u32 tx_buf_addr0; /* void *, header of frame to be transmitted. */ s32 tx_buf_size0; /* Length of Tx hdr. */ u32 tx_buf_addr1; /* void *, data to be transmitted. */ s32 tx_buf_size1; /* Length of Tx data. */ } txfd; struct RxFD { /* Receive frame descriptor. */ volatile s16 status; s16 command; u32 link; /* struct RxFD * */ u32 rx_buf_addr; /* void * */ u16 count; u16 size; char packet[1518]; }; static struct nic_operations eepro100_operations; #define RXFD_COUNT 4 struct { struct RxFD rxfds[RXFD_COUNT]; } eepro100_bufs __shared; #define rxfds eepro100_bufs.rxfds static unsigned int rxfd = 0; static int congenb = 0; /* Enable congestion control in the DP83840. */ static int txfifo = 8; /* Tx FIFO threshold in 4 byte units, 0-15 */ static int rxfifo = 8; /* Rx FIFO threshold, default 32 bytes. */ static int txdmacount = 0; /* Tx DMA burst length, 0-127, default 0. */ static int rxdmacount = 0; /* Rx DMA length, 0 means no preemption. */ /* I don't understand a byte in this structure. It was copied from the * Linux kernel initialization for the eepro100. -- REW */ static struct ConfCmd { s16 status; s16 command; u32 link; unsigned char data[22]; } confcmd = { 0, 0, 0, /* filled in later */ {22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */ 0, 0x2E, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2, 0x80, /* 0x40=Force full-duplex */ 0x3f, 0x05, } }; /***********************************************************************/ /* Locally used functions */ /***********************************************************************/ /* Support function: mdio_write * * This probably writes to the "physical media interface chip". * -- REW */ static int mdio_write(int phy_id, int location, int value) { int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */ outl(0x04000000 | (location<<16) | (phy_id<<21) | value, ioaddr + SCBCtrlMDI); do { udelay(16); val = inl(ioaddr + SCBCtrlMDI); if (--boguscnt < 0) { printf(" mdio_write() timed out with val = %X.\n", val); break; } } while (! (val & 0x10000000)); return val & 0xffff; } /* Support function: mdio_read * * This probably reads a register in the "physical media interface chip". * -- REW */ static int mdio_read(int phy_id, int location) { int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */ outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI); do { udelay(16); val = inl(ioaddr + SCBCtrlMDI); if (--boguscnt < 0) { printf( " mdio_read() timed out with val = %X.\n", val); break; } } while (! (val & 0x10000000)); return val & 0xffff; } /* The fixes for the code were kindly provided by Dragan Stancevic to strictly follow Intel specifications of EEPROM access timing. The publicly available sheet 64486302 (sec. 3.1) specifies 1us access interval for serial EEPROM. However, it looks like that there is an additional requirement dictating larger udelay's in the code below. 2000/05/24 SAW */ static int do_eeprom_cmd(int cmd, int cmd_len) { unsigned retval = 0; long ee_addr = ioaddr + SCBeeprom; outw(EE_ENB, ee_addr); udelay(2); outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2); /* Shift the command bits out. */ do { short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0; outw(dataval, ee_addr); udelay(2); outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2); retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0); } while (--cmd_len >= 0); outw(EE_ENB, ee_addr); udelay(2); /* Terminate the EEPROM access. */ outw(EE_ENB & ~EE_CS, ee_addr); return retval; } #if 0 static inline void whereami (const char *str) { printf ("%s\n", str); sleep (2); } #else #define whereami(s) #endif static void eepro100_irq(struct nic *nic __unused, irq_action_t action) { uint16_t enabled_mask = ( SCBMaskCmdDone | SCBMaskCmdIdle | SCBMaskEarlyRx | SCBMaskFlowCtl ); switch ( action ) { case DISABLE : outw(SCBMaskAll, ioaddr + SCBCmd); break; case ENABLE : outw(enabled_mask, ioaddr + SCBCmd); break; case FORCE : outw(enabled_mask | SCBTriggerIntr, ioaddr + SCBCmd); break; } } /* function: eepro100_transmit * This transmits a packet. * * Arguments: char d[6]: destination ethernet address. * unsigned short t: ethernet protocol type. * unsigned short s: size of the data-part of the packet. * char *p: the data for the packet. * returns: void. */ static void eepro100_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p) { struct eth_hdr { unsigned char dst_addr[ETH_ALEN]; unsigned char src_addr[ETH_ALEN]; unsigned short type; } hdr; unsigned short status; int s1, s2; unsigned long ct; status = inw(ioaddr + SCBStatus); /* Acknowledge all of the current interrupt sources ASAP. */ outw(status & 0xfc00, ioaddr + SCBStatus); #ifdef DEBUG printf ("transmitting type %hX packet (%d bytes). status = %hX, cmd=%hX\n", t, s, status, inw (ioaddr + SCBCmd)); #endif memcpy (&hdr.dst_addr, d, ETH_ALEN); memcpy (&hdr.src_addr, nic->node_addr, ETH_ALEN); hdr.type = htons (t); txfd.status = 0; txfd.command = CmdSuspend | CmdTx | CmdTxFlex; txfd.link = virt_to_bus (&txfd); txfd.count = 0x02208000; txfd.tx_desc_addr = virt_to_bus(&txfd.tx_buf_addr0); txfd.tx_buf_addr0 = virt_to_bus (&hdr); txfd.tx_buf_size0 = sizeof (hdr); txfd.tx_buf_addr1 = virt_to_bus (p); txfd.tx_buf_size1 = s; #ifdef DEBUG printf ("txfd: \n"); hd (&txfd, sizeof (txfd)); #endif outl(virt_to_bus(&txfd), ioaddr + SCBPointer); outb(CU_START, ioaddr + SCBCmd); wait_for_cmd_done(ioaddr + SCBCmd); s1 = inw (ioaddr + SCBStatus); ct = currticks(); /* timeout 10 ms for transmit */ while (!txfd.status && ct + 10*1000) /* Wait */; s2 = inw (ioaddr + SCBStatus); #ifdef DEBUG printf ("s1 = %hX, s2 = %hX.\n", s1, s2); #endif } /* * Sometimes the receiver stops making progress. This routine knows how to * get it going again, without losing packets or being otherwise nasty like * a chip reset would be. Previously the driver had a whole sequence * of if RxSuspended, if it's no buffers do one thing, if it's no resources, * do another, etc. But those things don't really matter. Separate logic * in the ISR provides for allocating buffers--the other half of operation * is just making sure the receiver is active. speedo_rx_soft_reset does that. * This problem with the old, more involved algorithm is shown up under * ping floods on the order of 60K packets/second on a 100Mbps fdx network. */ static void speedo_rx_soft_reset(void) { int i; #ifdef DEBUG printf("reset\n"); #endif wait_for_cmd_done(ioaddr + SCBCmd); /* * Put the hardware into a known state. */ outb(RX_ABORT, ioaddr + SCBCmd); for (i = 0; i < RXFD_COUNT; i++) { rxfds[i].status = 0; rxfds[i].rx_buf_addr = 0xffffffff; rxfds[i].count = 0; rxfds[i].size = 1528; } wait_for_cmd_done(ioaddr + SCBCmd); outl(virt_to_bus(&rxfds[rxfd]), ioaddr + SCBPointer); outb(RX_START, ioaddr + SCBCmd); } /* function: eepro100_poll / eth_poll * This receives a packet from the network. * * Arguments: none * * returns: 1 if a packet was received. * 0 if no packet was received. * side effects: * returns the packet in the array nic->packet. * returns the length of the packet in nic->packetlen. */ static int eepro100_poll(struct nic *nic, int retrieve) { if (rxfds[rxfd].status) { if (!retrieve) return 1; #ifdef DEBUG printf("Got a packet: Len = %d, rxfd = %d.\n", rxfds[rxfd].count & 0x3fff, rxfd); #endif /* First save the data from the rxfd */ nic->packetlen = rxfds[rxfd].count & 0x3fff; memcpy(nic->packet, rxfds[rxfd].packet, nic->packetlen); rxfds[rxfd].status = 0; rxfds[rxfd].command = 0xc000; rxfds[rxfd].rx_buf_addr = 0xFFFFFFFF; rxfds[rxfd].count = 0; rxfds[rxfd].size = 1528; rxfds[(rxfd-1) % RXFD_COUNT].command = 0x0000; rxfd = (rxfd+1) % RXFD_COUNT; #ifdef DEBUG hd (nic->packet, 0x30); #endif /* Acknowledge all conceivable interrupts */ outw(0xff00, ioaddr + SCBStatus); return 1; } /* * The chip may have suspended reception for various reasons. * Check for that, and re-prime it should this be the case. */ switch ((inw(ioaddr + SCBStatus) >> 2) & 0xf) { case 0: /* Idle */ break; case 1: /* Suspended */ case 2: /* No resources (RxFDs) */ case 9: /* Suspended with no more RBDs */ case 10: /* No resources due to no RBDs */ case 12: /* Ready with no RBDs */ speedo_rx_soft_reset(); break; default: /* reserved values */ break; } return 0; } /* function: eepro100_disable * resets the card. This is used to allow Etherboot or Linux * to probe the card again from a "virginal" state.... * Arguments: none * * returns: void. */ static void eepro100_disable ( struct nic *nic __unused ) { /* from eepro100_reset */ outl(0, ioaddr + SCBPort); /* from eepro100_disable */ /* See if this PartialReset solves the problem with interfering with kernel operation after Etherboot hands over. - Ken 20001102 */ outl(2, ioaddr + SCBPort); /* The following is from the Intel e100 driver. * This hopefully solves the problem with hanging hard DOS images. */ /* wait for the reset to take effect */ udelay(20); /* Mask off our interrupt line -- it is unmasked after reset */ { u16 intr_status; /* Disable interrupts on our PCI board by setting the mask bit */ outw(INT_MASK, ioaddr + SCBCmd); intr_status = inw(ioaddr + SCBStatus); /* ack and clear intrs */ outw(intr_status, ioaddr + SCBStatus); inw(ioaddr + SCBStatus); } } /* exported function: eepro100_probe / eth_probe * initializes a card * * side effects: * leaves the ioaddress of the 82557 chip in the variable ioaddr. * leaves the 82557 initialized, and ready to recieve packets. */ static int eepro100_probe ( struct nic *nic, struct pci_device *pci ) { unsigned short sum = 0; int i; int read_cmd, ee_size; int options; int rx_mode; unsigned long ct; /* we cache only the first few words of the EEPROM data be careful not to access beyond this array */ unsigned short eeprom[16]; if (pci->ioaddr == 0) return 0; adjust_pci_device(pci); nic->ioaddr = pci->ioaddr; nic->irqno = pci->irq; ioaddr = nic->ioaddr; if ((do_eeprom_cmd(EE_READ_CMD << 24, 27) & 0xffe0000) == 0xffe0000) { ee_size = 0x100; read_cmd = EE_READ_CMD << 24; } else { ee_size = 0x40; read_cmd = EE_READ_CMD << 22; } for (i = 0, sum = 0; i < ee_size; i++) { unsigned short value = do_eeprom_cmd(read_cmd | (i << 16), 27); if (i < (int)(sizeof(eeprom)/sizeof(eeprom[0]))) eeprom[i] = value; sum += value; } for (i=0;inode_addr[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff; } DBG ( "Ethernet addr: %s\n", eth_ntoa ( nic->node_addr ) ); if (sum != 0xBABA) printf("eepro100: Invalid EEPROM checksum %#hX, " "check settings before activating this device!\n", sum); outl(0, ioaddr + SCBPort); udelay (10000); whereami ("Got eeprom."); /* Base = 0, disable all interrupts */ outl(0, ioaddr + SCBPointer); outw(INT_MASK | RX_ADDR_LOAD, ioaddr + SCBCmd); wait_for_cmd_done(ioaddr + SCBCmd); whereami ("set rx base addr."); outl(virt_to_bus(&lstats), ioaddr + SCBPointer); outb(CU_STATSADDR, ioaddr + SCBCmd); wait_for_cmd_done(ioaddr + SCBCmd); whereami ("set stats addr."); /* INIT RX stuff. */ for (i = 0; i < RXFD_COUNT; i++) { rxfds[i].status = 0x0000; rxfds[i].command = 0x0000; rxfds[i].rx_buf_addr = 0xFFFFFFFF; rxfds[i].count = 0; rxfds[i].size = 1528; rxfds[i].link = virt_to_bus(&rxfds[i+1]); } rxfds[RXFD_COUNT-1].status = 0x0000; rxfds[RXFD_COUNT-1].command = 0xC000; rxfds[RXFD_COUNT-1].link = virt_to_bus(&rxfds[0]); outl(virt_to_bus(&rxfds[0]), ioaddr + SCBPointer); outb(RX_START, ioaddr + SCBCmd); wait_for_cmd_done(ioaddr + SCBCmd); whereami ("started RX process."); /* INIT TX stuff. */ /* Base = 0 */ outl(0, ioaddr + SCBPointer); outb(CU_CMD_BASE, ioaddr + SCBCmd); wait_for_cmd_done(ioaddr + SCBCmd); whereami ("set TX base addr."); txfd.command = (CmdIASetup); txfd.status = 0x0000; txfd.link = virt_to_bus (&confcmd); { char *t = (char *)&txfd.tx_desc_addr; for (i=0;inode_addr[i]; } #ifdef DEBUG printf ("Setup_eaddr:\n"); hd (&txfd, 0x20); #endif /* options = 0x40; */ /* 10mbps half duplex... */ options = 0x00; /* Autosense */ #ifdef PROMISC rx_mode = 3; #elif ALLMULTI rx_mode = 1; #else rx_mode = 0; #endif if ( ((eeprom[6]>>8) & 0x3f) == DP83840 || ((eeprom[6]>>8) & 0x3f) == DP83840A) { int mdi_reg23 = mdio_read(eeprom[6] & 0x1f, 23) | 0x0422; if (congenb) mdi_reg23 |= 0x0100; printf(" DP83840 specific setup, setting register 23 to %hX.\n", mdi_reg23); mdio_write(eeprom[6] & 0x1f, 23, mdi_reg23); } whereami ("Done DP8340 special setup."); if (options != 0) { mdio_write(eeprom[6] & 0x1f, 0, ((options & 0x20) ? 0x2000 : 0) | /* 100mbps? */ ((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */ whereami ("set mdio_register."); } confcmd.command = CmdSuspend | CmdConfigure; confcmd.status = 0x0000; confcmd.link = virt_to_bus (&txfd); confcmd.data[1] = (txfifo << 4) | rxfifo; confcmd.data[4] = rxdmacount; confcmd.data[5] = txdmacount + 0x80; confcmd.data[15] = (rx_mode & 2) ? 0x49: 0x48; confcmd.data[19] = (options & 0x10) ? 0xC0 : 0x80; confcmd.data[21] = (rx_mode & 1) ? 0x0D: 0x05; outl(virt_to_bus(&txfd), ioaddr + SCBPointer); outb(CU_START, ioaddr + SCBCmd); wait_for_cmd_done(ioaddr + SCBCmd); whereami ("started TX thingy (config, iasetup)."); ct = currticks(); while (!txfd.status && ct + 10*1000 < currticks()) /* Wait */; /* Read the status register once to disgard stale data */ mdio_read(eeprom[6] & 0x1f, 1); /* Check to see if the network cable is plugged in. * This allows for faster failure if there is nothing * we can do. */ if (!(mdio_read(eeprom[6] & 0x1f, 1) & (1 << 2))) { printf("Valid link not established\n"); eepro100_disable(nic); return 0; } nic->nic_op = &eepro100_operations; return 1; } /*********************************************************************/ #ifdef DEBUG /* Hexdump a number of bytes from memory... */ void hd (void *where, int n) { int i; while (n > 0) { printf ("%X ", where); for (i=0;i < ( (n>16)?16:n);i++) printf (" %hhX", ((char *)where)[i]); printf ("\n"); n -= 16; where += 16; } } #endif static struct nic_operations eepro100_operations = { .connect = dummy_connect, .poll = eepro100_poll, .transmit = eepro100_transmit, .irq = eepro100_irq, }; static struct pci_device_id eepro100_nics[] = { PCI_ROM(0x8086, 0x1029, "id1029", "Intel EtherExpressPro100 ID1029", 0), PCI_ROM(0x8086, 0x1030, "id1030", "Intel EtherExpressPro100 ID1030", 0), PCI_ROM(0x8086, 0x1031, "82801cam", "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0), PCI_ROM(0x8086, 0x1032, "eepro100-1032", "Intel PRO/100 VE Network Connection", 0), PCI_ROM(0x8086, 0x1033, "eepro100-1033", "Intel PRO/100 VM Network Connection", 0), PCI_ROM(0x8086, 0x1034, "eepro100-1034", "Intel PRO/100 VM Network Connection", 0), PCI_ROM(0x8086, 0x1035, "eepro100-1035", "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0), PCI_ROM(0x8086, 0x1036, "eepro100-1036", "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0), PCI_ROM(0x8086, 0x1037, "eepro100-1037", "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0), PCI_ROM(0x8086, 0x1038, "id1038", "Intel PRO/100 VM Network Connection", 0), PCI_ROM(0x8086, 0x1039, "82562et", "Intel PRO100 VE 82562ET", 0), PCI_ROM(0x8086, 0x103a, "id103a", "Intel Corporation 82559 InBusiness 10/100", 0), PCI_ROM(0x8086, 0x103b, "82562etb", "Intel PRO100 VE 82562ETB", 0), PCI_ROM(0x8086, 0x103c, "eepro100-103c", "Intel PRO/100 VM Network Connection", 0), PCI_ROM(0x8086, 0x103d, "eepro100-103d", "Intel PRO/100 VE Network Connection", 0), PCI_ROM(0x8086, 0x103e, "eepro100-103e", "Intel PRO/100 VM Network Connection", 0), PCI_ROM(0x8086, 0x1051, "prove", "Intel PRO/100 VE Network Connection", 0), PCI_ROM(0x8086, 0x1059, "82551qm", "Intel PRO/100 M Mobile Connection", 0), PCI_ROM(0x8086, 0x1209, "82559er", "Intel EtherExpressPro100 82559ER", 0), PCI_ROM(0x8086, 0x1227, "82865", "Intel 82865 EtherExpress PRO/100A", 0), PCI_ROM(0x8086, 0x1228, "82556", "Intel 82556 EtherExpress PRO/100 Smart", 0), PCI_ROM(0x8086, 0x1229, "eepro100", "Intel EtherExpressPro100", 0), PCI_ROM(0x8086, 0x2449, "82562em", "Intel EtherExpressPro100 82562EM", 0), PCI_ROM(0x8086, 0x2459, "82562-1", "Intel 82562 based Fast Ethernet Connection", 0), PCI_ROM(0x8086, 0x245d, "82562-2", "Intel 82562 based Fast Ethernet Connection", 0), PCI_ROM(0x8086, 0x1050, "82562ez", "Intel 82562EZ Network Connection", 0), PCI_ROM(0x8086, 0x1051, "eepro100-1051", "Intel 82801EB/ER (ICH5/ICH5R) Chipset Ethernet Controller", 0), PCI_ROM(0x8086, 0x1065, "82562-3", "Intel 82562 based Fast Ethernet Connection", 0), PCI_ROM(0x8086, 0x5200, "eepro100-5200", "Intel EtherExpress PRO/100 Intelligent Server", 0), PCI_ROM(0x8086, 0x5201, "eepro100-5201", "Intel EtherExpress PRO/100 Intelligent Server", 0), }; /* Cards with device ids 0x1030 to 0x103F, 0x2449, 0x2459 or 0x245D might need * a workaround for hardware bug on 10 mbit half duplex (see linux driver eepro100.c) * 2003/03/17 gbaum */ PCI_DRIVER ( eepro100_driver, eepro100_nics, PCI_NO_CLASS ); DRIVER ( "EEPRO100", nic_driver, pci_driver, eepro100_driver, eepro100_probe, eepro100_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/mtd80x.c0000664000000000000000000007776412524662415020524 0ustar /************************************************************************** * * mtd80x.c: Etherboot device driver for the mtd80x Ethernet chip. * Written 2004-2004 by Erdem Güven * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Portions of this code based on: * fealnx.c: A Linux device driver for the mtd80x Ethernet chip * Written 1998-2000 by Donald Becker * ***************************************************************************/ FILE_LICENCE ( GPL2_OR_LATER ); /* to get some global routines like printf */ #include "etherboot.h" /* to get the interface to the body of the program */ #include "nic.h" /* to get the PCI support functions, if this is a PCI NIC */ #include #include #include /* Condensed operations for readability. */ #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) #define get_unaligned(ptr) (*(ptr)) /* Operational parameters that are set at compile time. */ /* Keep the ring sizes a power of two for compile efficiency. */ /* The compiler will convert '%'<2^N> into a bit mask. */ /* Making the Tx ring too large decreases the effectiveness of channel */ /* bonding and packet priority. */ /* There are no ill effects from too-large receive rings. */ #define TX_RING_SIZE 2 #define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */ #define RX_RING_SIZE 4 /* Operational parameters that usually are not changed. */ /* Time in jiffies before concluding the transmitter is hung. */ #define HZ 100 #define TX_TIME_OUT (6*HZ) /* Allocation size of Rx buffers with normal sized Ethernet frames. Do not change this value without good reason. This is not a limit, but a way to keep a consistent allocation size among drivers. */ #define PKT_BUF_SZ 1536 /* for different PHY */ enum phy_type_flags { MysonPHY = 1, AhdocPHY = 2, SeeqPHY = 3, MarvellPHY = 4, Myson981 = 5, LevelOnePHY = 6, OtherPHY = 10, }; /* A chip capabilities table*/ enum chip_capability_flags { HAS_MII_XCVR, HAS_CHIP_XCVR, }; #if 0 /* not used */ static struct chip_info { u16 dev_id; int flag; } mtd80x_chips[] = { {0x0800, HAS_MII_XCVR}, {0x0803, HAS_CHIP_XCVR}, {0x0891, HAS_MII_XCVR} }; static int chip_cnt = sizeof( mtd80x_chips ) / sizeof( struct chip_info ); #endif /* Offsets to the Command and Status Registers. */ enum mtd_offsets { PAR0 = 0x0, /* physical address 0-3 */ PAR1 = 0x04, /* physical address 4-5 */ MAR0 = 0x08, /* multicast address 0-3 */ MAR1 = 0x0C, /* multicast address 4-7 */ FAR0 = 0x10, /* flow-control address 0-3 */ FAR1 = 0x14, /* flow-control address 4-5 */ TCRRCR = 0x18, /* receive & transmit configuration */ BCR = 0x1C, /* bus command */ TXPDR = 0x20, /* transmit polling demand */ RXPDR = 0x24, /* receive polling demand */ RXCWP = 0x28, /* receive current word pointer */ TXLBA = 0x2C, /* transmit list base address */ RXLBA = 0x30, /* receive list base address */ ISR = 0x34, /* interrupt status */ IMR = 0x38, /* interrupt mask */ FTH = 0x3C, /* flow control high/low threshold */ MANAGEMENT = 0x40, /* bootrom/eeprom and mii management */ TALLY = 0x44, /* tally counters for crc and mpa */ TSR = 0x48, /* tally counter for transmit status */ BMCRSR = 0x4c, /* basic mode control and status */ PHYIDENTIFIER = 0x50, /* phy identifier */ ANARANLPAR = 0x54, /* auto-negotiation advertisement and link partner ability */ ANEROCR = 0x58, /* auto-negotiation expansion and pci conf. */ BPREMRPSR = 0x5c, /* bypass & receive error mask and phy status */ }; /* Bits in the interrupt status/enable registers. */ /* The bits in the Intr Status/Enable registers, mostly interrupt sources. */ enum intr_status_bits { RFCON = 0x00020000, /* receive flow control xon packet */ RFCOFF = 0x00010000, /* receive flow control xoff packet */ LSCStatus = 0x00008000, /* link status change */ ANCStatus = 0x00004000, /* autonegotiation completed */ FBE = 0x00002000, /* fatal bus error */ FBEMask = 0x00001800, /* mask bit12-11 */ ParityErr = 0x00000000, /* parity error */ TargetErr = 0x00001000, /* target abort */ MasterErr = 0x00000800, /* master error */ TUNF = 0x00000400, /* transmit underflow */ ROVF = 0x00000200, /* receive overflow */ ETI = 0x00000100, /* transmit early int */ ERI = 0x00000080, /* receive early int */ CNTOVF = 0x00000040, /* counter overflow */ RBU = 0x00000020, /* receive buffer unavailable */ TBU = 0x00000010, /* transmit buffer unavilable */ TI = 0x00000008, /* transmit interrupt */ RI = 0x00000004, /* receive interrupt */ RxErr = 0x00000002, /* receive error */ }; /* Bits in the NetworkConfig register. */ enum rx_mode_bits { RxModeMask = 0xe0, AcceptAllPhys = 0x80, /* promiscuous mode */ AcceptBroadcast = 0x40, /* accept broadcast */ AcceptMulticast = 0x20, /* accept mutlicast */ AcceptRunt = 0x08, /* receive runt pkt */ ALP = 0x04, /* receive long pkt */ AcceptErr = 0x02, /* receive error pkt */ AcceptMyPhys = 0x00000000, RxEnable = 0x00000001, RxFlowCtrl = 0x00002000, TxEnable = 0x00040000, TxModeFDX = 0x00100000, TxThreshold = 0x00e00000, PS1000 = 0x00010000, PS10 = 0x00080000, FD = 0x00100000, }; /* Bits in network_desc.status */ enum rx_desc_status_bits { RXOWN = 0x80000000, /* own bit */ FLNGMASK = 0x0fff0000, /* frame length */ FLNGShift = 16, MARSTATUS = 0x00004000, /* multicast address received */ BARSTATUS = 0x00002000, /* broadcast address received */ PHYSTATUS = 0x00001000, /* physical address received */ RXFSD = 0x00000800, /* first descriptor */ RXLSD = 0x00000400, /* last descriptor */ ErrorSummary = 0x80, /* error summary */ RUNT = 0x40, /* runt packet received */ LONG = 0x20, /* long packet received */ FAE = 0x10, /* frame align error */ CRC = 0x08, /* crc error */ RXER = 0x04, /* receive error */ }; enum rx_desc_control_bits { RXIC = 0x00800000, /* interrupt control */ RBSShift = 0, }; enum tx_desc_status_bits { TXOWN = 0x80000000, /* own bit */ JABTO = 0x00004000, /* jabber timeout */ CSL = 0x00002000, /* carrier sense lost */ LC = 0x00001000, /* late collision */ EC = 0x00000800, /* excessive collision */ UDF = 0x00000400, /* fifo underflow */ DFR = 0x00000200, /* deferred */ HF = 0x00000100, /* heartbeat fail */ NCRMask = 0x000000ff, /* collision retry count */ NCRShift = 0, }; enum tx_desc_control_bits { TXIC = 0x80000000, /* interrupt control */ ETIControl = 0x40000000, /* early transmit interrupt */ TXLD = 0x20000000, /* last descriptor */ TXFD = 0x10000000, /* first descriptor */ CRCEnable = 0x08000000, /* crc control */ PADEnable = 0x04000000, /* padding control */ RetryTxLC = 0x02000000, /* retry late collision */ PKTSMask = 0x3ff800, /* packet size bit21-11 */ PKTSShift = 11, TBSMask = 0x000007ff, /* transmit buffer bit 10-0 */ TBSShift = 0, }; /* BootROM/EEPROM/MII Management Register */ #define MASK_MIIR_MII_READ 0x00000000 #define MASK_MIIR_MII_WRITE 0x00000008 #define MASK_MIIR_MII_MDO 0x00000004 #define MASK_MIIR_MII_MDI 0x00000002 #define MASK_MIIR_MII_MDC 0x00000001 /* ST+OP+PHYAD+REGAD+TA */ #define OP_READ 0x6000 /* ST:01+OP:10+PHYAD+REGAD+TA:Z0 */ #define OP_WRITE 0x5002 /* ST:01+OP:01+PHYAD+REGAD+TA:10 */ /* ------------------------------------------------------------------------- */ /* Constants for Myson PHY */ /* ------------------------------------------------------------------------- */ #define MysonPHYID 0xd0000302 /* 89-7-27 add, (begin) */ #define MysonPHYID0 0x0302 #define StatusRegister 18 #define SPEED100 0x0400 // bit10 #define FULLMODE 0x0800 // bit11 /* 89-7-27 add, (end) */ /* ------------------------------------------------------------------------- */ /* Constants for Seeq 80225 PHY */ /* ------------------------------------------------------------------------- */ #define SeeqPHYID0 0x0016 #define MIIRegister18 18 #define SPD_DET_100 0x80 #define DPLX_DET_FULL 0x40 /* ------------------------------------------------------------------------- */ /* Constants for Ahdoc 101 PHY */ /* ------------------------------------------------------------------------- */ #define AhdocPHYID0 0x0022 #define DiagnosticReg 18 #define DPLX_FULL 0x0800 #define Speed_100 0x0400 /* 89/6/13 add, */ /* -------------------------------------------------------------------------- */ /* Constants */ /* -------------------------------------------------------------------------- */ #define MarvellPHYID0 0x0141 #define LevelOnePHYID0 0x0013 #define MII1000BaseTControlReg 9 #define MII1000BaseTStatusReg 10 #define SpecificReg 17 /* for 1000BaseT Control Register */ #define PHYAbletoPerform1000FullDuplex 0x0200 #define PHYAbletoPerform1000HalfDuplex 0x0100 #define PHY1000AbilityMask 0x300 // for phy specific status register, marvell phy. #define SpeedMask 0x0c000 #define Speed_1000M 0x08000 #define Speed_100M 0x4000 #define Speed_10M 0 #define Full_Duplex 0x2000 // 89/12/29 add, for phy specific status register, levelone phy, (begin) #define LXT1000_100M 0x08000 #define LXT1000_1000M 0x0c000 #define LXT1000_Full 0x200 // 89/12/29 add, for phy specific status register, levelone phy, (end) #if 0 /* for 3-in-1 case */ #define PS10 0x00080000 #define FD 0x00100000 #define PS1000 0x00010000 #endif /* for PHY */ #define LinkIsUp 0x0004 #define LinkIsUp2 0x00040000 /* Create a static buffer of size PKT_BUF_SZ for each RX and TX Descriptor. All descriptors point to a part of this buffer */ struct { u8 txb[PKT_BUF_SZ * TX_RING_SIZE] __attribute__ ((aligned(8))); u8 rxb[PKT_BUF_SZ * RX_RING_SIZE] __attribute__ ((aligned(8))); } mtd80x_bufs __shared; #define txb mtd80x_bufs.txb #define rxb mtd80x_bufs.rxb /* The Tulip Rx and Tx buffer descriptors. */ struct mtd_desc { s32 status; s32 control; u32 buffer; u32 next_desc; struct mtd_desc *next_desc_logical; u8* skbuff; u32 reserved1; u32 reserved2; }; struct mtd_private { struct mtd_desc rx_ring[RX_RING_SIZE]; struct mtd_desc tx_ring[TX_RING_SIZE]; /* Frequently used values: keep some adjacent for cache effect. */ int flags; struct pci_dev *pci_dev; unsigned long crvalue; unsigned long bcrvalue; /*unsigned long imrvalue;*/ struct mtd_desc *cur_rx; struct mtd_desc *lack_rxbuf; int really_rx_count; struct mtd_desc *cur_tx; struct mtd_desc *cur_tx_copy; int really_tx_count; int free_tx_count; unsigned int rx_buf_sz; /* Based on MTU+slack. */ /* These values are keep track of the transceiver/media in use. */ unsigned int linkok; unsigned int line_speed; unsigned int duplexmode; unsigned int default_port: 4; /* Last dev->if_port value. */ unsigned int PHYType; /* MII transceiver section. */ int mii_cnt; /* MII device addresses. */ unsigned char phys[1]; /* MII device addresses. */ /*other*/ const char *nic_name; int ioaddr; u16 dev_id; }; static struct mtd_private mtdx; static int mdio_read(struct nic * , int phy_id, int location); static void getlinktype(struct nic * ); static void getlinkstatus(struct nic * ); static void set_rx_mode(struct nic *); /************************************************************************** * init_ring - setup the tx and rx descriptors *************************************************************************/ static void init_ring(struct nic *nic __unused) { int i; mtdx.cur_rx = &mtdx.rx_ring[0]; mtdx.rx_buf_sz = PKT_BUF_SZ; /*mtdx.rx_head_desc = &mtdx.rx_ring[0];*/ /* Initialize all Rx descriptors. */ /* Fill in the Rx buffers. Handle allocation failure gracefully. */ for (i = 0; i < RX_RING_SIZE; i++) { mtdx.rx_ring[i].status = RXOWN; mtdx.rx_ring[i].control = mtdx.rx_buf_sz << RBSShift; mtdx.rx_ring[i].next_desc = virt_to_le32desc(&mtdx.rx_ring[i+1]); mtdx.rx_ring[i].next_desc_logical = &mtdx.rx_ring[i+1]; mtdx.rx_ring[i].buffer = virt_to_le32desc(&rxb[i * PKT_BUF_SZ]); mtdx.rx_ring[i].skbuff = &rxb[i * PKT_BUF_SZ]; } /* Mark the last entry as wrapping the ring. */ mtdx.rx_ring[i-1].next_desc = virt_to_le32desc(&mtdx.rx_ring[0]); mtdx.rx_ring[i-1].next_desc_logical = &mtdx.rx_ring[0]; /* We only use one transmit buffer, but two * descriptors so transmit engines have somewhere * to point should they feel the need */ mtdx.tx_ring[0].status = 0x00000000; mtdx.tx_ring[0].buffer = virt_to_bus(&txb[0]); mtdx.tx_ring[0].next_desc = virt_to_le32desc(&mtdx.tx_ring[1]); /* This descriptor is never used */ mtdx.tx_ring[1].status = 0x00000000; mtdx.tx_ring[1].buffer = 0; /*virt_to_bus(&txb[1]); */ mtdx.tx_ring[1].next_desc = virt_to_le32desc(&mtdx.tx_ring[0]); return; } /************************************************************************** RESET - Reset Adapter ***************************************************************************/ static void mtd_reset( struct nic *nic ) { /* Reset the chip to erase previous misconfiguration. */ outl(0x00000001, mtdx.ioaddr + BCR); init_ring(nic); outl(virt_to_bus(mtdx.rx_ring), mtdx.ioaddr + RXLBA); outl(virt_to_bus(mtdx.tx_ring), mtdx.ioaddr + TXLBA); /* Initialize other registers. */ /* Configure the PCI bus bursts and FIFO thresholds. */ mtdx.bcrvalue = 0x10; /* little-endian, 8 burst length */ mtdx.crvalue = 0xa00; /* rx 128 burst length */ if ( mtdx.dev_id == 0x891 ) { mtdx.bcrvalue |= 0x200; /* set PROG bit */ mtdx.crvalue |= 0x02000000; /* set enhanced bit */ } outl( mtdx.bcrvalue, mtdx.ioaddr + BCR); /* Restart Rx engine if stopped. */ outl(0, mtdx.ioaddr + RXPDR); getlinkstatus(nic); if (mtdx.linkok) { static const char* texts[]={"half","full","10","100","1000"}; getlinktype(nic); DBG ( "Link is OK : %s %s\n", texts[mtdx.duplexmode-1], texts[mtdx.line_speed+1] ); } else { DBG ( "No link!!!\n" ); } mtdx.crvalue |= /*TxEnable |*/ RxEnable | TxThreshold; set_rx_mode(nic); /* Clear interrupts by setting the interrupt mask. */ outl(FBE | TUNF | CNTOVF | RBU | TI | RI, mtdx.ioaddr + ISR); outl( 0, mtdx.ioaddr + IMR); } /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int mtd_poll(struct nic *nic, __unused int retrieve) { s32 rx_status = mtdx.cur_rx->status; int retval = 0; if( ( rx_status & RXOWN ) != 0 ) { return 0; } if (rx_status & ErrorSummary) { /* there was a fatal error */ printf( "%s: Receive error, Rx status %8.8x, Error(s) %s%s%s\n", mtdx.nic_name, (unsigned int) rx_status, (rx_status & (LONG | RUNT)) ? "length_error ":"", (rx_status & RXER) ? "frame_error ":"", (rx_status & CRC) ? "crc_error ":"" ); retval = 0; } else if( !((rx_status & RXFSD) && (rx_status & RXLSD)) ) { /* this pkt is too long, over one rx buffer */ printf("Pkt is too long, over one rx buffer.\n"); retval = 0; } else { /* this received pkt is ok */ /* Omit the four octet CRC from the length. */ short pkt_len = ((rx_status & FLNGMASK) >> FLNGShift) - 4; DBG ( " netdev_rx() normal Rx pkt length %d" " status %x.\n", pkt_len, (unsigned int) rx_status ); nic->packetlen = pkt_len; memcpy(nic->packet, mtdx.cur_rx->skbuff, pkt_len); retval = 1; } while( ( mtdx.cur_rx->status & RXOWN ) == 0 ) { mtdx.cur_rx->status = RXOWN; mtdx.cur_rx = mtdx.cur_rx->next_desc_logical; } /* Restart Rx engine if stopped. */ outl(0, mtdx.ioaddr + RXPDR); return retval; } /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void mtd_transmit( struct nic *nic, const char *dest, /* Destination */ unsigned int type, /* Type */ unsigned int size, /* size */ const char *data) /* Packet */ { u32 to; u32 tx_status; unsigned int nstype = htons ( type ); memcpy( txb, dest, ETH_ALEN ); memcpy( txb + ETH_ALEN, nic->node_addr, ETH_ALEN ); memcpy( txb + 2 * ETH_ALEN, &nstype, 2 ); memcpy( txb + ETH_HLEN, data, size ); size += ETH_HLEN; size &= 0x0FFF; while( size < ETH_ZLEN ) { txb[size++] = '\0'; } mtdx.tx_ring[0].control = TXLD | TXFD | CRCEnable | PADEnable; mtdx.tx_ring[0].control |= (size << PKTSShift); /* pkt size */ mtdx.tx_ring[0].control |= (size << TBSShift); /* buffer size */ mtdx.tx_ring[0].status = TXOWN; /* Point to transmit descriptor */ outl(virt_to_bus(mtdx.tx_ring), mtdx.ioaddr + TXLBA); /* Enable Tx */ outl( mtdx.crvalue | TxEnable, mtdx.ioaddr + TCRRCR); /* Wake the potentially-idle transmit channel. */ outl(0, mtdx.ioaddr + TXPDR); to = currticks() + TX_TIME_OUT; while(( mtdx.tx_ring[0].status & TXOWN) && (currticks() < to)); /* Disable Tx */ outl( mtdx.crvalue & (~TxEnable), mtdx.ioaddr + TCRRCR); tx_status = mtdx.tx_ring[0].status; if (currticks() >= to){ DBG ( "TX Time Out" ); } else if( tx_status & (CSL | LC | EC | UDF | HF)){ printf( "Transmit error: %8.8x %s %s %s %s %s\n", (unsigned int) tx_status, tx_status & EC ? "abort" : "", tx_status & CSL ? "carrier" : "", tx_status & LC ? "late" : "", tx_status & UDF ? "fifo" : "", tx_status & HF ? "heartbeat" : "" ); } /*hex_dump( txb, size );*/ /*pause();*/ DBG ( "TRANSMIT\n" ); } /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void mtd_disable ( struct nic *nic ) { /* Disable Tx Rx*/ outl( mtdx.crvalue & (~TxEnable) & (~RxEnable), mtdx.ioaddr + TCRRCR ); /* Reset the chip to erase previous misconfiguration. */ mtd_reset(nic); DBG ( "DISABLE\n" ); } static struct nic_operations mtd_operations = { .connect = dummy_connect, .poll = mtd_poll, .transmit = mtd_transmit, .irq = dummy_irq, }; static struct pci_device_id mtd80x_nics[] = { PCI_ROM(0x1516, 0x0800, "MTD800", "Myson MTD800", 0), PCI_ROM(0x1516, 0x0803, "MTD803", "Surecom EP-320X", 0), PCI_ROM(0x1516, 0x0891, "MTD891", "Myson MTD891", 0), }; PCI_DRIVER ( mtd80x_driver, mtd80x_nics, PCI_NO_CLASS ); /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside ***************************************************************************/ static int mtd_probe ( struct nic *nic, struct pci_device *pci ) { int i; if (pci->ioaddr == 0) return 0; adjust_pci_device(pci); nic->ioaddr = pci->ioaddr; nic->irqno = 0; mtdx.nic_name = pci->driver_name; mtdx.dev_id = pci->device; mtdx.ioaddr = nic->ioaddr; /* read ethernet id */ for (i = 0; i < 6; ++i) { nic->node_addr[i] = inb(mtdx.ioaddr + PAR0 + i); } if (memcmp(nic->node_addr, "\0\0\0\0\0\0", 6) == 0) { return 0; } DBG ( "%s: ioaddr %4.4x MAC %s\n", mtdx.nic_name, mtdx.ioaddr, eth_ntoa ( nic->node_addr ) ); /* Reset the chip to erase previous misconfiguration. */ outl(0x00000001, mtdx.ioaddr + BCR); /* find the connected MII xcvrs */ if( mtdx.dev_id != 0x803 ) { int phy, phy_idx = 0; for (phy = 1; phy < 32 && phy_idx < 1; phy++) { int mii_status = mdio_read(nic, phy, 1); if (mii_status != 0xffff && mii_status != 0x0000) { mtdx.phys[phy_idx] = phy; DBG ( "%s: MII PHY found at address %d, status " "0x%4.4x.\n", mtdx.nic_name, phy, mii_status ); /* get phy type */ { unsigned int data; data = mdio_read(nic, mtdx.phys[phy_idx], 2); if (data == SeeqPHYID0) mtdx.PHYType = SeeqPHY; else if (data == AhdocPHYID0) mtdx.PHYType = AhdocPHY; else if (data == MarvellPHYID0) mtdx.PHYType = MarvellPHY; else if (data == MysonPHYID0) mtdx.PHYType = Myson981; else if (data == LevelOnePHYID0) mtdx.PHYType = LevelOnePHY; else mtdx.PHYType = OtherPHY; } phy_idx++; } } mtdx.mii_cnt = phy_idx; if (phy_idx == 0) { printf("%s: MII PHY not found -- this device may " "not operate correctly.\n", mtdx.nic_name); } } else { mtdx.phys[0] = 32; /* get phy type */ if (inl(mtdx.ioaddr + PHYIDENTIFIER) == MysonPHYID ) { mtdx.PHYType = MysonPHY; DBG ( "MysonPHY\n" ); } else { mtdx.PHYType = OtherPHY; DBG ( "OtherPHY\n" ); } } getlinkstatus(nic); if( !mtdx.linkok ) { printf("No link!!!\n"); return 0; } mtd_reset( nic ); /* point to NIC specific routines */ nic->nic_op = &mtd_operations; return 1; } /**************************************************************************/ static void set_rx_mode(struct nic *nic __unused) { u32 mc_filter[2]; /* Multicast hash filter */ u32 rx_mode; /* Too many to match, or accept all multicasts. */ mc_filter[1] = mc_filter[0] = ~0; rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; outl(mc_filter[0], mtdx.ioaddr + MAR0); outl(mc_filter[1], mtdx.ioaddr + MAR1); mtdx.crvalue = ( mtdx.crvalue & ~RxModeMask ) | rx_mode; outb( mtdx.crvalue, mtdx.ioaddr + TCRRCR); } /**************************************************************************/ static unsigned int m80x_read_tick(void) /* function: Reads the Timer tick count register which decrements by 2 from */ /* 65536 to 0 every 1/36.414 of a second. Each 2 decrements of the */ /* count represents 838 nsec's. */ /* input : none. */ /* output : none. */ { unsigned char tmp; int value; outb((char) 0x06, 0x43); // Command 8254 to latch T0's count // now read the count. tmp = (unsigned char) inb(0x40); value = ((int) tmp) << 8; tmp = (unsigned char) inb(0x40); value |= (((int) tmp) & 0xff); return (value); } static void m80x_delay(unsigned int interval) /* function: to wait for a specified time. */ /* input : interval ... the specified time. */ /* output : none. */ { unsigned int interval1, interval2, i = 0; interval1 = m80x_read_tick(); // get initial value do { interval2 = m80x_read_tick(); if (interval1 < interval2) interval1 += 65536; ++i; } while (((interval1 - interval2) < (u16) interval) && (i < 65535)); } static u32 m80x_send_cmd_to_phy(long miiport, int opcode, int phyad, int regad) { u32 miir; int i; unsigned int mask, data; /* enable MII output */ miir = (u32) inl(miiport); miir &= 0xfffffff0; miir |= MASK_MIIR_MII_WRITE + MASK_MIIR_MII_MDO; /* send 32 1's preamble */ for (i = 0; i < 32; i++) { /* low MDC; MDO is already high (miir) */ miir &= ~MASK_MIIR_MII_MDC; outl(miir, miiport); /* high MDC */ miir |= MASK_MIIR_MII_MDC; outl(miir, miiport); } /* calculate ST+OP+PHYAD+REGAD+TA */ data = opcode | (phyad << 7) | (regad << 2); /* sent out */ mask = 0x8000; while (mask) { /* low MDC, prepare MDO */ miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO); if (mask & data) miir |= MASK_MIIR_MII_MDO; outl(miir, miiport); /* high MDC */ miir |= MASK_MIIR_MII_MDC; outl(miir, miiport); m80x_delay(30); /* next */ mask >>= 1; if (mask == 0x2 && opcode == OP_READ) miir &= ~MASK_MIIR_MII_WRITE; } return miir; } static int mdio_read(struct nic *nic __unused, int phyad, int regad) { long miiport = mtdx.ioaddr + MANAGEMENT; u32 miir; unsigned int mask, data; miir = m80x_send_cmd_to_phy(miiport, OP_READ, phyad, regad); /* read data */ mask = 0x8000; data = 0; while (mask) { /* low MDC */ miir &= ~MASK_MIIR_MII_MDC; outl(miir, miiport); /* read MDI */ miir = inl(miiport); if (miir & MASK_MIIR_MII_MDI) data |= mask; /* high MDC, and wait */ miir |= MASK_MIIR_MII_MDC; outl(miir, miiport); m80x_delay((int) 30); /* next */ mask >>= 1; } /* low MDC */ miir &= ~MASK_MIIR_MII_MDC; outl(miir, miiport); return data & 0xffff; } #if 0 /* not used */ static void mdio_write(struct nic *nic __unused, int phyad, int regad, int data) { long miiport = mtdx.ioaddr + MANAGEMENT; u32 miir; unsigned int mask; miir = m80x_send_cmd_to_phy(miiport, OP_WRITE, phyad, regad); /* write data */ mask = 0x8000; while (mask) { /* low MDC, prepare MDO */ miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO); if (mask & data) miir |= MASK_MIIR_MII_MDO; outl(miir, miiport); /* high MDC */ miir |= MASK_MIIR_MII_MDC; outl(miir, miiport); /* next */ mask >>= 1; } /* low MDC */ miir &= ~MASK_MIIR_MII_MDC; outl(miir, miiport); return; } #endif static void getlinkstatus(struct nic *nic) /* function: Routine will read MII Status Register to get link status. */ /* input : dev... pointer to the adapter block. */ /* output : none. */ { unsigned int i, DelayTime = 0x1000; mtdx.linkok = 0; if (mtdx.PHYType == MysonPHY) { for (i = 0; i < DelayTime; ++i) { if (inl(mtdx.ioaddr + BMCRSR) & LinkIsUp2) { mtdx.linkok = 1; return; } // delay m80x_delay(100); } } else { for (i = 0; i < DelayTime; ++i) { if (mdio_read(nic, mtdx.phys[0], MII_BMSR) & BMSR_LSTATUS) { mtdx.linkok = 1; return; } // delay m80x_delay(100); } } } static void getlinktype(struct nic *dev) { if (mtdx.PHYType == MysonPHY) { /* 3-in-1 case */ if (inl(mtdx.ioaddr + TCRRCR) & FD) mtdx.duplexmode = 2; /* full duplex */ else mtdx.duplexmode = 1; /* half duplex */ if (inl(mtdx.ioaddr + TCRRCR) & PS10) mtdx.line_speed = 1; /* 10M */ else mtdx.line_speed = 2; /* 100M */ } else { if (mtdx.PHYType == SeeqPHY) { /* this PHY is SEEQ 80225 */ unsigned int data; data = mdio_read(dev, mtdx.phys[0], MIIRegister18); if (data & SPD_DET_100) mtdx.line_speed = 2; /* 100M */ else mtdx.line_speed = 1; /* 10M */ if (data & DPLX_DET_FULL) mtdx.duplexmode = 2; /* full duplex mode */ else mtdx.duplexmode = 1; /* half duplex mode */ } else if (mtdx.PHYType == AhdocPHY) { unsigned int data; data = mdio_read(dev, mtdx.phys[0], DiagnosticReg); if (data & Speed_100) mtdx.line_speed = 2; /* 100M */ else mtdx.line_speed = 1; /* 10M */ if (data & DPLX_FULL) mtdx.duplexmode = 2; /* full duplex mode */ else mtdx.duplexmode = 1; /* half duplex mode */ } /* 89/6/13 add, (begin) */ else if (mtdx.PHYType == MarvellPHY) { unsigned int data; data = mdio_read(dev, mtdx.phys[0], SpecificReg); if (data & Full_Duplex) mtdx.duplexmode = 2; /* full duplex mode */ else mtdx.duplexmode = 1; /* half duplex mode */ data &= SpeedMask; if (data == Speed_1000M) mtdx.line_speed = 3; /* 1000M */ else if (data == Speed_100M) mtdx.line_speed = 2; /* 100M */ else mtdx.line_speed = 1; /* 10M */ } /* 89/6/13 add, (end) */ /* 89/7/27 add, (begin) */ else if (mtdx.PHYType == Myson981) { unsigned int data; data = mdio_read(dev, mtdx.phys[0], StatusRegister); if (data & SPEED100) mtdx.line_speed = 2; else mtdx.line_speed = 1; if (data & FULLMODE) mtdx.duplexmode = 2; else mtdx.duplexmode = 1; } /* 89/7/27 add, (end) */ /* 89/12/29 add */ else if (mtdx.PHYType == LevelOnePHY) { unsigned int data; data = mdio_read(dev, mtdx.phys[0], SpecificReg); if (data & LXT1000_Full) mtdx.duplexmode = 2; /* full duplex mode */ else mtdx.duplexmode = 1; /* half duplex mode */ data &= SpeedMask; if (data == LXT1000_1000M) mtdx.line_speed = 3; /* 1000M */ else if (data == LXT1000_100M) mtdx.line_speed = 2; /* 100M */ else mtdx.line_speed = 1; /* 10M */ } // chage crvalue // mtdx.crvalue&=(~PS10)&(~FD); mtdx.crvalue &= (~PS10) & (~FD) & (~PS1000); if (mtdx.line_speed == 1) mtdx.crvalue |= PS10; else if (mtdx.line_speed == 3) mtdx.crvalue |= PS1000; if (mtdx.duplexmode == 2) mtdx.crvalue |= FD; } } DRIVER ( "MTD80X", nic_driver, pci_driver, mtd80x_driver, mtd_probe, mtd_disable ); debian/grub-extras/disabled/gpxe/src/drivers/net/3c595.c0000664000000000000000000003331112524662415020124 0ustar /* * 3c595.c -- 3COM 3C595 Fast Etherlink III PCI driver for etherboot * * Copyright (C) 2000 Shusuke Nisiyama * All rights reserved. * Mar. 14, 2000 * * This software may be used, modified, copied, distributed, and sold, in * both source and binary form provided that the above copyright and these * terms are retained. Under no circumstances are the authors responsible for * the proper functioning of this software, nor do the authors assume any * responsibility for damages incurred with its use. * * This code is based on Martin Renters' etherboot-4.4.3 3c509.c and * Herb Peyerl's FreeBSD 3.4-RELEASE if_vx.c driver. * * Copyright (C) 1993-1994, David Greenman, Martin Renters. * Copyright (C) 1993-1995, Andres Vega Garcia. * Copyright (C) 1995, Serge Babkin. * * Copyright (c) 1994 Herb Peyerl * * timlegge 08-24-2003 Add Multicast Support */ FILE_LICENCE ( BSD2 ); /* #define EDEBUG */ #include "etherboot.h" #include "nic.h" #include #include #include "3c595.h" static struct nic_operations t595_operations; static unsigned short eth_nic_base; static unsigned short vx_connector, vx_connectors; static struct connector_entry { int bit; char *name; } conn_tab[VX_CONNECTORS] = { #define CONNECTOR_UTP 0 { 0x08, "utp"}, #define CONNECTOR_AUI 1 { 0x20, "aui"}, /* dummy */ { 0, "???"}, #define CONNECTOR_BNC 3 { 0x10, "bnc"}, #define CONNECTOR_TX 4 { 0x02, "tx"}, #define CONNECTOR_FX 5 { 0x04, "fx"}, #define CONNECTOR_MII 6 { 0x40, "mii"}, { 0, "???"} }; static void vxgetlink(void); static void vxsetlink(void); /************************************************************************** ETH_RESET - Reset adapter ***************************************************************************/ static void t595_reset(struct nic *nic) { int i; /*********************************************************** Reset 3Com 595 card *************************************************************/ /* stop card */ outw(RX_DISABLE, BASE + VX_COMMAND); outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND); VX_BUSY_WAIT; outw(TX_DISABLE, BASE + VX_COMMAND); outw(STOP_TRANSCEIVER, BASE + VX_COMMAND); udelay(8000); outw(RX_RESET, BASE + VX_COMMAND); VX_BUSY_WAIT; outw(TX_RESET, BASE + VX_COMMAND); VX_BUSY_WAIT; outw(C_INTR_LATCH, BASE + VX_COMMAND); outw(SET_RD_0_MASK, BASE + VX_COMMAND); outw(SET_INTR_MASK, BASE + VX_COMMAND); outw(SET_RX_FILTER, BASE + VX_COMMAND); /* * initialize card */ VX_BUSY_WAIT; GO_WINDOW(0); /* Disable the card */ /* outw(0, BASE + VX_W0_CONFIG_CTRL); */ /* Configure IRQ to none */ /* outw(SET_IRQ(0), BASE + VX_W0_RESOURCE_CFG); */ /* Enable the card */ /* outw(ENABLE_DRQ_IRQ, BASE + VX_W0_CONFIG_CTRL); */ GO_WINDOW(2); /* Reload the ether_addr. */ for (i = 0; i < ETH_ALEN; i++) outb(nic->node_addr[i], BASE + VX_W2_ADDR_0 + i); outw(RX_RESET, BASE + VX_COMMAND); VX_BUSY_WAIT; outw(TX_RESET, BASE + VX_COMMAND); VX_BUSY_WAIT; /* Window 1 is operating window */ GO_WINDOW(1); for (i = 0; i < 31; i++) inb(BASE + VX_W1_TX_STATUS); outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND); outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND); /* * Attempt to get rid of any stray interrupts that occured during * configuration. On the i386 this isn't possible because one may * already be queued. However, a single stray interrupt is * unimportant. */ outw(ACK_INTR | 0xff, BASE + VX_COMMAND); outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST|FIL_MULTICAST, BASE + VX_COMMAND); vxsetlink(); /*{ int i,j; i = CONNECTOR_TX; GO_WINDOW(3); j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK; outl(BASE + VX_W3_INTERNAL_CFG, j | (i < ETH_FRAME_LEN) { return; } /* drop acknowledgements */ while(( status=inb(BASE + VX_W1_TX_STATUS) )& TXS_COMPLETE ) { if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) { outw(TX_RESET, BASE + VX_COMMAND); outw(TX_ENABLE, BASE + VX_COMMAND); } outb(0x0, BASE + VX_W1_TX_STATUS); } while (inw(BASE + VX_W1_FREE_TX) < len + pad + 4) { /* no room in FIFO */ } outw(len, BASE + VX_W1_TX_PIO_WR_1); outw(0x0, BASE + VX_W1_TX_PIO_WR_1); /* Second dword meaningless */ /* write packet */ outsw(BASE + VX_W1_TX_PIO_WR_1, d, ETH_ALEN/2); outsw(BASE + VX_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2); outw(t, BASE + VX_W1_TX_PIO_WR_1); outsw(BASE + VX_W1_TX_PIO_WR_1, p, s / 2); if (s & 1) outb(*(p+s - 1), BASE + VX_W1_TX_PIO_WR_1); while (pad--) outb(0, BASE + VX_W1_TX_PIO_WR_1); /* Padding */ /* wait for Tx complete */ while((inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS) != 0) ; } /************************************************************************** ETH_POLL - Wait for a frame ***************************************************************************/ static int t595_poll(struct nic *nic, int retrieve) { /* common variables */ /* variables for 3C595 */ short status, cst; register short rx_fifo; cst=inw(BASE + VX_STATUS); #ifdef EDEBUG if(cst & 0x1FFF) printf("-%hX-",cst); #endif if( (cst & S_RX_COMPLETE)==0 ) { /* acknowledge everything */ outw(ACK_INTR | cst, BASE + VX_COMMAND); outw(C_INTR_LATCH, BASE + VX_COMMAND); return 0; } status = inw(BASE + VX_W1_RX_STATUS); #ifdef EDEBUG printf("*%hX*",status); #endif if (status & ERR_RX) { outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND); return 0; } rx_fifo = status & RX_BYTES_MASK; if (rx_fifo==0) return 0; if ( ! retrieve ) return 1; /* read packet */ #ifdef EDEBUG printf("[l=%d",rx_fifo); #endif insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2); if(rx_fifo & 1) nic->packet[rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1); nic->packetlen=rx_fifo; while(1) { status = inw(BASE + VX_W1_RX_STATUS); #ifdef EDEBUG printf("*%hX*",status); #endif rx_fifo = status & RX_BYTES_MASK; if(rx_fifo>0) { insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2); if(rx_fifo & 1) nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1); nic->packetlen+=rx_fifo; #ifdef EDEBUG printf("+%d",rx_fifo); #endif } if(( status & RX_INCOMPLETE )==0) { #ifdef EDEBUG printf("=%d",nic->packetlen); #endif break; } udelay(1000); } /* acknowledge reception of packet */ outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND); while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS); #ifdef EDEBUG { unsigned short type = 0; /* used by EDEBUG */ type = (nic->packet[12]<<8) | nic->packet[13]; if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+ nic->packet[5] == 0xFF*ETH_ALEN) printf(",t=%hX,b]",type); else printf(",t=%hX]",type); } #endif return 1; } /************************************************************************* 3Com 595 - specific routines **************************************************************************/ static int eeprom_rdy() { int i; for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++) udelay(1000); if (i >= MAX_EEPROMBUSY) { /* printf("3c595: eeprom failed to come ready.\n"); */ printf("3c595: eeprom is busy.\n"); /* memory in EPROM is tight */ return (0); } return (1); } /* * get_e: gets a 16 bits word from the EEPROM. we must have set the window * before */ static int get_e(offset) int offset; { if (!eeprom_rdy()) return (0xffff); outw(EEPROM_CMD_RD | offset, BASE + VX_W0_EEPROM_COMMAND); if (!eeprom_rdy()) return (0xffff); return (inw(BASE + VX_W0_EEPROM_DATA)); } static void vxgetlink(void) { int n, k; GO_WINDOW(3); vx_connectors = inw(BASE + VX_W3_RESET_OPT) & 0x7f; for (n = 0, k = 0; k < VX_CONNECTORS; k++) { if (vx_connectors & conn_tab[k].bit) { if (n > 0) { printf("/"); } printf("%s", conn_tab[k].name ); n++; } } if (vx_connectors == 0) { printf("no connectors!"); return; } GO_WINDOW(3); vx_connector = (inl(BASE + VX_W3_INTERNAL_CFG) & INTERNAL_CONNECTOR_MASK) >> INTERNAL_CONNECTOR_BITS; if (vx_connector & 0x10) { vx_connector &= 0x0f; printf("[*%s*]", conn_tab[vx_connector].name); printf(": disable 'auto select' with DOS util!"); } else { printf("[*%s*]", conn_tab[vx_connector].name); } } static void vxsetlink(void) { int i, j; char *reason, *warning; static char prev_conn = -1; if (prev_conn == -1) { prev_conn = vx_connector; } i = vx_connector; /* default in EEPROM */ reason = "default"; warning = 0; if ((vx_connectors & conn_tab[vx_connector].bit) == 0) { warning = "strange connector type in EEPROM."; reason = "forced"; i = CONNECTOR_UTP; } if (warning != 0) { printf("warning: %s\n", warning); } printf("selected %s. (%s)\n", conn_tab[i].name, reason); /* Set the selected connector. */ GO_WINDOW(3); j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK; outl(j | (i <ioaddr == 0) return 0; eth_nic_base = pci->ioaddr; nic->irqno = 0; nic->ioaddr = pci->ioaddr; GO_WINDOW(0); outw(GLOBAL_RESET, BASE + VX_COMMAND); VX_BUSY_WAIT; vxgetlink(); /* printf("\nEEPROM:"); for (i = 0; i < (EEPROMSIZE/2); i++) { printf("%hX:", get_e(i)); } printf("\n"); */ /* * Read the station address from the eeprom */ p = (unsigned short *) nic->node_addr; for (i = 0; i < 3; i++) { GO_WINDOW(0); p[i] = htons(get_e(EEPROM_OEM_ADDR_0 + i)); GO_WINDOW(2); outw(ntohs(p[i]), BASE + VX_W2_ADDR_0 + (i * 2)); } DBG ( "Ethernet address: %s\n", eth_ntoa (nic->node_addr) ); t595_reset(nic); nic->nic_op = &t595_operations; return 1; } static struct nic_operations t595_operations = { .connect = dummy_connect, .poll = t595_poll, .transmit = t595_transmit, .irq = t595_irq, }; static struct pci_device_id t595_nics[] = { PCI_ROM(0x10b7, 0x5900, "3c590", "3Com590", 0), /* Vortex 10Mbps */ PCI_ROM(0x10b7, 0x5950, "3c595", "3Com595", 0), /* Vortex 100baseTx */ PCI_ROM(0x10b7, 0x5951, "3c595-1", "3Com595", 0), /* Vortex 100baseT4 */ PCI_ROM(0x10b7, 0x5952, "3c595-2", "3Com595", 0), /* Vortex 100base-MII */ PCI_ROM(0x10b7, 0x9000, "3c900-tpo", "3Com900-TPO", 0), /* 10 Base TPO */ PCI_ROM(0x10b7, 0x9001, "3c900-t4", "3Com900-Combo", 0), /* 10/100 T4 */ PCI_ROM(0x10b7, 0x9004, "3c900b-tpo", "3Com900B-TPO", 0), /* 10 Base TPO */ PCI_ROM(0x10b7, 0x9005, "3c900b-combo", "3Com900B-Combo", 0), /* 10 Base Combo */ PCI_ROM(0x10b7, 0x9006, "3c900b-tpb2", "3Com900B-2/T", 0), /* 10 Base TP and Base2 */ PCI_ROM(0x10b7, 0x900a, "3c900b-fl", "3Com900B-FL", 0), /* 10 Base F */ PCI_ROM(0x10b7, 0x9800, "3c980-cyclone-1", "3Com980-Cyclone", 0), /* Cyclone */ PCI_ROM(0x10b7, 0x9805, "3c9805-1", "3Com9805", 0), /* Dual Port Server Cyclone */ PCI_ROM(0x10b7, 0x7646, "3csoho100-tx-1", "3CSOHO100-TX", 0), /* Hurricane */ PCI_ROM(0x10b7, 0x4500, "3c450-1", "3Com450 HomePNA Tornado", 0), }; PCI_DRIVER ( t595_driver, t595_nics, PCI_NO_CLASS ); DRIVER ( "3C595", nic_driver, pci_driver, t595_driver, t595_probe, t595_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/eepro.c0000664000000000000000000004660012524662415020473 0ustar #ifdef ALLMULTI #error multicast support is not yet implemented #endif /************************************************************************** Etherboot - BOOTP/TFTP Bootstrap Program Intel EEPRO/10 NIC driver for Etherboot Adapted from Linux eepro.c from kernel 2.2.17 This board accepts a 32 pin EEPROM (29C256), however a test with a 27C010 shows that this EPROM also works in the socket, but it's not clear how repeatably. The two top address pins appear to be held low, thus the bottom 32kB of the 27C010 is visible in the CPU's address space. To be sure you could put 4 copies of the code in the 27C010, then it doesn't matter whether the extra lines are held low or high, just hopefully not floating as CMOS chips don't like floating inputs. Be careful with seating the EPROM as the socket on my board actually has 34 pins, the top row of 2 are not used. ***************************************************************************/ /* timlegge 2005-05-18 remove the relocation changes cards that write directly to the hardware don't need it */ /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. */ FILE_LICENCE ( GPL2_OR_LATER ); #include "etherboot.h" #include #include "nic.h" #include #include /* Different 82595 chips */ #define LAN595 0 #define LAN595TX 1 #define LAN595FX 2 #define LAN595FX_10ISA 3 #define SLOW_DOWN inb(0x80); /* The station (ethernet) address prefix, used for IDing the board. */ #define SA_ADDR0 0x00 /* Etherexpress Pro/10 */ #define SA_ADDR1 0xaa #define SA_ADDR2 0x00 #define GetBit(x,y) ((x & (1<>y) /* EEPROM Word 0: */ #define ee_PnP 0 /* Plug 'n Play enable bit */ #define ee_Word1 1 /* Word 1? */ #define ee_BusWidth 2 /* 8/16 bit */ #define ee_FlashAddr 3 /* Flash Address */ #define ee_FlashMask 0x7 /* Mask */ #define ee_AutoIO 6 /* */ #define ee_reserved0 7 /* =0! */ #define ee_Flash 8 /* Flash there? */ #define ee_AutoNeg 9 /* Auto Negotiation enabled? */ #define ee_IO0 10 /* IO Address LSB */ #define ee_IO0Mask 0x /*...*/ #define ee_IO1 15 /* IO MSB */ /* EEPROM Word 1: */ #define ee_IntSel 0 /* Interrupt */ #define ee_IntMask 0x7 #define ee_LI 3 /* Link Integrity 0= enabled */ #define ee_PC 4 /* Polarity Correction 0= enabled */ #define ee_TPE_AUI 5 /* PortSelection 1=TPE */ #define ee_Jabber 6 /* Jabber prevention 0= enabled */ #define ee_AutoPort 7 /* Auto Port Selection 1= Disabled */ #define ee_SMOUT 8 /* SMout Pin Control 0= Input */ #define ee_PROM 9 /* Flash EPROM / PROM 0=Flash */ #define ee_reserved1 10 /* .. 12 =0! */ #define ee_AltReady 13 /* Alternate Ready, 0=normal */ #define ee_reserved2 14 /* =0! */ #define ee_Duplex 15 /* Word2,3,4: */ #define ee_IA5 0 /*bit start for individual Addr Byte 5 */ #define ee_IA4 8 /*bit start for individual Addr Byte 5 */ #define ee_IA3 0 /*bit start for individual Addr Byte 5 */ #define ee_IA2 8 /*bit start for individual Addr Byte 5 */ #define ee_IA1 0 /*bit start for individual Addr Byte 5 */ #define ee_IA0 8 /*bit start for individual Addr Byte 5 */ /* Word 5: */ #define ee_BNC_TPE 0 /* 0=TPE */ #define ee_BootType 1 /* 00=None, 01=IPX, 10=ODI, 11=NDIS */ #define ee_BootTypeMask 0x3 #define ee_NumConn 3 /* Number of Connections 0= One or Two */ #define ee_FlashSock 4 /* Presence of Flash Socket 0= Present */ #define ee_PortTPE 5 #define ee_PortBNC 6 #define ee_PortAUI 7 #define ee_PowerMgt 10 /* 0= disabled */ #define ee_CP 13 /* Concurrent Processing */ #define ee_CPMask 0x7 /* Word 6: */ #define ee_Stepping 0 /* Stepping info */ #define ee_StepMask 0x0F #define ee_BoardID 4 /* Manucaturer Board ID, reserved */ #define ee_BoardMask 0x0FFF /* Word 7: */ #define ee_INT_TO_IRQ 0 /* int to IRQ Mapping = 0x1EB8 for Pro/10+ */ #define ee_FX_INT2IRQ 0x1EB8 /* the _only_ mapping allowed for FX chips */ /*..*/ #define ee_SIZE 0x40 /* total EEprom Size */ #define ee_Checksum 0xBABA /* initial and final value for adding checksum */ /* Card identification via EEprom: */ #define ee_addr_vendor 0x10 /* Word offset for EISA Vendor ID */ #define ee_addr_id 0x11 /* Word offset for Card ID */ #define ee_addr_SN 0x12 /* Serial Number */ #define ee_addr_CRC_8 0x14 /* CRC over last thee Bytes */ #define ee_vendor_intel0 0x25 /* Vendor ID Intel */ #define ee_vendor_intel1 0xD4 #define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */ #define ee_id_eepro10p1 0x31 /* now this section could be used by both boards: the oldies and the ee10: * ee10 uses tx buffer before of rx buffer and the oldies the inverse. * (aris) */ #define RAM_SIZE 0x8000 #define RCV_HEADER 8 #define RCV_DEFAULT_RAM 0x6000 #define RCV_RAM rcv_ram static unsigned rcv_ram = RCV_DEFAULT_RAM; #define XMT_HEADER 8 #define XMT_RAM (RAM_SIZE - RCV_RAM) #define XMT_START ((rcv_start + RCV_RAM) % RAM_SIZE) #define RCV_LOWER_LIMIT (rcv_start >> 8) #define RCV_UPPER_LIMIT (((rcv_start + RCV_RAM) - 2) >> 8) #define XMT_LOWER_LIMIT (XMT_START >> 8) #define XMT_UPPER_LIMIT (((XMT_START + XMT_RAM) - 2) >> 8) #define RCV_START_PRO 0x00 #define RCV_START_10 XMT_RAM /* by default the old driver */ static unsigned rcv_start = RCV_START_PRO; #define RCV_DONE 0x0008 #define RX_OK 0x2000 #define RX_ERROR 0x0d81 #define TX_DONE_BIT 0x0080 #define CHAIN_BIT 0x8000 #define XMT_STATUS 0x02 #define XMT_CHAIN 0x04 #define XMT_COUNT 0x06 #define BANK0_SELECT 0x00 #define BANK1_SELECT 0x40 #define BANK2_SELECT 0x80 /* Bank 0 registers */ #define COMMAND_REG 0x00 /* Register 0 */ #define MC_SETUP 0x03 #define XMT_CMD 0x04 #define DIAGNOSE_CMD 0x07 #define RCV_ENABLE_CMD 0x08 #define RCV_DISABLE_CMD 0x0a #define STOP_RCV_CMD 0x0b #define RESET_CMD 0x0e #define POWER_DOWN_CMD 0x18 #define RESUME_XMT_CMD 0x1c #define SEL_RESET_CMD 0x1e #define STATUS_REG 0x01 /* Register 1 */ #define RX_INT 0x02 #define TX_INT 0x04 #define EXEC_STATUS 0x30 #define ID_REG 0x02 /* Register 2 */ #define R_ROBIN_BITS 0xc0 /* round robin counter */ #define ID_REG_MASK 0x2c #define ID_REG_SIG 0x24 #define AUTO_ENABLE 0x10 #define INT_MASK_REG 0x03 /* Register 3 */ #define RX_STOP_MASK 0x01 #define RX_MASK 0x02 #define TX_MASK 0x04 #define EXEC_MASK 0x08 #define ALL_MASK 0x0f #define IO_32_BIT 0x10 #define RCV_BAR 0x04 /* The following are word (16-bit) registers */ #define RCV_STOP 0x06 #define XMT_BAR_PRO 0x0a #define XMT_BAR_10 0x0b static unsigned xmt_bar = XMT_BAR_PRO; #define HOST_ADDRESS_REG 0x0c #define IO_PORT 0x0e #define IO_PORT_32_BIT 0x0c /* Bank 1 registers */ #define REG1 0x01 #define WORD_WIDTH 0x02 #define INT_ENABLE 0x80 #define INT_NO_REG 0x02 #define RCV_LOWER_LIMIT_REG 0x08 #define RCV_UPPER_LIMIT_REG 0x09 #define XMT_LOWER_LIMIT_REG_PRO 0x0a #define XMT_UPPER_LIMIT_REG_PRO 0x0b #define XMT_LOWER_LIMIT_REG_10 0x0b #define XMT_UPPER_LIMIT_REG_10 0x0a static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO; static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO; /* Bank 2 registers */ #define XMT_Chain_Int 0x20 /* Interrupt at the end of the transmit chain */ #define XMT_Chain_ErrStop 0x40 /* Interrupt at the end of the chain even if there are errors */ #define RCV_Discard_BadFrame 0x80 /* Throw bad frames away, and continue to receive others */ #define REG2 0x02 #define PRMSC_Mode 0x01 #define Multi_IA 0x20 #define REG3 0x03 #define TPE_BIT 0x04 #define BNC_BIT 0x20 #define REG13 0x0d #define FDX 0x00 #define A_N_ENABLE 0x02 #define I_ADD_REG0 0x04 #define I_ADD_REG1 0x05 #define I_ADD_REG2 0x06 #define I_ADD_REG3 0x07 #define I_ADD_REG4 0x08 #define I_ADD_REG5 0x09 #define EEPROM_REG_PRO 0x0a #define EEPROM_REG_10 0x0b static unsigned eeprom_reg = EEPROM_REG_PRO; #define EESK 0x01 #define EECS 0x02 #define EEDI 0x04 #define EEDO 0x08 /* The horrible routine to read a word from the serial EEPROM. */ /* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */ /* The delay between EEPROM clock transitions. */ #define eeprom_delay() { udelay(40); } #define EE_READ_CMD (6 << 6) /* do a full reset; data sheet asks for 250us delay */ #define eepro_full_reset(ioaddr) outb(RESET_CMD, ioaddr); udelay(255); /* do a nice reset */ #define eepro_sel_reset(ioaddr) \ do { \ outb ( SEL_RESET_CMD, ioaddr ); \ (void) SLOW_DOWN; \ (void) SLOW_DOWN; \ } while (0) /* clear all interrupts */ #define eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG) /* enable rx */ #define eepro_en_rx(ioaddr) outb(RCV_ENABLE_CMD, ioaddr) /* disable rx */ #define eepro_dis_rx(ioaddr) outb(RCV_DISABLE_CMD, ioaddr) /* switch bank */ #define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr) #define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr) #define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr) static unsigned int rx_start, tx_start; static int tx_last; static unsigned int tx_end; static int eepro = 0; static unsigned int mem_start, mem_end = RCV_DEFAULT_RAM / 1024; /************************************************************************** RESET - Reset adapter ***************************************************************************/ static void eepro_reset(struct nic *nic) { int temp_reg, i; /* put the card in its initial state */ eepro_sw2bank2(nic->ioaddr); /* be careful, bank2 now */ temp_reg = inb(nic->ioaddr + eeprom_reg); DBG("Stepping %d\n", temp_reg >> 5); if (temp_reg & 0x10) /* check the TurnOff Enable bit */ outb(temp_reg & 0xEF, nic->ioaddr + eeprom_reg); for (i = 0; i < ETH_ALEN; i++) /* fill the MAC address */ outb(nic->node_addr[i], nic->ioaddr + I_ADD_REG0 + i); temp_reg = inb(nic->ioaddr + REG1); /* setup Transmit Chaining and discard bad RCV frames */ outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop | RCV_Discard_BadFrame, nic->ioaddr + REG1); temp_reg = inb(nic->ioaddr + REG2); /* match broadcast */ outb(temp_reg | 0x14, nic->ioaddr + REG2); temp_reg = inb(nic->ioaddr + REG3); outb(temp_reg & 0x3F, nic->ioaddr + REG3); /* clear test mode */ /* set the receiving mode */ eepro_sw2bank1(nic->ioaddr); /* be careful, bank1 now */ /* initialise the RCV and XMT upper and lower limits */ outb(RCV_LOWER_LIMIT, nic->ioaddr + RCV_LOWER_LIMIT_REG); outb(RCV_UPPER_LIMIT, nic->ioaddr + RCV_UPPER_LIMIT_REG); outb(XMT_LOWER_LIMIT, nic->ioaddr + xmt_lower_limit_reg); outb(XMT_UPPER_LIMIT, nic->ioaddr + xmt_upper_limit_reg); eepro_sw2bank0(nic->ioaddr); /* Switch back to bank 0 */ eepro_clear_int(nic->ioaddr); /* Initialise RCV */ outw(rx_start = (RCV_LOWER_LIMIT << 8), nic->ioaddr + RCV_BAR); outw(((RCV_UPPER_LIMIT << 8) | 0xFE), nic->ioaddr + RCV_STOP); /* Make sure 1st poll won't find a valid packet header */ outw((RCV_LOWER_LIMIT << 8), nic->ioaddr + HOST_ADDRESS_REG); outw(0, nic->ioaddr + IO_PORT); /* Intialise XMT */ outw((XMT_LOWER_LIMIT << 8), nic->ioaddr + xmt_bar); eepro_sel_reset(nic->ioaddr); tx_start = tx_end = (unsigned int) (XMT_LOWER_LIMIT << 8); tx_last = 0; eepro_en_rx(nic->ioaddr); } /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int eepro_poll(struct nic *nic, int retrieve) { unsigned int rcv_car = rx_start; unsigned int rcv_event, rcv_status, rcv_next_frame, rcv_size; /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ /* nic->packetlen should contain length of data */ #if 0 if ((inb(nic->ioaddr + STATUS_REG) & 0x40) == 0) return (0); outb(0x40, nic->ioaddr + STATUS_REG); #endif outw(rcv_car, nic->ioaddr + HOST_ADDRESS_REG); rcv_event = inw(nic->ioaddr + IO_PORT); if (rcv_event != RCV_DONE) return (0); /* FIXME: I'm guessing this might not work with this card, since it looks like once a rcv_event is started it must be completed. maybe there's another way. */ if ( ! retrieve ) return 1; rcv_status = inw(nic->ioaddr + IO_PORT); rcv_next_frame = inw(nic->ioaddr + IO_PORT); rcv_size = inw(nic->ioaddr + IO_PORT); #if 0 printf("%hX %hX %d %hhX\n", rcv_status, rcv_next_frame, rcv_size, inb(nic->ioaddr + STATUS_REG)); #endif if ((rcv_status & (RX_OK|RX_ERROR)) != RX_OK) { printf("Receive error %hX\n", rcv_status); return (0); } rcv_size &= 0x3FFF; insw(nic->ioaddr + IO_PORT, nic->packet, ((rcv_size + 3) >> 1)); #if 0 { int i; for (i = 0; i < 48; i++) { printf("%hhX", nic->packet[i]); putchar(i % 16 == 15 ? '\n' : ' '); } } #endif nic->packetlen = rcv_size; rcv_car = (rx_start + RCV_HEADER + rcv_size); rx_start = rcv_next_frame; /* hex_dump(rcv_car, nic->packetlen); */ if (rcv_car == 0) rcv_car = ((RCV_UPPER_LIMIT << 8) | 0xff); outw(rcv_car - 1, nic->ioaddr + RCV_STOP); return (1); } /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void eepro_transmit( struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) /* Packet */ { unsigned int status, tx_available, last, end, length; unsigned short type; int boguscount = 20; length = s + ETH_HLEN; if (tx_end > tx_start) tx_available = XMT_RAM - (tx_end - tx_start); else if (tx_end < tx_start) tx_available = tx_start - tx_end; else tx_available = XMT_RAM; last = tx_end; end = last + (((length + 3) >> 1) << 1) + XMT_HEADER; if (end >= (XMT_UPPER_LIMIT << 8)) { last = (XMT_LOWER_LIMIT << 8); end = last + (((length + 3) >> 1) << 1) + XMT_HEADER; } outw(last, nic->ioaddr + HOST_ADDRESS_REG); outw(XMT_CMD, nic->ioaddr + IO_PORT); outw(0, nic->ioaddr + IO_PORT); outw(end, nic->ioaddr + IO_PORT); outw(length, nic->ioaddr + IO_PORT); outsw(nic->ioaddr + IO_PORT, d, ETH_ALEN / 2); outsw(nic->ioaddr + IO_PORT, nic->node_addr, ETH_ALEN / 2); type = htons(t); outsw(nic->ioaddr + IO_PORT, &type, sizeof(type) / 2); outsw(nic->ioaddr + IO_PORT, p, (s + 3) >> 1); /* A dummy read to flush the DRAM write pipeline */ status = inw(nic->ioaddr + IO_PORT); outw(last, nic->ioaddr + xmt_bar); outb(XMT_CMD, nic->ioaddr); tx_start = last; tx_last = last; tx_end = end; #if 0 printf("%d %d\n", tx_start, tx_end); #endif while (boguscount > 0) { if (((status = inw(nic->ioaddr + IO_PORT)) & TX_DONE_BIT) == 0) { udelay(40); boguscount--; continue; } if ((status & 0x2000) == 0) { DBG("Transmit status %hX\n", status); } } } /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void eepro_disable ( struct nic *nic, struct isa_device *isa __unused ) { eepro_sw2bank0(nic->ioaddr); /* Switch to bank 0 */ /* Flush the Tx and disable Rx */ outb(STOP_RCV_CMD, nic->ioaddr); tx_start = tx_end = (XMT_LOWER_LIMIT << 8); tx_last = 0; /* Reset the 82595 */ eepro_full_reset(nic->ioaddr); } /************************************************************************** DISABLE - Enable, Disable, or Force interrupts ***************************************************************************/ static void eepro_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } static int read_eeprom(uint16_t ioaddr, int location) { int i; unsigned short retval = 0; int ee_addr = ioaddr + eeprom_reg; int read_cmd = location | EE_READ_CMD; int ctrl_val = EECS; if (eepro == LAN595FX_10ISA) { eepro_sw2bank1(ioaddr); outb(0x00, ioaddr + STATUS_REG); } eepro_sw2bank2(ioaddr); outb(ctrl_val, ee_addr); /* shift the read command bits out */ for (i = 8; i >= 0; i--) { short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val; outb(outval, ee_addr); outb(outval | EESK, ee_addr); /* EEPROM clock tick */ eeprom_delay(); outb(outval, ee_addr); /* finish EEPROM clock tick */ eeprom_delay(); } outb(ctrl_val, ee_addr); for (i = 16; i > 0; i--) { outb(ctrl_val | EESK, ee_addr); eeprom_delay(); retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0); outb(ctrl_val, ee_addr); eeprom_delay(); } /* terminate the EEPROM access */ ctrl_val &= ~EECS; outb(ctrl_val | EESK, ee_addr); eeprom_delay(); outb(ctrl_val, ee_addr); eeprom_delay(); eepro_sw2bank0(ioaddr); return (retval); } static int eepro_probe1 ( isa_probe_addr_t ioaddr ) { int id, counter; id = inb(ioaddr + ID_REG); if ((id & ID_REG_MASK) != ID_REG_SIG) return (0); counter = id & R_ROBIN_BITS; if (((id = inb(ioaddr + ID_REG)) & R_ROBIN_BITS) != (counter + 0x40)) return (0); /* yes the 82595 has been found */ return (1); } static struct nic_operations eepro_operations = { .connect = dummy_connect, .poll = eepro_poll, .transmit = eepro_transmit, .irq = eepro_irq, }; /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside ***************************************************************************/ static int eepro_probe ( struct nic *nic, struct isa_device *isa ) { int i, l_eepro = 0; union { unsigned char caddr[ETH_ALEN]; unsigned short saddr[ETH_ALEN/2]; } station_addr; const char *name; nic->irqno = 0; nic->ioaddr = isa->ioaddr; station_addr.saddr[2] = read_eeprom(nic->ioaddr,2); if ( ( station_addr.saddr[2] == 0x0000 ) || ( station_addr.saddr[2] == 0xFFFF ) ) { l_eepro = 3; eepro = LAN595FX_10ISA; eeprom_reg= EEPROM_REG_10; rcv_start = RCV_START_10; xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10; xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10; station_addr.saddr[2] = read_eeprom(nic->ioaddr,2); } station_addr.saddr[1] = read_eeprom(nic->ioaddr,3); station_addr.saddr[0] = read_eeprom(nic->ioaddr,4); if (l_eepro) name = "Intel EtherExpress 10 ISA"; else if (read_eeprom(nic->ioaddr,7) == ee_FX_INT2IRQ) { name = "Intel EtherExpress Pro/10+ ISA"; l_eepro = 2; } else if (station_addr.saddr[0] == SA_ADDR1) { name = "Intel EtherExpress Pro/10 ISA"; l_eepro = 1; } else { l_eepro = 0; name = "Intel 82595-based LAN card"; } station_addr.saddr[0] = swap16(station_addr.saddr[0]); station_addr.saddr[1] = swap16(station_addr.saddr[1]); station_addr.saddr[2] = swap16(station_addr.saddr[2]); for (i = 0; i < ETH_ALEN; i++) { nic->node_addr[i] = station_addr.caddr[i]; } DBG ( "%s ioaddr %#hX, addr %s", name, nic->ioaddr, eth_ntoa ( nic->node_addr ) ); mem_start = RCV_LOWER_LIMIT << 8; if ((mem_end & 0x3F) < 3 || (mem_end & 0x3F) > 29) mem_end = RCV_UPPER_LIMIT << 8; else { mem_end = mem_end * 1024 + (RCV_LOWER_LIMIT << 8); rcv_ram = mem_end - (RCV_LOWER_LIMIT << 8); } printf(", Rx mem %dK, if %s\n", (mem_end - mem_start) >> 10, GetBit(read_eeprom(nic->ioaddr,5), ee_BNC_TPE) ? "BNC" : "TP"); eepro_reset(nic); /* point to NIC specific routines */ nic->nic_op = &eepro_operations; return 1; } static isa_probe_addr_t eepro_probe_addrs[] = { 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, }; ISA_DRIVER ( eepro_driver, eepro_probe_addrs, eepro_probe1, GENERIC_ISAPNP_VENDOR, 0x828a ); DRIVER ( "eepro", nic_driver, isa_driver, eepro_driver, eepro_probe, eepro_disable ); ISA_ROM ( "eepro", "Intel Etherexpress Pro/10" ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/3c5x9.c0000664000000000000000000002510712524662415020233 0ustar /************************************************************************** ETHERBOOT - BOOTP/TFTP Bootstrap Program Author: Martin Renters. Date: Mar 22 1995 This code is based heavily on David Greenman's if_ed.c driver and Andres Vega Garcia's if_ep.c driver. Copyright (C) 1993-1994, David Greenman, Martin Renters. Copyright (C) 1993-1995, Andres Vega Garcia. Copyright (C) 1995, Serge Babkin. This software may be used, modified, copied, distributed, and sold, in both source and binary form provided that the above copyright and these terms are retained. Under no circumstances are the authors responsible for the proper functioning of this software, nor do the authors assume any responsibility for damages incurred with its use. 3c509 support added by Serge Babkin (babkin@hq.icb.chel.su) $Id$ ***************************************************************************/ FILE_LICENCE ( BSD2 ); /* #define EDEBUG */ #include #include "etherboot.h" #include "nic.h" #include #include "3c509.h" static enum { none, bnc, utp } connector = none; /* for 3C509 */ /************************************************************************** ETH_RESET - Reset adapter ***************************************************************************/ void t5x9_disable ( struct nic *nic ) { /* stop card */ outw(RX_DISABLE, nic->ioaddr + EP_COMMAND); outw(RX_DISCARD_TOP_PACK, nic->ioaddr + EP_COMMAND); while (inw(nic->ioaddr + EP_STATUS) & S_COMMAND_IN_PROGRESS) ; outw(TX_DISABLE, nic->ioaddr + EP_COMMAND); outw(STOP_TRANSCEIVER, nic->ioaddr + EP_COMMAND); udelay(1000); outw(RX_RESET, nic->ioaddr + EP_COMMAND); outw(TX_RESET, nic->ioaddr + EP_COMMAND); outw(C_INTR_LATCH, nic->ioaddr + EP_COMMAND); outw(SET_RD_0_MASK, nic->ioaddr + EP_COMMAND); outw(SET_INTR_MASK, nic->ioaddr + EP_COMMAND); outw(SET_RX_FILTER, nic->ioaddr + EP_COMMAND); /* * wait for reset to complete */ while (inw(nic->ioaddr + EP_STATUS) & S_COMMAND_IN_PROGRESS) ; GO_WINDOW(nic->ioaddr,0); /* Disable the card */ outw(0, nic->ioaddr + EP_W0_CONFIG_CTRL); /* Configure IRQ to none */ outw(SET_IRQ(0), nic->ioaddr + EP_W0_RESOURCE_CFG); } static void t509_enable ( struct nic *nic ) { int i; /* Enable the card */ GO_WINDOW(nic->ioaddr,0); outw(ENABLE_DRQ_IRQ, nic->ioaddr + EP_W0_CONFIG_CTRL); GO_WINDOW(nic->ioaddr,2); /* Reload the ether_addr. */ for (i = 0; i < ETH_ALEN; i++) outb(nic->node_addr[i], nic->ioaddr + EP_W2_ADDR_0 + i); outw(RX_RESET, nic->ioaddr + EP_COMMAND); outw(TX_RESET, nic->ioaddr + EP_COMMAND); /* Window 1 is operating window */ GO_WINDOW(nic->ioaddr,1); for (i = 0; i < 31; i++) inb(nic->ioaddr + EP_W1_TX_STATUS); /* get rid of stray intr's */ outw(ACK_INTR | 0xff, nic->ioaddr + EP_COMMAND); outw(SET_RD_0_MASK | S_5_INTS, nic->ioaddr + EP_COMMAND); outw(SET_INTR_MASK, nic->ioaddr + EP_COMMAND); outw(SET_RX_FILTER | FIL_GROUP | FIL_INDIVIDUAL | FIL_BRDCST, nic->ioaddr + EP_COMMAND); /* configure BNC */ if (connector == bnc) { outw(START_TRANSCEIVER, nic->ioaddr + EP_COMMAND); udelay(1000); } /* configure UTP */ else if (connector == utp) { GO_WINDOW(nic->ioaddr,4); outw(ENABLE_UTP, nic->ioaddr + EP_W4_MEDIA_TYPE); sleep(2); /* Give time for media to negotiate */ GO_WINDOW(nic->ioaddr,1); } /* start transceiver and receiver */ outw(RX_ENABLE, nic->ioaddr + EP_COMMAND); outw(TX_ENABLE, nic->ioaddr + EP_COMMAND); /* set early threshold for minimal packet length */ outw(SET_RX_EARLY_THRESH | ETH_ZLEN, nic->ioaddr + EP_COMMAND); outw(SET_TX_START_THRESH | 16, nic->ioaddr + EP_COMMAND); } static void t509_reset ( struct nic *nic ) { t5x9_disable ( nic ); t509_enable ( nic ); } /************************************************************************** ETH_TRANSMIT - Transmit a frame ***************************************************************************/ static char padmap[] = { 0, 3, 2, 1}; static void t509_transmit( struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) /* Packet */ { register unsigned int len; int pad; int status; #ifdef EDEBUG printf("{l=%d,t=%hX}",s+ETH_HLEN,t); #endif /* swap bytes of type */ t= htons(t); len=s+ETH_HLEN; /* actual length of packet */ pad = padmap[len & 3]; /* * The 3c509 automatically pads short packets to minimum ethernet length, * but we drop packets that are too large. Perhaps we should truncate * them instead? */ if (len + pad > ETH_FRAME_LEN) { return; } /* drop acknowledgements */ while ((status=inb(nic->ioaddr + EP_W1_TX_STATUS)) & TXS_COMPLETE ) { if (status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) { outw(TX_RESET, nic->ioaddr + EP_COMMAND); outw(TX_ENABLE, nic->ioaddr + EP_COMMAND); } outb(0x0, nic->ioaddr + EP_W1_TX_STATUS); } while (inw(nic->ioaddr + EP_W1_FREE_TX) < (unsigned short)len + pad + 4) ; /* no room in FIFO */ outw(len, nic->ioaddr + EP_W1_TX_PIO_WR_1); outw(0x0, nic->ioaddr + EP_W1_TX_PIO_WR_1); /* Second dword meaningless */ /* write packet */ outsw(nic->ioaddr + EP_W1_TX_PIO_WR_1, d, ETH_ALEN/2); outsw(nic->ioaddr + EP_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2); outw(t, nic->ioaddr + EP_W1_TX_PIO_WR_1); outsw(nic->ioaddr + EP_W1_TX_PIO_WR_1, p, s / 2); if (s & 1) outb(*(p+s - 1), nic->ioaddr + EP_W1_TX_PIO_WR_1); while (pad--) outb(0, nic->ioaddr + EP_W1_TX_PIO_WR_1); /* Padding */ /* wait for Tx complete */ while((inw(nic->ioaddr + EP_STATUS) & S_COMMAND_IN_PROGRESS) != 0) ; } /************************************************************************** ETH_POLL - Wait for a frame ***************************************************************************/ static int t509_poll(struct nic *nic, int retrieve) { /* common variables */ /* variables for 3C509 */ short status, cst; register short rx_fifo; cst=inw(nic->ioaddr + EP_STATUS); #ifdef EDEBUG if(cst & 0x1FFF) printf("-%hX-",cst); #endif if( (cst & S_RX_COMPLETE)==0 ) { /* acknowledge everything */ outw(ACK_INTR| (cst & S_5_INTS), nic->ioaddr + EP_COMMAND); outw(C_INTR_LATCH, nic->ioaddr + EP_COMMAND); return 0; } status = inw(nic->ioaddr + EP_W1_RX_STATUS); #ifdef EDEBUG printf("*%hX*",status); #endif if (status & ERR_RX) { outw(RX_DISCARD_TOP_PACK, nic->ioaddr + EP_COMMAND); return 0; } rx_fifo = status & RX_BYTES_MASK; if (rx_fifo==0) return 0; if ( ! retrieve ) return 1; /* read packet */ #ifdef EDEBUG printf("[l=%d",rx_fifo); #endif insw(nic->ioaddr + EP_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2); if(rx_fifo & 1) nic->packet[rx_fifo-1]=inb(nic->ioaddr + EP_W1_RX_PIO_RD_1); nic->packetlen=rx_fifo; while(1) { status = inw(nic->ioaddr + EP_W1_RX_STATUS); #ifdef EDEBUG printf("*%hX*",status); #endif rx_fifo = status & RX_BYTES_MASK; if(rx_fifo>0) { insw(nic->ioaddr + EP_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2); if(rx_fifo & 1) nic->packet[nic->packetlen+rx_fifo-1]=inb(nic->ioaddr + EP_W1_RX_PIO_RD_1); nic->packetlen+=rx_fifo; #ifdef EDEBUG printf("+%d",rx_fifo); #endif } if(( status & RX_INCOMPLETE )==0) { #ifdef EDEBUG printf("=%d",nic->packetlen); #endif break; } udelay(1000); /* if incomplete wait 1 ms */ } /* acknowledge reception of packet */ outw(RX_DISCARD_TOP_PACK, nic->ioaddr + EP_COMMAND); while (inw(nic->ioaddr + EP_STATUS) & S_COMMAND_IN_PROGRESS) ; #ifdef EDEBUG { unsigned short type = 0; /* used by EDEBUG */ type = (nic->packet[12]<<8) | nic->packet[13]; if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+ nic->packet[5] == 0xFF*ETH_ALEN) printf(",t=%hX,b]",type); else printf(",t=%hX]",type); } #endif return (1); } /************************************************************************** ETH_IRQ - interrupt handling ***************************************************************************/ static void t509_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } /************************************************************************* 3Com 509 - specific routines **************************************************************************/ static int eeprom_rdy ( uint16_t ioaddr ) { int i; for (i = 0; is_eeprom_busy(ioaddr) && i < MAX_EEPROMBUSY; i++); if (i >= MAX_EEPROMBUSY) { /* printf("3c509: eeprom failed to come ready.\n"); */ /* memory in EPROM is tight */ /* printf("3c509: eeprom busy.\n"); */ return (0); } return (1); } /* * get_e: gets a 16 bits word from the EEPROM. */ static int get_e ( uint16_t ioaddr, int offset ) { GO_WINDOW(ioaddr,0); if (!eeprom_rdy(ioaddr)) return (0xffff); outw(EEPROM_CMD_RD | offset, ioaddr + EP_W0_EEPROM_COMMAND); if (!eeprom_rdy(ioaddr)) return (0xffff); return (inw(ioaddr + EP_W0_EEPROM_DATA)); } static struct nic_operations t509_operations = { .connect = dummy_connect, .poll = t509_poll, .transmit = t509_transmit, .irq = t509_irq, }; /************************************************************************** ETH_PROBE - Look for an adapter ***************************************************************************/ int t5x9_probe ( struct nic *nic, uint16_t prod_id_check, uint16_t prod_id_mask ) { uint16_t prod_id; int i,j; unsigned short *p; /* Check product ID */ prod_id = get_e ( nic->ioaddr, EEPROM_PROD_ID ); if ( ( prod_id & prod_id_mask ) != prod_id_check ) { printf ( "EEPROM Product ID is incorrect (%hx & %hx != %hx)\n", prod_id, prod_id_mask, prod_id_check ); return 0; } /* test for presence of connectors */ GO_WINDOW(nic->ioaddr,0); i = inw(nic->ioaddr + EP_W0_CONFIG_CTRL); j = (inw(nic->ioaddr + EP_W0_ADDRESS_CFG) >> 14) & 0x3; switch(j) { case 0: if (i & IS_UTP) { printf("10baseT\n"); connector = utp; } else { printf("10baseT not present\n"); return 0; } break; case 1: if (i & IS_AUI) { printf("10base5\n"); } else { printf("10base5 not present\n"); return 0; } break; case 3: if (i & IS_BNC) { printf("10base2\n"); connector = bnc; } else { printf("10base2 not present\n"); return 0; } break; default: printf("unknown connector\n"); return 0; } /* * Read the station address from the eeprom */ p = (unsigned short *) nic->node_addr; for (i = 0; i < ETH_ALEN / 2; i++) { p[i] = htons(get_e(nic->ioaddr,i)); GO_WINDOW(nic->ioaddr,2); outw(ntohs(p[i]), nic->ioaddr + EP_W2_ADDR_0 + (i * 2)); } DBG ( "Ethernet Address: %s\n", eth_ntoa ( nic->node_addr ) ); t509_reset(nic); nic->nic_op = &t509_operations; return 1; } /* * Local variables: * c-basic-offset: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/sundance.c0000664000000000000000000006407712524662415021171 0ustar /************************************************************************** * * sundance.c -- Etherboot device driver for the Sundance ST201 "Alta". * Written 2002-2002 by Timothy Legge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Portions of this code based on: * sundance.c: A Linux device driver for the Sundance ST201 "Alta" * Written 1999-2002 by Donald Becker * * tulip.c: Tulip and Clone Etherboot Driver * By Marty Conner * Copyright (C) 2001 Entity Cyber, Inc. * * Linux Driver Version LK1.09a, 10-Jul-2003 (2.4.25) * * REVISION HISTORY: * ================ * v1.1 01-01-2003 timlegge Initial implementation * v1.7 04-10-2003 timlegge Transfers Linux Kernel (30 sec) * v1.8 04-13-2003 timlegge Fix multiple transmission bug * v1.9 08-19-2003 timlegge Support Multicast * v1.10 01-17-2004 timlegge Initial driver output cleanup * v1.11 03-21-2004 timlegge Remove unused variables * v1.12 03-21-2004 timlegge Remove excess MII defines * v1.13 03-24-2004 timlegge Update to Linux 2.4.25 driver * ****************************************************************************/ FILE_LICENCE ( GPL2_OR_LATER ); /* to get some global routines like printf */ #include "etherboot.h" /* to get the interface to the body of the program */ #include "nic.h" /* to get the PCI support functions, if this is a PCI NIC */ #include #include "mii.h" #define drv_version "v1.12" #define drv_date "2004-03-21" #define HZ 100 /* Condensed operations for readability. */ #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) /* Set the mtu */ static int mtu = 1514; /* Maximum number of multicast addresses to filter (vs. rx-all-multicast). The sundance uses a 64 element hash table based on the Ethernet CRC. */ // static int multicast_filter_limit = 32; /* Set the copy breakpoint for the copy-only-tiny-frames scheme. Setting to > 1518 effectively disables this feature. This chip can receive into any byte alignment buffers, so word-oriented archs do not need a copy-align of the IP header. */ static int rx_copybreak = 0; static int flowctrl = 1; /* Allow forcing the media type */ /* media[] specifies the media type the NIC operates at. autosense Autosensing active media. 10mbps_hd 10Mbps half duplex. 10mbps_fd 10Mbps full duplex. 100mbps_hd 100Mbps half duplex. 100mbps_fd 100Mbps full duplex. */ static char media[] = "autosense"; /* Operational parameters that are set at compile time. */ /* As Etherboot uses a Polling driver we can keep the number of rings to the minimum number required. In general that is 1 transmit and 4 receive receive rings. However some cards require that there be a minimum of 2 rings */ #define TX_RING_SIZE 2 #define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */ #define RX_RING_SIZE 4 /* Operational parameters that usually are not changed. */ /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIME_OUT (4*HZ) #define PKT_BUF_SZ 1536 /* Offsets to the device registers. Unlike software-only systems, device drivers interact with complex hardware. It's not useful to define symbolic names for every register bit in the device. The name can only partially document the semantics and make the driver longer and more difficult to read. In general, only the important configuration values or bits changed multiple times should be defined symbolically. */ enum alta_offsets { DMACtrl = 0x00, TxListPtr = 0x04, TxDMABurstThresh = 0x08, TxDMAUrgentThresh = 0x09, TxDMAPollPeriod = 0x0a, RxDMAStatus = 0x0c, RxListPtr = 0x10, DebugCtrl0 = 0x1a, DebugCtrl1 = 0x1c, RxDMABurstThresh = 0x14, RxDMAUrgentThresh = 0x15, RxDMAPollPeriod = 0x16, LEDCtrl = 0x1a, ASICCtrl = 0x30, EEData = 0x34, EECtrl = 0x36, TxStartThresh = 0x3c, RxEarlyThresh = 0x3e, FlashAddr = 0x40, FlashData = 0x44, TxStatus = 0x46, TxFrameId = 0x47, DownCounter = 0x18, IntrClear = 0x4a, IntrEnable = 0x4c, IntrStatus = 0x4e, MACCtrl0 = 0x50, MACCtrl1 = 0x52, StationAddr = 0x54, MaxFrameSize = 0x5A, RxMode = 0x5c, MIICtrl = 0x5e, MulticastFilter0 = 0x60, MulticastFilter1 = 0x64, RxOctetsLow = 0x68, RxOctetsHigh = 0x6a, TxOctetsLow = 0x6c, TxOctetsHigh = 0x6e, TxFramesOK = 0x70, RxFramesOK = 0x72, StatsCarrierError = 0x74, StatsLateColl = 0x75, StatsMultiColl = 0x76, StatsOneColl = 0x77, StatsTxDefer = 0x78, RxMissed = 0x79, StatsTxXSDefer = 0x7a, StatsTxAbort = 0x7b, StatsBcastTx = 0x7c, StatsBcastRx = 0x7d, StatsMcastTx = 0x7e, StatsMcastRx = 0x7f, /* Aliased and bogus values! */ RxStatus = 0x0c, }; enum ASICCtrl_HiWord_bit { GlobalReset = 0x0001, RxReset = 0x0002, TxReset = 0x0004, DMAReset = 0x0008, FIFOReset = 0x0010, NetworkReset = 0x0020, HostReset = 0x0040, ResetBusy = 0x0400, }; /* Bits in the interrupt status/mask registers. */ enum intr_status_bits { IntrSummary = 0x0001, IntrPCIErr = 0x0002, IntrMACCtrl = 0x0008, IntrTxDone = 0x0004, IntrRxDone = 0x0010, IntrRxStart = 0x0020, IntrDrvRqst = 0x0040, StatsMax = 0x0080, LinkChange = 0x0100, IntrTxDMADone = 0x0200, IntrRxDMADone = 0x0400, }; /* Bits in the RxMode register. */ enum rx_mode_bits { AcceptAllIPMulti = 0x20, AcceptMultiHash = 0x10, AcceptAll = 0x08, AcceptBroadcast = 0x04, AcceptMulticast = 0x02, AcceptMyPhys = 0x01, }; /* Bits in MACCtrl. */ enum mac_ctrl0_bits { EnbFullDuplex = 0x20, EnbRcvLargeFrame = 0x40, EnbFlowCtrl = 0x100, EnbPassRxCRC = 0x200, }; enum mac_ctrl1_bits { StatsEnable = 0x0020, StatsDisable = 0x0040, StatsEnabled = 0x0080, TxEnable = 0x0100, TxDisable = 0x0200, TxEnabled = 0x0400, RxEnable = 0x0800, RxDisable = 0x1000, RxEnabled = 0x2000, }; /* The Rx and Tx buffer descriptors. Using only 32 bit fields simplifies software endian correction. This structure must be aligned, and should avoid spanning cache lines. */ struct netdev_desc { u32 next_desc; u32 status; u32 addr; u32 length; }; /* Bits in netdev_desc.status */ enum desc_status_bits { DescOwn = 0x8000, DescEndPacket = 0x4000, DescEndRing = 0x2000, LastFrag = 0x80000000, DescIntrOnTx = 0x8000, DescIntrOnDMADone = 0x80000000, DisableAlign = 0x00000001, }; /********************************************** * Descriptor Ring and Buffer defination ***********************************************/ /* Define the TX Descriptor */ static struct netdev_desc tx_ring[TX_RING_SIZE]; /* Define the RX Descriptor */ static struct netdev_desc rx_ring[RX_RING_SIZE]; /* Create a static buffer of size PKT_BUF_SZ for each RX and TX descriptor. All descriptors point to a part of this buffer */ struct { unsigned char txb[PKT_BUF_SZ * TX_RING_SIZE]; unsigned char rxb[RX_RING_SIZE * PKT_BUF_SZ]; } rx_tx_buf __shared; #define rxb rx_tx_buf.rxb #define txb rx_tx_buf.txb /* FIXME: Move BASE to the private structure */ static u32 BASE; #define EEPROM_SIZE 128 enum pci_id_flags_bits { PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4, PCI_ADDR0 = 0 << 4, PCI_ADDR1 = 1 << 4, PCI_ADDR2 = 2 << 4, PCI_ADDR3 = 3 << 4, }; enum chip_capability_flags { CanHaveMII = 1, KendinPktDropBug = 2, }; #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0) #define MII_CNT 4 static struct sundance_private { const char *nic_name; /* Frequently used values */ unsigned int cur_rx; /* Producer/consumer ring indicies */ unsigned int mtu; /* These values keep track of the tranceiver/media in use */ unsigned int flowctrl:1; unsigned int an_enable:1; unsigned int speed; /* MII tranceiver section */ struct mii_if_info mii_if; int mii_preamble_required; unsigned char phys[MII_CNT]; unsigned char pci_rev_id; } sdx; static struct sundance_private *sdc; /* Station Address location within the EEPROM */ #define EEPROM_SA_OFFSET 0x10 #define DEFAULT_INTR (IntrRxDMADone | IntrPCIErr | \ IntrDrvRqst | IntrTxDone | StatsMax | \ LinkChange) static int eeprom_read(long ioaddr, int location); static int mdio_read(struct nic *nic, int phy_id, unsigned int location); static void mdio_write(struct nic *nic, int phy_id, unsigned int location, int value); static void set_rx_mode(struct nic *nic); static void check_duplex(struct nic *nic) { int mii_lpa = mdio_read(nic, sdc->phys[0], MII_LPA); int negotiated = mii_lpa & sdc->mii_if.advertising; int duplex; /* Force media */ if (!sdc->an_enable || mii_lpa == 0xffff) { if (sdc->mii_if.full_duplex) outw(inw(BASE + MACCtrl0) | EnbFullDuplex, BASE + MACCtrl0); return; } /* Autonegotiation */ duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040; if (sdc->mii_if.full_duplex != duplex) { sdc->mii_if.full_duplex = duplex; DBG ("%s: Setting %s-duplex based on MII #%d " "negotiated capability %4.4x.\n", sdc->nic_name, duplex ? "full" : "half", sdc->phys[0], negotiated ); outw(inw(BASE + MACCtrl0) | duplex ? 0x20 : 0, BASE + MACCtrl0); } } /************************************************************************** * init_ring - setup the tx and rx descriptors *************************************************************************/ static void init_ring(struct nic *nic __unused) { int i; sdc->cur_rx = 0; /* Initialize all the Rx descriptors */ for (i = 0; i < RX_RING_SIZE; i++) { rx_ring[i].next_desc = virt_to_le32desc(&rx_ring[i + 1]); rx_ring[i].status = 0; rx_ring[i].length = 0; rx_ring[i].addr = 0; } /* Mark the last entry as wrapping the ring */ rx_ring[i - 1].next_desc = virt_to_le32desc(&rx_ring[0]); for (i = 0; i < RX_RING_SIZE; i++) { rx_ring[i].addr = virt_to_le32desc(&rxb[i * PKT_BUF_SZ]); rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LastFrag); } /* We only use one transmit buffer, but two * descriptors so transmit engines have somewhere * to point should they feel the need */ tx_ring[0].status = 0x00000000; tx_ring[0].addr = virt_to_bus(&txb[0]); tx_ring[0].next_desc = 0; /* virt_to_bus(&tx_ring[1]); */ /* This descriptor is never used */ tx_ring[1].status = 0x00000000; tx_ring[1].addr = 0; /*virt_to_bus(&txb[0]); */ tx_ring[1].next_desc = 0; /* Mark the last entry as wrapping the ring, * though this should never happen */ tx_ring[1].length = cpu_to_le32(LastFrag | PKT_BUF_SZ); } /************************************************************************** * RESET - Reset Adapter * ***********************************************************************/ static void sundance_reset(struct nic *nic) { int i; init_ring(nic); outl(virt_to_le32desc(&rx_ring[0]), BASE + RxListPtr); /* The Tx List Pointer is written as packets are queued */ /* Initialize other registers. */ /* __set_mac_addr(dev); */ { u16 addr16; addr16 = (nic->node_addr[0] | (nic->node_addr[1] << 8)); outw(addr16, BASE + StationAddr); addr16 = (nic->node_addr[2] | (nic->node_addr[3] << 8)); outw(addr16, BASE + StationAddr + 2); addr16 = (nic->node_addr[4] | (nic->node_addr[5] << 8)); outw(addr16, BASE + StationAddr + 4); } outw(sdc->mtu + 14, BASE + MaxFrameSize); if (sdc->mtu > 2047) /* this will never happen with default options */ outl(inl(BASE + ASICCtrl) | 0x0c, BASE + ASICCtrl); set_rx_mode(nic); outw(0, BASE + DownCounter); /* Set the chip to poll every N*30nsec */ outb(100, BASE + RxDMAPollPeriod); /* Fix DFE-580TX packet drop issue */ if (sdc->pci_rev_id >= 0x14) writeb(0x01, BASE + DebugCtrl1); outw(RxEnable | TxEnable, BASE + MACCtrl1); /* Construct a perfect filter frame with the mac address as first match * and broadcast for all others */ for (i = 0; i < 192; i++) txb[i] = 0xFF; txb[0] = nic->node_addr[0]; txb[1] = nic->node_addr[1]; txb[2] = nic->node_addr[2]; txb[3] = nic->node_addr[3]; txb[4] = nic->node_addr[4]; txb[5] = nic->node_addr[5]; DBG ( "%s: Done sundance_reset, status: Rx %hX Tx %hX " "MAC Control %hX, %hX %hX\n", sdc->nic_name, (int) inl(BASE + RxStatus), (int) inw(BASE + TxStatus), (int) inl(BASE + MACCtrl0), (int) inw(BASE + MACCtrl1), (int) inw(BASE + MACCtrl0) ); } /************************************************************************** IRQ - Wait for a frame ***************************************************************************/ static void sundance_irq ( struct nic *nic, irq_action_t action ) { unsigned int intr_status; switch ( action ) { case DISABLE : case ENABLE : intr_status = inw(nic->ioaddr + IntrStatus); intr_status = intr_status & ~DEFAULT_INTR; if ( action == ENABLE ) intr_status = intr_status | DEFAULT_INTR; outw(intr_status, nic->ioaddr + IntrEnable); break; case FORCE : outw(0x0200, BASE + ASICCtrl); break; } } /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int sundance_poll(struct nic *nic, int retreive) { /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ /* nic->packetlen should contain length of data */ int entry = sdc->cur_rx % RX_RING_SIZE; u32 frame_status = le32_to_cpu(rx_ring[entry].status); int intr_status; int pkt_len = 0; if (!(frame_status & DescOwn)) return 0; /* There is a packet ready */ if(!retreive) return 1; intr_status = inw(nic->ioaddr + IntrStatus); outw(intr_status, nic->ioaddr + IntrStatus); pkt_len = frame_status & 0x1fff; if (frame_status & 0x001f4000) { DBG ( "Polling frame_status error\n" ); /* Do we really care about this */ } else { if (pkt_len < rx_copybreak) { /* FIXME: What should happen Will this ever occur */ printf("Poll Error: pkt_len < rx_copybreak"); } else { nic->packetlen = pkt_len; memcpy(nic->packet, rxb + (sdc->cur_rx * PKT_BUF_SZ), nic->packetlen); } } rx_ring[entry].length = cpu_to_le32(PKT_BUF_SZ | LastFrag); rx_ring[entry].status = 0; entry++; sdc->cur_rx = entry % RX_RING_SIZE; outw(DEFAULT_INTR & ~(IntrRxDone|IntrRxDMADone), nic->ioaddr + IntrStatus); return 1; } /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void sundance_transmit(struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) { /* Packet */ u16 nstype; u32 to; /* Disable the Tx */ outw(TxDisable, BASE + MACCtrl1); memcpy(txb, d, ETH_ALEN); memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN); nstype = htons((u16) t); memcpy(txb + 2 * ETH_ALEN, (u8 *) & nstype, 2); memcpy(txb + ETH_HLEN, p, s); s += ETH_HLEN; s &= 0x0FFF; while (s < ETH_ZLEN) txb[s++] = '\0'; /* Setup the transmit descriptor */ tx_ring[0].length = cpu_to_le32(s | LastFrag); tx_ring[0].status = cpu_to_le32(0x00000001); /* Point to transmit descriptor */ outl(virt_to_le32desc(&tx_ring[0]), BASE + TxListPtr); /* Enable Tx */ outw(TxEnable, BASE + MACCtrl1); /* Trigger an immediate send */ outw(0, BASE + TxStatus); to = currticks() + TX_TIME_OUT; while (!(tx_ring[0].status & 0x00010000) && (currticks() < to)); /* wait */ if (currticks() >= to) { printf("TX Time Out"); } /* Disable Tx */ outw(TxDisable, BASE + MACCtrl1); } /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void sundance_disable ( struct nic *nic __unused ) { /* put the card in its initial state */ /* This function serves 3 purposes. * This disables DMA and interrupts so we don't receive * unexpected packets or interrupts from the card after * etherboot has finished. * This frees resources so etherboot may use * this driver on another interface * This allows etherboot to reinitialize the interface * if something is something goes wrong. */ outw(0x0000, BASE + IntrEnable); /* Stop the Chipchips Tx and Rx Status */ outw(TxDisable | RxDisable | StatsDisable, BASE + MACCtrl1); } static struct nic_operations sundance_operations = { .connect = dummy_connect, .poll = sundance_poll, .transmit = sundance_transmit, .irq = sundance_irq, }; /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside ***************************************************************************/ static int sundance_probe ( struct nic *nic, struct pci_device *pci ) { u8 ee_data[EEPROM_SIZE]; u16 mii_ctl; int i; int speed; if (pci->ioaddr == 0) return 0; /* BASE is used throughout to address the card */ BASE = pci->ioaddr; printf(" sundance.c: Found %s Vendor=0x%hX Device=0x%hX\n", pci->driver_name, pci->vendor, pci->device); /* Get the MAC Address by reading the EEPROM */ for (i = 0; i < 3; i++) { ((u16 *) ee_data)[i] = le16_to_cpu(eeprom_read(BASE, i + EEPROM_SA_OFFSET)); } /* Update the nic structure with the MAC Address */ for (i = 0; i < ETH_ALEN; i++) { nic->node_addr[i] = ee_data[i]; } /* Set the card as PCI Bus Master */ adjust_pci_device(pci); // sdc->mii_if.dev = pci; // sdc->mii_if.phy_id_mask = 0x1f; // sdc->mii_if.reg_num_mask = 0x1f; /* point to private storage */ sdc = &sdx; sdc->nic_name = pci->driver_name; sdc->mtu = mtu; pci_read_config_byte(pci, PCI_REVISION_ID, &sdc->pci_rev_id); DBG ( "Device revision id: %hx\n", sdc->pci_rev_id ); /* Print out some hardware info */ DBG ( "%s: %s at ioaddr %hX, ", pci->driver_name, nic->node_addr, (unsigned int) BASE); sdc->mii_preamble_required = 0; if (1) { int phy, phy_idx = 0; sdc->phys[0] = 1; /* Default Setting */ sdc->mii_preamble_required++; for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) { int mii_status = mdio_read(nic, phy, MII_BMSR); if (mii_status != 0xffff && mii_status != 0x0000) { sdc->phys[phy_idx++] = phy; sdc->mii_if.advertising = mdio_read(nic, phy, MII_ADVERTISE); if ((mii_status & 0x0040) == 0) sdc->mii_preamble_required++; DBG ( "%s: MII PHY found at address %d, status " "%hX advertising %hX\n", sdc->nic_name, phy, mii_status, sdc->mii_if.advertising ); } } sdc->mii_preamble_required--; if (phy_idx == 0) printf("%s: No MII transceiver found!\n", sdc->nic_name); sdc->mii_if.phy_id = sdc->phys[0]; } /* Parse override configuration */ sdc->an_enable = 1; if (strcasecmp(media, "autosense") != 0) { sdc->an_enable = 0; if (strcasecmp(media, "100mbps_fd") == 0 || strcasecmp(media, "4") == 0) { sdc->speed = 100; sdc->mii_if.full_duplex = 1; } else if (strcasecmp(media, "100mbps_hd") == 0 || strcasecmp(media, "3") == 0) { sdc->speed = 100; sdc->mii_if.full_duplex = 0; } else if (strcasecmp(media, "10mbps_fd") == 0 || strcasecmp(media, "2") == 0) { sdc->speed = 10; sdc->mii_if.full_duplex = 1; } else if (strcasecmp(media, "10mbps_hd") == 0 || strcasecmp(media, "1") == 0) { sdc->speed = 10; sdc->mii_if.full_duplex = 0; } else { sdc->an_enable = 1; } } if (flowctrl == 1) sdc->flowctrl = 1; /* Fibre PHY? */ if (inl(BASE + ASICCtrl) & 0x80) { /* Default 100Mbps Full */ if (sdc->an_enable) { sdc->speed = 100; sdc->mii_if.full_duplex = 1; sdc->an_enable = 0; } } /* The Linux driver uses flow control and resets the link here. This means the mii section from above would need to be re done I believe. Since it serves no real purpose leave it out. */ /* Force media type */ if (!sdc->an_enable) { mii_ctl = 0; mii_ctl |= (sdc->speed == 100) ? BMCR_SPEED100 : 0; mii_ctl |= (sdc->mii_if.full_duplex) ? BMCR_FULLDPLX : 0; mdio_write(nic, sdc->phys[0], MII_BMCR, mii_ctl); printf("Override speed=%d, %s duplex\n", sdc->speed, sdc->mii_if.full_duplex ? "Full" : "Half"); } /* Reset the chip to erase previous misconfiguration */ DBG ( "ASIC Control is %#x\n", inl(BASE + ASICCtrl) ); outw(0x007f, BASE + ASICCtrl + 2); /* * wait for reset to complete * this is heavily inspired by the linux sundance driver * according to the linux driver it can take up to 1ms for the reset * to complete */ i = 0; while(inl(BASE + ASICCtrl) & (ResetBusy << 16)) { if(i++ >= 10) { DBG("sundance: NIC reset did not complete.\n"); break; } udelay(100); } DBG ( "ASIC Control is now %#x.\n", inl(BASE + ASICCtrl) ); sundance_reset(nic); if (sdc->an_enable) { u16 mii_advertise, mii_lpa; mii_advertise = mdio_read(nic, sdc->phys[0], MII_ADVERTISE); mii_lpa = mdio_read(nic, sdc->phys[0], MII_LPA); mii_advertise &= mii_lpa; if (mii_advertise & ADVERTISE_100FULL) sdc->speed = 100; else if (mii_advertise & ADVERTISE_100HALF) sdc->speed = 100; else if (mii_advertise & ADVERTISE_10FULL) sdc->speed = 10; else if (mii_advertise & ADVERTISE_10HALF) sdc->speed = 10; } else { mii_ctl = mdio_read(nic, sdc->phys[0], MII_BMCR); speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10; sdc->speed = speed; printf("%s: Link changed: %dMbps ,", sdc->nic_name, speed); printf("%s duplex.\n", (mii_ctl & BMCR_FULLDPLX) ? "full" : "half"); } check_duplex(nic); if (sdc->flowctrl && sdc->mii_if.full_duplex) { outw(inw(BASE + MulticastFilter1 + 2) | 0x0200, BASE + MulticastFilter1 + 2); outw(inw(BASE + MACCtrl0) | EnbFlowCtrl, BASE + MACCtrl0); } printf("%dMbps, %s-Duplex\n", sdc->speed, sdc->mii_if.full_duplex ? "Full" : "Half"); /* point to NIC specific routines */ nic->nic_op = &sundance_operations; nic->irqno = pci->irq; nic->ioaddr = BASE; return 1; } /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */ static int eeprom_read(long ioaddr, int location) { int boguscnt = 10000; /* Typical 1900 ticks */ outw(0x0200 | (location & 0xff), ioaddr + EECtrl); do { if (!(inw(ioaddr + EECtrl) & 0x8000)) { return inw(ioaddr + EEData); } } while (--boguscnt > 0); return 0; } /* MII transceiver control section. Read and write the MII registers using software-generated serial MDIO protocol. See the MII specifications or DP83840A data sheet for details. The maximum data clock rate is 2.5 Mhz. The timing is decoupled from the processor clock by flushing the write from the CPU write buffer with a following read, and using PCI transaction time. */ #define mdio_in(mdio_addr) inb(mdio_addr) #define mdio_out(value, mdio_addr) outb(value, mdio_addr) #define mdio_delay(mdio_addr) inb(mdio_addr) enum mii_reg_bits { MDIO_ShiftClk = 0x0001, MDIO_Data = 0x0002, MDIO_EnbOutput = 0x0004, }; #define MDIO_EnbIn (0) #define MDIO_WRITE0 (MDIO_EnbOutput) #define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput) /* Generate the preamble required for initial synchronization and a few older transceivers. */ static void mdio_sync(long mdio_addr) { int bits = 32; /* Establish sync by sending at least 32 logic ones. */ while (--bits >= 0) { mdio_out(MDIO_WRITE1, mdio_addr); mdio_delay(mdio_addr); mdio_out(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr); mdio_delay(mdio_addr); } } static int mdio_read(struct nic *nic __unused, int phy_id, unsigned int location) { long mdio_addr = BASE + MIICtrl; int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location; int i, retval = 0; if (sdc->mii_preamble_required) mdio_sync(mdio_addr); /* Shift the read command bits out. */ for (i = 15; i >= 0; i--) { int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; mdio_out(dataval, mdio_addr); mdio_delay(mdio_addr); mdio_out(dataval | MDIO_ShiftClk, mdio_addr); mdio_delay(mdio_addr); } /* Read the two transition, 16 data, and wire-idle bits. */ for (i = 19; i > 0; i--) { mdio_out(MDIO_EnbIn, mdio_addr); mdio_delay(mdio_addr); retval = (retval << 1) | ((mdio_in(mdio_addr) & MDIO_Data) ? 1 : 0); mdio_out(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr); mdio_delay(mdio_addr); } return (retval >> 1) & 0xffff; } static void mdio_write(struct nic *nic __unused, int phy_id, unsigned int location, int value) { long mdio_addr = BASE + MIICtrl; int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value; int i; if (sdc->mii_preamble_required) mdio_sync(mdio_addr); /* Shift the command bits out. */ for (i = 31; i >= 0; i--) { int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; mdio_out(dataval, mdio_addr); mdio_delay(mdio_addr); mdio_out(dataval | MDIO_ShiftClk, mdio_addr); mdio_delay(mdio_addr); } /* Clear out extra bits. */ for (i = 2; i > 0; i--) { mdio_out(MDIO_EnbIn, mdio_addr); mdio_delay(mdio_addr); mdio_out(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr); mdio_delay(mdio_addr); } return; } static void set_rx_mode(struct nic *nic __unused) { int i; u16 mc_filter[4]; /* Multicast hash filter */ u32 rx_mode; memset(mc_filter, 0xff, sizeof(mc_filter)); rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; if (sdc->mii_if.full_duplex && sdc->flowctrl) mc_filter[3] |= 0x0200; for (i = 0; i < 4; i++) outw(mc_filter[i], BASE + MulticastFilter0 + i * 2); outb(rx_mode, BASE + RxMode); return; } static struct pci_device_id sundance_nics[] = { PCI_ROM(0x13f0, 0x0201, "sundance", "ST201 Sundance 'Alta' based Adaptor", 0), PCI_ROM(0x1186, 0x1002, "dfe530txs", "D-Link DFE530TXS (Sundance ST201 Alta)", 0), PCI_ROM(0x13f0, 0x0200, "ip100a", "IC+ IP100A", 0), }; PCI_DRIVER ( sundance_driver, sundance_nics, PCI_NO_CLASS ); DRIVER ( "SUNDANCE/PCI", nic_driver, pci_driver, sundance_driver, sundance_probe, sundance_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/pnic.c0000664000000000000000000002106512524662415020310 0ustar /************************************************************************** Etherboot - BOOTP/TFTP Bootstrap Program Bochs Pseudo NIC driver for Etherboot ***************************************************************************/ /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * See pnic_api.h for an explanation of the Bochs Pseudo NIC. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include "pnic_api.h" struct pnic { unsigned short ioaddr; }; /* * Utility functions: issue a PNIC command, retrieve result. Use * pnic_command_quiet if you don't want failure codes to be * automatically printed. Returns the PNIC status code. * * Set output_length to NULL only if you expect to receive exactly * output_max_length bytes, otherwise it'll complain that you didn't * get enough data (on the assumption that if you not interested in * discovering the output length then you're expecting a fixed amount * of data). */ static uint16_t pnic_command_quiet ( struct pnic *pnic, uint16_t command, const void *input, uint16_t input_length, void *output, uint16_t output_max_length, uint16_t *output_length ) { uint16_t status; uint16_t _output_length; if ( input != NULL ) { /* Write input length */ outw ( input_length, pnic->ioaddr + PNIC_REG_LEN ); /* Write input data */ outsb ( pnic->ioaddr + PNIC_REG_DATA, input, input_length ); } /* Write command */ outw ( command, pnic->ioaddr + PNIC_REG_CMD ); /* Retrieve status */ status = inw ( pnic->ioaddr + PNIC_REG_STAT ); /* Retrieve output length */ _output_length = inw ( pnic->ioaddr + PNIC_REG_LEN ); if ( output_length == NULL ) { if ( _output_length != output_max_length ) { printf ( "pnic_command %#hx: wrong data length " "returned (expected %d, got %d)\n", command, output_max_length, _output_length ); } } else { *output_length = _output_length; } if ( output != NULL ) { if ( _output_length > output_max_length ) { printf ( "pnic_command %#hx: output buffer too small " "(have %d, need %d)\n", command, output_max_length, _output_length ); _output_length = output_max_length; } /* Retrieve output data */ insb ( pnic->ioaddr + PNIC_REG_DATA, output, _output_length ); } return status; } static uint16_t pnic_command ( struct pnic *pnic, uint16_t command, const void *input, uint16_t input_length, void *output, uint16_t output_max_length, uint16_t *output_length ) { uint16_t status = pnic_command_quiet ( pnic, command, input, input_length, output, output_max_length, output_length ); if ( status == PNIC_STATUS_OK ) return status; printf ( "PNIC command %#hx (len %#hx) failed with status %#hx\n", command, input_length, status ); return status; } /* Check API version matches that of NIC */ static int pnic_api_check ( uint16_t api_version ) { if ( api_version != PNIC_API_VERSION ) { printf ( "Warning: API version mismatch! " "(NIC's is %d.%d, ours is %d.%d)\n", api_version >> 8, api_version & 0xff, PNIC_API_VERSION >> 8, PNIC_API_VERSION & 0xff ); } if ( api_version < PNIC_API_VERSION ) { printf ( "** You may need to update your copy of Bochs **\n" ); } return ( api_version == PNIC_API_VERSION ); } /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static void pnic_poll ( struct net_device *netdev ) { struct pnic *pnic = netdev->priv; struct io_buffer *iobuf; uint16_t length; uint16_t qlen; /* Fetch all available packets */ while ( 1 ) { if ( pnic_command ( pnic, PNIC_CMD_RECV_QLEN, NULL, 0, &qlen, sizeof ( qlen ), NULL ) != PNIC_STATUS_OK ) return; if ( qlen == 0 ) return; iobuf = alloc_iob ( ETH_FRAME_LEN ); if ( ! iobuf ) { DBG ( "could not allocate buffer\n" ); netdev_rx_err ( netdev, NULL, -ENOMEM ); return; } if ( pnic_command ( pnic, PNIC_CMD_RECV, NULL, 0, iobuf->data, ETH_FRAME_LEN, &length ) != PNIC_STATUS_OK ) { netdev_rx_err ( netdev, iobuf, -EIO ); return; } iob_put ( iobuf, length ); netdev_rx ( netdev, iobuf ); } } /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static int pnic_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { struct pnic *pnic = netdev->priv; /* Pad the packet */ iob_pad ( iobuf, ETH_ZLEN ); /* Send packet */ pnic_command ( pnic, PNIC_CMD_XMIT, iobuf->data, iob_len ( iobuf ), NULL, 0, NULL ); netdev_tx_complete ( netdev, iobuf ); return 0; } /************************************************************************** OPEN - Open network device ***************************************************************************/ static int pnic_open ( struct net_device *netdev __unused ) { /* Nothing to do */ return 0; } /************************************************************************** CLOSE - Close network device ***************************************************************************/ static void pnic_close ( struct net_device *netdev __unused ) { /* Nothing to do */ } /************************************************************************** IRQ - Enable/disable interrupts ***************************************************************************/ static void pnic_irq ( struct net_device *netdev, int enable ) { struct pnic *pnic = netdev->priv; uint8_t mask = ( enable ? 1 : 0 ); pnic_command ( pnic, PNIC_CMD_MASK_IRQ, &mask, sizeof ( mask ), NULL, 0, NULL ); } /************************************************************************** OPERATIONS TABLE ***************************************************************************/ static struct net_device_operations pnic_operations = { .open = pnic_open, .close = pnic_close, .transmit = pnic_transmit, .poll = pnic_poll, .irq = pnic_irq, }; /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void pnic_remove ( struct pci_device *pci ) { struct net_device *netdev = pci_get_drvdata ( pci ); struct pnic *pnic = netdev->priv; unregister_netdev ( netdev ); pnic_command ( pnic, PNIC_CMD_RESET, NULL, 0, NULL, 0, NULL ); netdev_nullify ( netdev ); netdev_put ( netdev ); } /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside ***************************************************************************/ static int pnic_probe ( struct pci_device *pci, const struct pci_device_id *id __unused ) { struct net_device *netdev; struct pnic *pnic; uint16_t api_version; uint16_t status; int rc; /* Allocate net device */ netdev = alloc_etherdev ( sizeof ( *pnic ) ); if ( ! netdev ) return -ENOMEM; netdev_init ( netdev, &pnic_operations ); pnic = netdev->priv; pci_set_drvdata ( pci, netdev ); netdev->dev = &pci->dev; pnic->ioaddr = pci->ioaddr; /* Fix up PCI device */ adjust_pci_device ( pci ); /* API version check */ status = pnic_command_quiet ( pnic, PNIC_CMD_API_VER, NULL, 0, &api_version, sizeof ( api_version ), NULL ); if ( status != PNIC_STATUS_OK ) { printf ( "PNIC failed installation check, code %#hx\n", status ); rc = -EIO; goto err; } pnic_api_check ( api_version ); /* Get MAC address */ status = pnic_command ( pnic, PNIC_CMD_READ_MAC, NULL, 0, netdev->hw_addr, ETH_ALEN, NULL ); /* Mark as link up; PNIC has no concept of link state */ netdev_link_up ( netdev ); /* Register network device */ if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err; return 0; err: /* Free net device */ netdev_nullify ( netdev ); netdev_put ( netdev ); return rc; } static struct pci_device_id pnic_nics[] = { /* genrules.pl doesn't let us use macros for PCI IDs...*/ PCI_ROM ( 0xfefe, 0xefef, "pnic", "Bochs Pseudo NIC Adaptor", 0 ), }; struct pci_driver pnic_driver __pci_driver = { .ids = pnic_nics, .id_count = ( sizeof ( pnic_nics ) / sizeof ( pnic_nics[0] ) ), .probe = pnic_probe, .remove = pnic_remove, }; debian/grub-extras/disabled/gpxe/src/drivers/net/pnic_api.h0000664000000000000000000000347712524662415021155 0ustar /* * Constants etc. for the Bochs/Etherboot pseudo-NIC * * This header file must be valid C and C++. * * Operation of the pseudo-NIC (PNIC) is pretty simple. To write a * command plus data, first write the length of the data to * PNIC_REG_LEN, then write the data a byte at a type to * PNIC_REG_DATA, then write the command code to PNIC_REG_CMD. The * status will be available from PNIC_REG_STAT. The length of any * data returned will be in PNIC_REG_LEN and can be read a byte at a * time from PNIC_REG_DATA. */ FILE_LICENCE ( GPL2_OR_LATER ); /* * PCI parameters */ #define PNIC_PCI_VENDOR 0xfefe /* Hopefully these won't clash with */ #define PNIC_PCI_DEVICE 0xefef /* any real PCI device IDs. */ /* * 'Hardware' register addresses, offset from io_base */ #define PNIC_REG_CMD 0x00 /* Command register, 2 bytes, write only */ #define PNIC_REG_STAT 0x00 /* Status register, 2 bytes, read only */ #define PNIC_REG_LEN 0x02 /* Length register, 2 bytes, read-write */ #define PNIC_REG_DATA 0x04 /* Data port, 1 byte, read-write */ /* * PNIC_MAX_REG used in Bochs to claim i/o space */ #define PNIC_MAX_REG 0x04 /* * Command code definitions: write these into PNIC_REG_CMD */ #define PNIC_CMD_NOOP 0x0000 #define PNIC_CMD_API_VER 0x0001 #define PNIC_CMD_READ_MAC 0x0002 #define PNIC_CMD_RESET 0x0003 #define PNIC_CMD_XMIT 0x0004 #define PNIC_CMD_RECV 0x0005 #define PNIC_CMD_RECV_QLEN 0x0006 #define PNIC_CMD_MASK_IRQ 0x0007 #define PNIC_CMD_FORCE_IRQ 0x0008 /* * Status code definitions: read these from PNIC_REG_STAT * * We avoid using status codes that might be confused with * randomly-read data (e.g. 0x0000, 0xffff etc.) */ #define PNIC_STATUS_OK 0x4f4b /* 'OK' */ #define PNIC_STATUS_UNKNOWN_CMD 0x3f3f /* '??' */ /* * Other miscellaneous information */ #define PNIC_API_VERSION 0x0101 /* 1.1 */ debian/grub-extras/disabled/gpxe/src/drivers/net/prism2.c0000664000000000000000000006674312524662415020607 0ustar /************************************************************************** Etherboot - BOOTP/TFTP Bootstrap Program Prism2 NIC driver for Etherboot Written by Michael Brown of Fen Systems Ltd $Id$ ***************************************************************************/ /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include /* * Hard-coded SSID * Leave blank in order to connect to any available SSID */ static const char hardcoded_ssid[] = ""; /* * Maximum number of info packets to wait for on a join attempt. * Some APs (including the Linksys WAP11) will send a "you are disconnected" packet * before sending the "you are connected" packet, if the card has previously been * attached to the AP. * * 2 is probably a sensible value, but YMMV. */ #define MAX_JOIN_INFO_COUNT 2 /* * Type of Prism2 interface to support * If not already defined, select PLX */ #ifndef WLAN_HOSTIF #define WLAN_HOSTIF WLAN_PLX #endif /* * Include wlan_compat, p80211 and hfa384x header files from Linux Prism2 driver * We need to hack some defines in order to avoid compiling kernel-specific routines */ #define __LINUX_WLAN__ #undef __KERNEL__ #define __I386__ #include "wlan_compat.h" #include "p80211hdr.h" #include "hfa384x.h" #define BAP_TIMEOUT ( 5000 ) /* * A few hacks to make the coding environment more Linux-like. This makes it somewhat * quicker to convert code from the Linux Prism2 driver. */ #include #define __le16_to_cpu(x) (x) #define __le32_to_cpu(x) (x) #define __cpu_to_le16(x) (x) #define __cpu_to_le32(x) (x) #define hfa384x2host_16(n) (__le16_to_cpu((UINT16)(n))) #define hfa384x2host_32(n) (__le32_to_cpu((UINT32)(n))) #define host2hfa384x_16(n) (__cpu_to_le16((UINT16)(n))) #define host2hfa384x_32(n) (__cpu_to_le32((UINT32)(n))) /* * PLX9052 PCI register offsets * Taken from PLX9052 datasheet available from http://www.plxtech.com/download/9052/databook/9052db-20.pdf */ #define PLX_LOCAL_CONFIG_REGISTER_BASE ( PCI_BASE_ADDRESS_1 ) #define PLX_LOCAL_ADDRESS_SPACE_0_BASE ( PCI_BASE_ADDRESS_2 ) #define PLX_LOCAL_ADDRESS_SPACE_1_BASE ( PCI_BASE_ADDRESS_3 ) #define PLX_LOCAL_ADDRESS_SPACE_2_BASE ( PCI_BASE_ADDRESS_4 ) #define PLX_LOCAL_ADDRESS_SPACE_3_BASE ( PCI_BASE_ADDRESS_5 ) #define PRISM2_PLX_ATTR_MEM_BASE ( PLX_LOCAL_ADDRESS_SPACE_0_BASE ) #define PRISM2_PLX_IO_BASE ( PLX_LOCAL_ADDRESS_SPACE_1_BASE ) #define PRISM2_PCI_MEM_BASE ( PCI_BASE_ADDRESS_0 ) /* * PCMCIA CIS types * Taken from cistpl.h in pcmcia-cs */ #define CISTPL_VERS_1 ( 0x15 ) #define CISTPL_END ( 0xff ) #define CIS_STEP ( 2 ) #define CISTPL_HEADER_LEN ( 2 * CIS_STEP ) #define CISTPL_LEN_OFF ( 1 * CIS_STEP ) #define CISTPL_VERS_1_STR_OFF ( 4 * CIS_STEP ) /* * Prism2 constants * Taken from prism2sta.c in linux-wlan-ng */ #define COR_OFFSET ( 0x3e0 ) /* COR attribute offset of Prism2 PC card */ #define COR_VALUE ( 0x41 ) /* Enable PC card with irq in level trigger (but interrupts disabled) */ /* NIC specific static variables */ /* The hfa384x_t structure is used extensively in the Linux driver but is ifdef'd out in our include since __KERNEL__ is not defined. * This is a dummy version that contains only the fields we are interested in. */ typedef struct hfa384x { UINT32 iobase; void *membase; UINT16 lastcmd; UINT16 status; /* in host order */ UINT16 resp0; /* in host order */ UINT16 resp1; /* in host order */ UINT16 resp2; /* in host order */ UINT8 bssid[WLAN_BSSID_LEN]; } hfa384x_t; /* The global instance of the hardware (i.e. where we store iobase and membase, in the absence of anywhere better to put them */ static hfa384x_t hw_global = { 0, 0, 0, 0, 0, 0, 0, {0,0,0,0,0,0} }; /* * 802.11 headers in addition to those in hfa384x_tx_frame_t (LLC and SNAP) * Taken from p80211conv.h */ typedef struct wlan_llc { UINT8 dsap; UINT8 ssap; UINT8 ctl; } wlan_llc_t; static const wlan_llc_t wlan_llc_snap = { 0xaa, 0xaa, 0x03 }; /* LLC header indicating SNAP (?) */ #define WLAN_IEEE_OUI_LEN 3 typedef struct wlan_snap { UINT8 oui[WLAN_IEEE_OUI_LEN]; UINT16 type; } wlan_snap_t; typedef struct wlan_80211hdr { wlan_llc_t llc; wlan_snap_t snap; } wlan_80211hdr_t; /* * Function prototypes */ /* * Hardware-level hfa384x functions * These are based on the ones in hfa384x.h (which are ifdef'd out since __KERNEL__ is not defined). * Basically, these functions are the result of hand-evaluating all the ifdefs and defines in the hfa384x.h versions. */ /* Retrieve the value of one of the MAC registers. */ static inline UINT16 hfa384x_getreg( hfa384x_t *hw, UINT reg ) { #if (WLAN_HOSTIF == WLAN_PLX) return inw ( hw->iobase + reg ); #elif (WLAN_HOSTIF == WLAN_PCI) return readw ( hw->membase + reg ); #endif } /* Set the value of one of the MAC registers. */ static inline void hfa384x_setreg( hfa384x_t *hw, UINT16 val, UINT reg ) { #if (WLAN_HOSTIF == WLAN_PLX) outw ( val, hw->iobase + reg ); #elif (WLAN_HOSTIF == WLAN_PCI) writew ( val, hw->membase + reg ); #endif return; } /* * Noswap versions * Etherboot is i386 only, so swap and noswap are the same... */ static inline UINT16 hfa384x_getreg_noswap( hfa384x_t *hw, UINT reg ) { return hfa384x_getreg ( hw, reg ); } static inline void hfa384x_setreg_noswap( hfa384x_t *hw, UINT16 val, UINT reg ) { hfa384x_setreg ( hw, val, reg ); } /* * Low-level hfa384x functions * These are based on the ones in hfa384x.c, modified to work in the Etherboot environment. */ /* * hfa384x_docmd_wait * * Waits for availability of the Command register, then * issues the given command. Then polls the Evstat register * waiting for command completion. * Arguments: * hw device structure * cmd Command in host order * parm0 Parameter0 in host order * parm1 Parameter1 in host order * parm2 Parameter2 in host order * Returns: * 0 success * >0 command indicated error, Status and Resp0-2 are * in hw structure. */ static int hfa384x_docmd_wait( hfa384x_t *hw, UINT16 cmd, UINT16 parm0, UINT16 parm1, UINT16 parm2) { UINT16 reg = 0; UINT16 counter = 0; /* wait for the busy bit to clear */ counter = 0; reg = hfa384x_getreg(hw, HFA384x_CMD); while ( HFA384x_CMD_ISBUSY(reg) && (counter < 10) ) { reg = hfa384x_getreg(hw, HFA384x_CMD); counter++; udelay(10); } if (HFA384x_CMD_ISBUSY(reg)) { printf("hfa384x_cmd timeout(1), reg=0x%0hx.\n", reg); return -ETIMEDOUT; } /* busy bit clear, write command */ hfa384x_setreg(hw, parm0, HFA384x_PARAM0); hfa384x_setreg(hw, parm1, HFA384x_PARAM1); hfa384x_setreg(hw, parm2, HFA384x_PARAM2); hw->lastcmd = cmd; hfa384x_setreg(hw, cmd, HFA384x_CMD); /* Now wait for completion */ counter = 0; reg = hfa384x_getreg(hw, HFA384x_EVSTAT); /* Initialization is the problem. It takes about 100ms. "normal" commands are typically is about 200-400 us (I've never seen less than 200). Longer is better so that we're not hammering the bus. */ while ( !HFA384x_EVSTAT_ISCMD(reg) && (counter < 5000)) { reg = hfa384x_getreg(hw, HFA384x_EVSTAT); counter++; udelay(200); } if ( ! HFA384x_EVSTAT_ISCMD(reg) ) { printf("hfa384x_cmd timeout(2), reg=0x%0hx.\n", reg); return -ETIMEDOUT; } /* Read status and response */ hw->status = hfa384x_getreg(hw, HFA384x_STATUS); hw->resp0 = hfa384x_getreg(hw, HFA384x_RESP0); hw->resp1 = hfa384x_getreg(hw, HFA384x_RESP1); hw->resp2 = hfa384x_getreg(hw, HFA384x_RESP2); hfa384x_setreg(hw, HFA384x_EVACK_CMD, HFA384x_EVACK); return HFA384x_STATUS_RESULT_GET(hw->status); } /* * Prepare BAP for access. Assigns FID and RID, sets offset register * and waits for BAP to become available. * * Arguments: * hw device structure * id FID or RID, destined for the select register (host order) * offset An _even_ offset into the buffer for the given FID/RID. * Returns: * 0 success */ static int hfa384x_prepare_bap(hfa384x_t *hw, UINT16 id, UINT16 offset) { int result = 0; UINT16 reg; UINT16 i; /* Validate offset, buf, and len */ if ( (offset > HFA384x_BAP_OFFSET_MAX) || (offset % 2) ) { result = -EINVAL; } else { /* Write fid/rid and offset */ hfa384x_setreg(hw, id, HFA384x_SELECT0); udelay(10); hfa384x_setreg(hw, offset, HFA384x_OFFSET0); /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */ i = 0; do { reg = hfa384x_getreg(hw, HFA384x_OFFSET0); if ( i > 0 ) udelay(2); i++; } while ( i < BAP_TIMEOUT && HFA384x_OFFSET_ISBUSY(reg)); if ( i >= BAP_TIMEOUT ) { /* failure */ result = reg; } else if ( HFA384x_OFFSET_ISERR(reg) ){ /* failure */ result = reg; } } return result; } /* * Copy data from BAP to memory. * * Arguments: * hw device structure * id FID or RID, destined for the select register (host order) * offset An _even_ offset into the buffer for the given FID/RID. * buf ptr to array of bytes * len length of data to transfer in bytes * Returns: * 0 success */ static int hfa384x_copy_from_bap(hfa384x_t *hw, UINT16 id, UINT16 offset, void *buf, UINT len) { int result = 0; UINT8 *d = (UINT8*)buf; UINT16 i; UINT16 reg = 0; /* Prepare BAP */ result = hfa384x_prepare_bap ( hw, id, offset ); if ( result == 0 ) { /* Read even(len) buf contents from data reg */ for ( i = 0; i < (len & 0xfffe); i+=2 ) { *(UINT16*)(&(d[i])) = hfa384x_getreg_noswap(hw, HFA384x_DATA0); } /* If len odd, handle last byte */ if ( len % 2 ){ reg = hfa384x_getreg_noswap(hw, HFA384x_DATA0); d[len-1] = ((UINT8*)(®))[0]; } } if (result) { printf ( "copy_from_bap(%#hx, %#hx, %d) failed, result=%#hx\n", id, offset, len, result); } return result; } /* * Copy data from memory to BAP. * * Arguments: * hw device structure * id FID or RID, destined for the select register (host order) * offset An _even_ offset into the buffer for the given FID/RID. * buf ptr to array of bytes * len length of data to transfer in bytes * Returns: * 0 success */ static int hfa384x_copy_to_bap(hfa384x_t *hw, UINT16 id, UINT16 offset, void *buf, UINT len) { int result = 0; UINT8 *d = (UINT8*)buf; UINT16 i; UINT16 savereg; /* Prepare BAP */ result = hfa384x_prepare_bap ( hw, id, offset ); if ( result == 0 ) { /* Write even(len) buf contents to data reg */ for ( i = 0; i < (len & 0xfffe); i+=2 ) { hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), HFA384x_DATA0); } /* If len odd, handle last byte */ if ( len % 2 ){ savereg = hfa384x_getreg_noswap(hw, HFA384x_DATA0); result = hfa384x_prepare_bap ( hw, id, offset + (len & 0xfffe) ); if ( result == 0 ) { ((UINT8*)(&savereg))[0] = d[len-1]; hfa384x_setreg_noswap(hw, savereg, HFA384x_DATA0); } } } if (result) { printf ( "copy_to_bap(%#hx, %#hx, %d) failed, result=%#hx\n", id, offset, len, result); } return result; } /* * Request a given record to be copied to/from the record buffer. * * Arguments: * hw device structure * write [0|1] copy the record buffer to the given * configuration record. (host order) * rid RID of the record to read/write. (host order) * * Returns: * 0 success */ static inline int hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid) { return hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ACCESS) | HFA384x_CMD_WRITE_SET(write), rid, 0, 0); } /* * Performs the sequence necessary to read a config/info item. * * Arguments: * hw device structure * rid config/info record id (host order) * buf host side record buffer. Upon return it will * contain the body portion of the record (minus the * RID and len). * len buffer length (in bytes, should match record length) * * Returns: * 0 success */ static int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len) { int result = 0; hfa384x_rec_t rec; /* Request read of RID */ result = hfa384x_cmd_access( hw, 0, rid); if ( result ) { printf("Call to hfa384x_cmd_access failed\n"); return -1; } /* Copy out record length */ result = hfa384x_copy_from_bap( hw, rid, 0, &rec, sizeof(rec)); if ( result ) { return -1; } /* Validate the record length */ if ( ((hfa384x2host_16(rec.reclen)-1)*2) != len ) { /* note body len calculation in bytes */ printf ( "RID len mismatch, rid=%#hx hlen=%d fwlen=%d\n", rid, len, (hfa384x2host_16(rec.reclen)-1)*2); return -1; } /* Copy out record data */ result = hfa384x_copy_from_bap( hw, rid, sizeof(rec), buf, len); return result; } /* * Performs the sequence necessary to read a 16/32 bit config/info item * and convert it to host order. * * Arguments: * hw device structure * rid config/info record id (in host order) * val ptr to 16/32 bit buffer to receive value (in host order) * * Returns: * 0 success */ #if 0 /* Not actually used anywhere */ static int hfa384x_drvr_getconfig16(hfa384x_t *hw, UINT16 rid, void *val) { int result = 0; result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT16)); if ( result == 0 ) { *((UINT16*)val) = hfa384x2host_16(*((UINT16*)val)); } return result; } #endif #if 0 /* Not actually used anywhere */ static int hfa384x_drvr_getconfig32(hfa384x_t *hw, UINT16 rid, void *val) { int result = 0; result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT32)); if ( result == 0 ) { *((UINT32*)val) = hfa384x2host_32(*((UINT32*)val)); } return result; } #endif /* * Performs the sequence necessary to write a config/info item. * * Arguments: * hw device structure * rid config/info record id (in host order) * buf host side record buffer * len buffer length (in bytes) * * Returns: * 0 success */ static int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len) { int result = 0; hfa384x_rec_t rec; rec.rid = host2hfa384x_16(rid); rec.reclen = host2hfa384x_16((len/2) + 1); /* note conversion to words, +1 for rid field */ /* write the record header */ result = hfa384x_copy_to_bap( hw, rid, 0, &rec, sizeof(rec)); if ( result ) { printf("Failure writing record header\n"); return -1; } /* write the record data (if there is any) */ if ( len > 0 ) { result = hfa384x_copy_to_bap( hw, rid, sizeof(rec), buf, len); if ( result ) { printf("Failure writing record data\n"); return -1; } } /* Trigger setting of record */ result = hfa384x_cmd_access( hw, 1, rid); return result; } /* * Performs the sequence necessary to write a 16/32 bit config/info item. * * Arguments: * hw device structure * rid config/info record id (in host order) * val 16/32 bit value to store (in host order) * * Returns: * 0 success */ static int hfa384x_drvr_setconfig16(hfa384x_t *hw, UINT16 rid, UINT16 *val) { UINT16 value; value = host2hfa384x_16(*val); return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(UINT16)); } #if 0 /* Not actually used anywhere */ static int hfa384x_drvr_setconfig32(hfa384x_t *hw, UINT16 rid, UINT32 *val) { UINT32 value; value = host2hfa384x_32(*val); return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(UINT32)); } #endif /* * Wait for an event, with specified checking interval and timeout. * Automatically acknolwedges events. * * Arguments: * hw device structure * event_mask EVSTAT register mask of events to wait for * event_ack EVACK register set of events to be acknowledged if they happen (can be * used to acknowledge "ignorable" events in addition to the "main" event) * wait Time (in us) to wait between each poll of the register * timeout Maximum number of polls before timing out * descr Descriptive text string of what is being waited for * (will be printed out if a timeout happens) * * Returns: * value of EVSTAT register, or 0 on failure */ static int hfa384x_wait_for_event(hfa384x_t *hw, UINT16 event_mask, UINT16 event_ack, int wait, int timeout, const char *descr) { UINT16 reg; int count = 0; do { reg = hfa384x_getreg(hw, HFA384x_EVSTAT); if ( count > 0 ) udelay(wait); count++; } while ( !(reg & event_mask) && count < timeout); if ( count >= timeout ) { printf("hfa384x: Timed out waiting for %s\n", descr); return 0; /* Return failure */ } /* Acknowledge all events that we were waiting on */ hfa384x_setreg(hw, reg & ( event_mask | event_ack ), HFA384x_EVACK); return reg; } /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int prism2_poll(struct nic *nic, int retrieve) { UINT16 reg; UINT16 rxfid; UINT16 result; hfa384x_rx_frame_t rxdesc; hfa384x_t *hw = &hw_global; /* Check for received packet */ reg = hfa384x_getreg(hw, HFA384x_EVSTAT); if ( ! HFA384x_EVSTAT_ISRX(reg) ) { /* No packet received - return 0 */ return 0; } if ( ! retrieve ) return 1; /* Acknowledge RX event */ hfa384x_setreg(hw, HFA384x_EVACK_RX_SET(1), HFA384x_EVACK); /* Get RX FID */ rxfid = hfa384x_getreg(hw, HFA384x_RXFID); /* Get the descriptor (including headers) */ result = hfa384x_copy_from_bap(hw, rxfid, 0, &rxdesc, sizeof(rxdesc)); if ( result ) { return 0; /* fail */ } /* Byte order convert once up front. */ rxdesc.status = hfa384x2host_16(rxdesc.status); rxdesc.time = hfa384x2host_32(rxdesc.time); rxdesc.data_len = hfa384x2host_16(rxdesc.data_len); /* Fill in nic->packetlen */ nic->packetlen = rxdesc.data_len; if ( nic->packetlen > 0 ) { /* Fill in nic->packet */ /* * NOTE: Packets as received have an 8-byte header (LLC+SNAP(?)) terminating with the packet type. * Etherboot expects a 14-byte header terminating with the packet type (it ignores the rest of the * header), so we use a quick hack to achieve this. */ result = hfa384x_copy_from_bap(hw, rxfid, HFA384x_RX_DATA_OFF, nic->packet + ETH_HLEN - sizeof(wlan_80211hdr_t), nic->packetlen); if ( result ) { return 0; /* fail */ } } return 1; /* Packet successfully received */ } /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void prism2_transmit( struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) /* Packet */ { hfa384x_t *hw = &hw_global; hfa384x_tx_frame_t txdesc; wlan_80211hdr_t p80211hdr = { wlan_llc_snap, {{0,0,0},0} }; UINT16 fid; UINT16 status; int result; // Request FID allocation result = hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ALLOC), HFA384x_DRVR_TXBUF_MAX, 0, 0); if (result != 0) { printf("hfa384x: Tx FID allocate command failed: Aborting transmit..\n"); return; } if ( !hfa384x_wait_for_event(hw, HFA384x_EVSTAT_ALLOC, HFA384x_EVACK_INFO, 10, 50, "Tx FID to be allocated\n" ) ) return; fid = hfa384x_getreg(hw, HFA384x_ALLOCFID); /* Build Tx frame structure */ memset(&txdesc, 0, sizeof(txdesc)); txdesc.tx_control = host2hfa384x_16( HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1) ); txdesc.frame_control = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) | WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY) | WLAN_SET_FC_TODS(1) ); memcpy(txdesc.address1, hw->bssid, WLAN_ADDR_LEN); memcpy(txdesc.address2, nic->node_addr, WLAN_ADDR_LEN); memcpy(txdesc.address3, d, WLAN_ADDR_LEN); txdesc.data_len = host2hfa384x_16( sizeof(txdesc) + sizeof(p80211hdr) + s ); /* Set up SNAP header */ /* Let OUI default to RFC1042 (0x000000) */ p80211hdr.snap.type = htons(t); /* Copy txdesc, p80211hdr and payload parts to FID */ result = hfa384x_copy_to_bap(hw, fid, 0, &txdesc, sizeof(txdesc)); if ( result ) return; /* fail */ result = hfa384x_copy_to_bap( hw, fid, sizeof(txdesc), &p80211hdr, sizeof(p80211hdr) ); if ( result ) return; /* fail */ result = hfa384x_copy_to_bap( hw, fid, sizeof(txdesc) + sizeof(p80211hdr), (UINT8*)p, s ); if ( result ) return; /* fail */ /* Issue Tx command */ result = hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_TX), fid, 0, 0); if ( result != 0 ) { printf("hfa384x: Transmit failed with result %#hx.\n", result); return; } /* Wait for transmit completion (or exception) */ result = hfa384x_wait_for_event(hw, HFA384x_EVSTAT_TXEXC | HFA384x_EVSTAT_TX, HFA384x_EVACK_INFO, 200, 500, "Tx to complete\n" ); if ( !result ) return; /* timeout failure */ if ( HFA384x_EVSTAT_ISTXEXC(result) ) { fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID); printf ( "Tx exception occurred with fid %#hx\n", fid ); result = hfa384x_copy_from_bap(hw, fid, 0, &status, sizeof(status)); if ( result ) return; /* fail */ printf("hfa384x: Tx error occurred (status %#hx):\n", status); if ( HFA384x_TXSTATUS_ISACKERR(status) ) { printf(" ...acknowledgement error\n"); } if ( HFA384x_TXSTATUS_ISFORMERR(status) ) { printf(" ...format error\n"); } if ( HFA384x_TXSTATUS_ISDISCON(status) ) { printf(" ...disconnected error\n"); } if ( HFA384x_TXSTATUS_ISAGEDERR(status) ) { printf(" ...AGED error\n"); } if ( HFA384x_TXSTATUS_ISRETRYERR(status) ) { printf(" ...retry error\n"); } return; /* fail */ } } /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void prism2_disable ( struct nic *nic __unused ) { /* put the card in its initial state */ } /************************************************************************** IRQ - Enable, Disable, or Force interrupts ***************************************************************************/ static void prism2_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } /************************************************************************** Operations table ***************************************************************************/ static struct nic_operations prism2_operations = { .connect = dummy_connect, .poll = prism2_poll, .transmit = prism2_transmit, .irq = prism2_irq, }; /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside You should omit the last argument struct pci_device * for a non-PCI NIC ***************************************************************************/ static int prism2_probe ( struct nic *nic, hfa384x_t *hw ) { int result; UINT16 tmp16 = 0; UINT16 infofid; hfa384x_InfFrame_t inf; char ssid[HFA384x_RID_CNFDESIREDSSID_LEN]; int info_count = 0; nic->irqno = 0; /* Initialize card */ result = hfa384x_docmd_wait(hw, HFA384x_CMDCODE_INIT, 0,0,0); /* Send initialize command */ if ( result ) printf ( "Initialize command returned %#hx\n", result ); hfa384x_setreg(hw, 0, HFA384x_INTEN); /* Disable interrupts */ hfa384x_setreg(hw, 0xffff, HFA384x_EVACK); /* Acknowledge any spurious events */ DBG ( "MAC address %s\n", eth_ntoa ( nic->node_addr ) ); /* Retrieve MAC address (and fill out nic->node_addr) */ hfa384x_drvr_getconfig ( hw, HFA384x_RID_CNFOWNMACADDR, nic->node_addr, HFA384x_RID_CNFOWNMACADDR_LEN ); /* Prepare card for autojoin */ /* This procedure is reverse-engineered from a register-level trace of the Linux driver's join process */ tmp16 = WLAN_DATA_MAXLEN; /* Set maximum data length */ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, &tmp16); if ( result ) printf ( "Set Max Data Length command returned %#hx\n", result ); tmp16 = 0x000f; /* Set transmit rate(?) */ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, &tmp16); if ( result ) printf ( "Set Transmit Rate command returned %#hx\n", result ); tmp16 = HFA384x_CNFAUTHENTICATION_OPENSYSTEM; /* Set authentication type to OpenSystem */ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, &tmp16); if ( result ) printf ( "Set Authentication Type command returned %#hx\n", result ); /* Set SSID */ memset(ssid, 0, HFA384x_RID_CNFDESIREDSSID_LEN); for ( tmp16=0; tmp16 MAX_JOIN_INFO_COUNT ) { printf ( "Too many failed attempts - aborting\n" ); return 0; } /* Wait for info frame to indicate link status */ if ( sizeof(hardcoded_ssid) == 1 ) { /* Empty SSID => join to any SSID */ printf ( "Attempting to autojoin to any available access point (attempt %d)...", info_count ); } else { printf ( "Attempting to autojoin to SSID %s (attempt %d)...", &ssid[2], info_count ); } if ( !hfa384x_wait_for_event(hw, HFA384x_EVSTAT_INFO, 0, 1000, 2000, "Info event" ) ) return 0; printf("done\n"); infofid = hfa384x_getreg(hw, HFA384x_INFOFID); /* Retrieve the length */ result = hfa384x_copy_from_bap( hw, infofid, 0, &inf.framelen, sizeof(UINT16)); if ( result ) return 0; /* fail */ inf.framelen = hfa384x2host_16(inf.framelen); /* Retrieve the rest */ result = hfa384x_copy_from_bap( hw, infofid, sizeof(UINT16), &(inf.infotype), inf.framelen * sizeof(UINT16)); if ( result ) return 0; /* fail */ if ( inf.infotype != HFA384x_IT_LINKSTATUS ) { /* Not a Link Status info frame: die */ printf ( "Unexpected info frame type %#hx (not LinkStatus type)\n", inf.infotype ); return 0; } inf.info.linkstatus.linkstatus = hfa384x2host_16(inf.info.linkstatus.linkstatus); if ( inf.info.linkstatus.linkstatus != HFA384x_LINK_CONNECTED ) { /* Link not connected - retry */ printf ( "Link not connected (status %#hx)\n", inf.info.linkstatus.linkstatus ); } } while ( inf.info.linkstatus.linkstatus != HFA384x_LINK_CONNECTED ); /* Retrieve BSSID and print Connected message */ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CURRENTBSSID, hw->bssid, WLAN_BSSID_LEN); DBG ( "Link connected (BSSID %s - ", eth_ntoa ( hw->bssid ) ); DBG ( " MAC address %s)\n", eth_ntoa (nic->node_addr ) ); /* point to NIC specific routines */ nic->nic_op = &prism2_operations; return 1; } debian/grub-extras/disabled/gpxe/src/drivers/net/smc9000.h0000664000000000000000000004347312524662415020466 0ustar /*------------------------------------------------------------------------ * smc9000.h * * Copyright (C) 1998 by Daniel Engstrm * Copyright (C) 1996 by Erik Stahlman * * This software may be used and distributed according to the terms * of the GNU Public License, incorporated herein by reference. * * This file contains register information and access macros for * the SMC91xxx chipset. * * Information contained in this file was obtained from the SMC91C94 * manual from SMC. To get a copy, if you really want one, you can find * information under www.smsc.com in the components division. * ( this thanks to advice from Donald Becker ). * * Authors * Daniel Engstrm * Erik Stahlman * * History * 96-01-06 Erik Stahlman moved definitions here from main .c * file * 96-01-19 Erik Stahlman polished this up some, and added * better error handling * 98-09-25 Daniel Engstrm adjusted for Etherboot * 98-09-27 Daniel Engstrm moved some static strings back to the * main .c file * --------------------------------------------------------------------------*/ FILE_LICENCE ( GPL_ANY ); #ifndef _SMC9000_H_ # define _SMC9000_H_ /* I want some simple types */ typedef unsigned char byte; typedef unsigned short word; typedef unsigned long int dword; /*--------------------------------------------------------------- * * A description of the SMC registers is probably in order here, * although for details, the SMC datasheet is invaluable. * * Basically, the chip has 4 banks of registers ( 0 to 3 ), which * are accessed by writing a number into the BANK_SELECT register * ( I also use a SMC_SELECT_BANK macro for this ). * * The banks are configured so that for most purposes, bank 2 is all * that is needed for simple run time tasks. * ----------------------------------------------------------------------*/ /* * Bank Select Register: * * yyyy yyyy 0000 00xx * xx = bank number * yyyy yyyy = 0x33, for identification purposes. */ #define BANK_SELECT 14 /* BANK 0 */ #define TCR 0 /* transmit control register */ #define TCR_ENABLE 0x0001 /* if this is 1, we can transmit */ #define TCR_FDUPLX 0x0800 /* receive packets sent out */ #define TCR_STP_SQET 0x1000 /* stop transmitting if Signal quality error */ #define TCR_MON_CNS 0x0400 /* monitors the carrier status */ #define TCR_PAD_ENABLE 0x0080 /* pads short packets to 64 bytes */ #define TCR_CLEAR 0 /* do NOTHING */ /* the normal settings for the TCR register : */ #define TCR_NORMAL (TCR_ENABLE | TCR_PAD_ENABLE) #define EPH_STATUS 2 #define ES_LINK_OK 0x4000 /* is the link integrity ok ? */ #define RCR 4 #define RCR_SOFTRESET 0x8000 /* resets the chip */ #define RCR_STRIP_CRC 0x200 /* strips CRC */ #define RCR_ENABLE 0x100 /* IFF this is set, we can receive packets */ #define RCR_ALMUL 0x4 /* receive all multicast packets */ #define RCR_PROMISC 0x2 /* enable promiscuous mode */ /* the normal settings for the RCR register : */ #define RCR_NORMAL (RCR_STRIP_CRC | RCR_ENABLE) #define RCR_CLEAR 0x0 /* set it to a base state */ #define COUNTER 6 #define MIR 8 #define MCR 10 /* 12 is reserved */ // Receive/Phy Control Register /* BANK 0 */ #define RPC_REG 0x000A #define RPC_SPEED 0x2000 // When 1 PHY is in 100Mbps mode. #define RPC_DPLX 0x1000 // When 1 PHY is in Full-Duplex Mode #define RPC_ANEG 0x0800 // When 1 PHY is in Auto-Negotiate Mode #define RPC_LSXA_SHFT 5 // Bits to shift LS2A,LS1A,LS0A to lsb #define RPC_LSXB_SHFT 2 // Bits to get LS2B,LS1B,LS0B to lsb #define RPC_LED_100_10 (0x00) // LED = 100Mbps OR's with 10Mbps link detect #define RPC_LED_RES (0x01) // LED = Reserved #define RPC_LED_10 (0x02) // LED = 10Mbps link detect #define RPC_LED_FD (0x03) // LED = Full Duplex Mode #define RPC_LED_TX_RX (0x04) // LED = TX or RX packet occurred #define RPC_LED_100 (0x05) // LED = 100Mbps link dectect #define RPC_LED_TX (0x06) // LED = TX packet occurred #define RPC_LED_RX (0x07) // LED = RX packet occurred #define RPC_DEFAULT (RPC_ANEG | (RPC_LED_100 << RPC_LSXA_SHFT) | (RPC_LED_FD << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX) // Receive/Phy Control Register /* BANK 0 */ #define RPC_REG 0x000A #define RPC_SPEED 0x2000 // When 1 PHY is in 100Mbps mode. #define RPC_DPLX 0x1000 // When 1 PHY is in Full-Duplex Mode #define RPC_ANEG 0x0800 // When 1 PHY is in Auto-Negotiate Mode #define RPC_LSXA_SHFT 5 // Bits to shift LS2A,LS1A,LS0A to lsb #define RPC_LSXB_SHFT 2 // Bits to get LS2B,LS1B,LS0B to lsb #define RPC_LED_100_10 (0x00) // LED = 100Mbps OR's with 10Mbps link detect #define RPC_LED_RES (0x01) // LED = Reserved #define RPC_LED_10 (0x02) // LED = 10Mbps link detect #define RPC_LED_FD (0x03) // LED = Full Duplex Mode #define RPC_LED_TX_RX (0x04) // LED = TX or RX packet occurred #define RPC_LED_100 (0x05) // LED = 100Mbps link dectect #define RPC_LED_TX (0x06) // LED = TX packet occurred #define RPC_LED_RX (0x07) // LED = RX packet occurred #define RPC_DEFAULT (RPC_ANEG | (RPC_LED_100 << RPC_LSXA_SHFT) | (RPC_LED_FD << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX) /* BANK 1 */ #define CONFIG 0 #define CFG_AUI_SELECT 0x100 #define BASE 2 #define ADDR0 4 #define ADDR1 6 #define ADDR2 8 #define GENERAL 10 #define CONTROL 12 #define CTL_POWERDOWN 0x2000 #define CTL_LE_ENABLE 0x80 #define CTL_CR_ENABLE 0x40 #define CTL_TE_ENABLE 0x0020 #define CTL_AUTO_RELEASE 0x0800 #define CTL_EPROM_ACCESS 0x0003 /* high if Eprom is being read */ /* BANK 2 */ #define MMU_CMD 0 #define MC_BUSY 1 /* only readable bit in the register */ #define MC_NOP 0 #define MC_ALLOC 0x20 /* or with number of 256 byte packets */ #define MC_RESET 0x40 #define MC_REMOVE 0x60 /* remove the current rx packet */ #define MC_RELEASE 0x80 /* remove and release the current rx packet */ #define MC_FREEPKT 0xA0 /* Release packet in PNR register */ #define MC_ENQUEUE 0xC0 /* Enqueue the packet for transmit */ #define PNR_ARR 2 #define FIFO_PORTS 4 #define FP_RXEMPTY 0x8000 #define FP_TXEMPTY 0x80 #define POINTER 6 #define PTR_READ 0x2000 #define PTR_RCV 0x8000 #define PTR_AUTOINC 0x4000 #define PTR_AUTO_INC 0x0040 #define DATA_1 8 #define DATA_2 10 #define INTERRUPT 12 #define INT_MASK 13 #define IM_RCV_INT 0x1 #define IM_TX_INT 0x2 #define IM_TX_EMPTY_INT 0x4 #define IM_ALLOC_INT 0x8 #define IM_RX_OVRN_INT 0x10 #define IM_EPH_INT 0x20 #define IM_ERCV_INT 0x40 /* not on SMC9192 */ /* BANK 3 */ #define MULTICAST1 0 #define MULTICAST2 2 #define MULTICAST3 4 #define MULTICAST4 6 #define MGMT 8 #define REVISION 10 /* ( hi: chip id low: rev # ) */ // Management Interface Register (MII) #define MII_REG 0x0008 #define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup #define MII_MDOE 0x0008 // MII Output Enable #define MII_MCLK 0x0004 // MII Clock, pin MDCLK #define MII_MDI 0x0002 // MII Input, pin MDI #define MII_MDO 0x0001 // MII Output, pin MDO /* this is NOT on SMC9192 */ #define ERCV 12 /* Note that 9194 and 9196 have the smame chip id, * the 9196 will have revisions starting at 6 */ #define CHIP_9190 3 #define CHIP_9194 4 #define CHIP_9195 5 #define CHIP_9196 4 #define CHIP_91100 7 #define CHIP_91100FD 8 #define REV_9196 6 /* * Transmit status bits */ #define TS_SUCCESS 0x0001 #define TS_LOSTCAR 0x0400 #define TS_LATCOL 0x0200 #define TS_16COL 0x0010 /* * Receive status bits */ #define RS_ALGNERR 0x8000 #define RS_BADCRC 0x2000 #define RS_ODDFRAME 0x1000 #define RS_TOOLONG 0x0800 #define RS_TOOSHORT 0x0400 #define RS_MULTICAST 0x0001 #define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) // PHY Register Addresses (LAN91C111 Internal PHY) // PHY Control Register #define PHY_CNTL_REG 0x00 #define PHY_CNTL_RST 0x8000 // 1=PHY Reset #define PHY_CNTL_LPBK 0x4000 // 1=PHY Loopback #define PHY_CNTL_SPEED 0x2000 // 1=100Mbps, 0=10Mpbs #define PHY_CNTL_ANEG_EN 0x1000 // 1=Enable Auto negotiation #define PHY_CNTL_PDN 0x0800 // 1=PHY Power Down mode #define PHY_CNTL_MII_DIS 0x0400 // 1=MII 4 bit interface disabled #define PHY_CNTL_ANEG_RST 0x0200 // 1=Reset Auto negotiate #define PHY_CNTL_DPLX 0x0100 // 1=Full Duplex, 0=Half Duplex #define PHY_CNTL_COLTST 0x0080 // 1= MII Colision Test // PHY Status Register #define PHY_STAT_REG 0x01 #define PHY_STAT_CAP_T4 0x8000 // 1=100Base-T4 capable #define PHY_STAT_CAP_TXF 0x4000 // 1=100Base-X full duplex capable #define PHY_STAT_CAP_TXH 0x2000 // 1=100Base-X half duplex capable #define PHY_STAT_CAP_TF 0x1000 // 1=10Mbps full duplex capable #define PHY_STAT_CAP_TH 0x0800 // 1=10Mbps half duplex capable #define PHY_STAT_CAP_SUPR 0x0040 // 1=recv mgmt frames with not preamble #define PHY_STAT_ANEG_ACK 0x0020 // 1=ANEG has completed #define PHY_STAT_REM_FLT 0x0010 // 1=Remote Fault detected #define PHY_STAT_CAP_ANEG 0x0008 // 1=Auto negotiate capable #define PHY_STAT_LINK 0x0004 // 1=valid link #define PHY_STAT_JAB 0x0002 // 1=10Mbps jabber condition #define PHY_STAT_EXREG 0x0001 // 1=extended registers implemented // PHY Identifier Registers #define PHY_ID1_REG 0x02 // PHY Identifier 1 #define PHY_ID2_REG 0x03 // PHY Identifier 2 // PHY Auto-Negotiation Advertisement Register #define PHY_AD_REG 0x04 #define PHY_AD_NP 0x8000 // 1=PHY requests exchange of Next Page #define PHY_AD_ACK 0x4000 // 1=got link code word from remote #define PHY_AD_RF 0x2000 // 1=advertise remote fault #define PHY_AD_T4 0x0200 // 1=PHY is capable of 100Base-T4 #define PHY_AD_TX_FDX 0x0100 // 1=PHY is capable of 100Base-TX FDPLX #define PHY_AD_TX_HDX 0x0080 // 1=PHY is capable of 100Base-TX HDPLX #define PHY_AD_10_FDX 0x0040 // 1=PHY is capable of 10Base-T FDPLX #define PHY_AD_10_HDX 0x0020 // 1=PHY is capable of 10Base-T HDPLX #define PHY_AD_CSMA 0x0001 // 1=PHY is capable of 802.3 CMSA // PHY Auto-negotiation Remote End Capability Register #define PHY_RMT_REG 0x05 // Uses same bit definitions as PHY_AD_REG // PHY Configuration Register 1 #define PHY_CFG1_REG 0x10 #define PHY_CFG1_LNKDIS 0x8000 // 1=Rx Link Detect Function disabled #define PHY_CFG1_XMTDIS 0x4000 // 1=TP Transmitter Disabled #define PHY_CFG1_XMTPDN 0x2000 // 1=TP Transmitter Powered Down #define PHY_CFG1_BYPSCR 0x0400 // 1=Bypass scrambler/descrambler #define PHY_CFG1_UNSCDS 0x0200 // 1=Unscramble Idle Reception Disable #define PHY_CFG1_EQLZR 0x0100 // 1=Rx Equalizer Disabled #define PHY_CFG1_CABLE 0x0080 // 1=STP(150ohm), 0=UTP(100ohm) #define PHY_CFG1_RLVL0 0x0040 // 1=Rx Squelch level reduced by 4.5db #define PHY_CFG1_TLVL_SHIFT 2 // Transmit Output Level Adjust #define PHY_CFG1_TLVL_MASK 0x003C #define PHY_CFG1_TRF_MASK 0x0003 // Transmitter Rise/Fall time // PHY Configuration Register 2 #define PHY_CFG2_REG 0x11 #define PHY_CFG2_APOLDIS 0x0020 // 1=Auto Polarity Correction disabled #define PHY_CFG2_JABDIS 0x0010 // 1=Jabber disabled #define PHY_CFG2_MREG 0x0008 // 1=Multiple register access (MII mgt) #define PHY_CFG2_INTMDIO 0x0004 // 1=Interrupt signaled with MDIO pulseo // PHY Status Output (and Interrupt status) Register #define PHY_INT_REG 0x12 // Status Output (Interrupt Status) #define PHY_INT_INT 0x8000 // 1=bits have changed since last read #define PHY_INT_LNKFAIL 0x4000 // 1=Link Not detected #define PHY_INT_LOSSSYNC 0x2000 // 1=Descrambler has lost sync #define PHY_INT_CWRD 0x1000 // 1=Invalid 4B5B code detected on rx #define PHY_INT_SSD 0x0800 // 1=No Start Of Stream detected on rx #define PHY_INT_ESD 0x0400 // 1=No End Of Stream detected on rx #define PHY_INT_RPOL 0x0200 // 1=Reverse Polarity detected #define PHY_INT_JAB 0x0100 // 1=Jabber detected #define PHY_INT_SPDDET 0x0080 // 1=100Base-TX mode, 0=10Base-T mode #define PHY_INT_DPLXDET 0x0040 // 1=Device in Full Duplex // PHY Interrupt/Status Mask Register #define PHY_MASK_REG 0x13 // Interrupt Mask // Uses the same bit definitions as PHY_INT_REG // PHY Register Addresses (LAN91C111 Internal PHY) // PHY Control Register #define PHY_CNTL_REG 0x00 #define PHY_CNTL_RST 0x8000 // 1=PHY Reset #define PHY_CNTL_LPBK 0x4000 // 1=PHY Loopback #define PHY_CNTL_SPEED 0x2000 // 1=100Mbps, 0=10Mpbs #define PHY_CNTL_ANEG_EN 0x1000 // 1=Enable Auto negotiation #define PHY_CNTL_PDN 0x0800 // 1=PHY Power Down mode #define PHY_CNTL_MII_DIS 0x0400 // 1=MII 4 bit interface disabled #define PHY_CNTL_ANEG_RST 0x0200 // 1=Reset Auto negotiate #define PHY_CNTL_DPLX 0x0100 // 1=Full Duplex, 0=Half Duplex #define PHY_CNTL_COLTST 0x0080 // 1= MII Colision Test // PHY Status Register #define PHY_STAT_REG 0x01 #define PHY_STAT_CAP_T4 0x8000 // 1=100Base-T4 capable #define PHY_STAT_CAP_TXF 0x4000 // 1=100Base-X full duplex capable #define PHY_STAT_CAP_TXH 0x2000 // 1=100Base-X half duplex capable #define PHY_STAT_CAP_TF 0x1000 // 1=10Mbps full duplex capable #define PHY_STAT_CAP_TH 0x0800 // 1=10Mbps half duplex capable #define PHY_STAT_CAP_SUPR 0x0040 // 1=recv mgmt frames with not preamble #define PHY_STAT_ANEG_ACK 0x0020 // 1=ANEG has completed #define PHY_STAT_REM_FLT 0x0010 // 1=Remote Fault detected #define PHY_STAT_CAP_ANEG 0x0008 // 1=Auto negotiate capable #define PHY_STAT_LINK 0x0004 // 1=valid link #define PHY_STAT_JAB 0x0002 // 1=10Mbps jabber condition #define PHY_STAT_EXREG 0x0001 // 1=extended registers implemented // PHY Identifier Registers #define PHY_ID1_REG 0x02 // PHY Identifier 1 #define PHY_ID2_REG 0x03 // PHY Identifier 2 // PHY Auto-Negotiation Advertisement Register #define PHY_AD_REG 0x04 #define PHY_AD_NP 0x8000 // 1=PHY requests exchange of Next Page #define PHY_AD_ACK 0x4000 // 1=got link code word from remote #define PHY_AD_RF 0x2000 // 1=advertise remote fault #define PHY_AD_T4 0x0200 // 1=PHY is capable of 100Base-T4 #define PHY_AD_TX_FDX 0x0100 // 1=PHY is capable of 100Base-TX FDPLX #define PHY_AD_TX_HDX 0x0080 // 1=PHY is capable of 100Base-TX HDPLX #define PHY_AD_10_FDX 0x0040 // 1=PHY is capable of 10Base-T FDPLX #define PHY_AD_10_HDX 0x0020 // 1=PHY is capable of 10Base-T HDPLX #define PHY_AD_CSMA 0x0001 // 1=PHY is capable of 802.3 CMSA // PHY Auto-negotiation Remote End Capability Register #define PHY_RMT_REG 0x05 // Uses same bit definitions as PHY_AD_REG // PHY Configuration Register 1 #define PHY_CFG1_REG 0x10 #define PHY_CFG1_LNKDIS 0x8000 // 1=Rx Link Detect Function disabled #define PHY_CFG1_XMTDIS 0x4000 // 1=TP Transmitter Disabled #define PHY_CFG1_XMTPDN 0x2000 // 1=TP Transmitter Powered Down #define PHY_CFG1_BYPSCR 0x0400 // 1=Bypass scrambler/descrambler #define PHY_CFG1_UNSCDS 0x0200 // 1=Unscramble Idle Reception Disable #define PHY_CFG1_EQLZR 0x0100 // 1=Rx Equalizer Disabled #define PHY_CFG1_CABLE 0x0080 // 1=STP(150ohm), 0=UTP(100ohm) #define PHY_CFG1_RLVL0 0x0040 // 1=Rx Squelch level reduced by 4.5db #define PHY_CFG1_TLVL_SHIFT 2 // Transmit Output Level Adjust #define PHY_CFG1_TLVL_MASK 0x003C #define PHY_CFG1_TRF_MASK 0x0003 // Transmitter Rise/Fall time // PHY Configuration Register 2 #define PHY_CFG2_REG 0x11 #define PHY_CFG2_APOLDIS 0x0020 // 1=Auto Polarity Correction disabled #define PHY_CFG2_JABDIS 0x0010 // 1=Jabber disabled #define PHY_CFG2_MREG 0x0008 // 1=Multiple register access (MII mgt) #define PHY_CFG2_INTMDIO 0x0004 // 1=Interrupt signaled with MDIO pulseo // PHY Status Output (and Interrupt status) Register #define PHY_INT_REG 0x12 // Status Output (Interrupt Status) #define PHY_INT_INT 0x8000 // 1=bits have changed since last read #define PHY_INT_LNKFAIL 0x4000 // 1=Link Not detected #define PHY_INT_LOSSSYNC 0x2000 // 1=Descrambler has lost sync #define PHY_INT_CWRD 0x1000 // 1=Invalid 4B5B code detected on rx #define PHY_INT_SSD 0x0800 // 1=No Start Of Stream detected on rx #define PHY_INT_ESD 0x0400 // 1=No End Of Stream detected on rx #define PHY_INT_RPOL 0x0200 // 1=Reverse Polarity detected #define PHY_INT_JAB 0x0100 // 1=Jabber detected #define PHY_INT_SPDDET 0x0080 // 1=100Base-TX mode, 0=10Base-T mode #define PHY_INT_DPLXDET 0x0040 // 1=Device in Full Duplex // PHY Interrupt/Status Mask Register #define PHY_MASK_REG 0x13 // Interrupt Mask // Uses the same bit definitions as PHY_INT_REG /*------------------------------------------------------------------------- * I define some macros to make it easier to do somewhat common * or slightly complicated, repeated tasks. --------------------------------------------------------------------------*/ /* select a register bank, 0 to 3 */ #define SMC_SELECT_BANK(x, y) { _outw( y, x + BANK_SELECT ); } /* define a small delay for the reset */ #define SMC_DELAY(x) { inw( x + RCR );\ inw( x + RCR );\ inw( x + RCR ); } #endif /* _SMC_9000_H_ */ debian/grub-extras/disabled/gpxe/src/drivers/net/amd8111e.h0000664000000000000000000004011012524662415020575 0ustar /* * Advanced Micro Devices Inc. AMD8111E Linux Network Driver * Copyright (C) 2003 Advanced Micro Devices * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA Module Name: amd8111e.h Abstract: AMD8111 based 10/100 Ethernet Controller driver definitions. Environment: Kernel Mode Revision History: 3.0.0 Initial Revision. 3.0.1 */ FILE_LICENCE ( GPL2_OR_LATER ); #ifndef _AMD811E_H #define _AMD811E_H /* Command style register access Registers CMD0, CMD2, CMD3,CMD7 and INTEN0 uses a write access technique called command style access. It allows the write to selected bits of this register without altering the bits that are not selected. Command style registers are divided into 4 bytes that can be written independently. Higher order bit of each byte is the value bit that specifies the value that will be written into the selected bits of register. eg., if the value 10011010b is written into the least significant byte of a command style register, bits 1,3 and 4 of the register will be set to 1, and the other bits will not be altered. If the value 00011010b is written into the same byte, bits 1,3 and 4 will be cleared to 0 and the other bits will not be altered. */ /* Offset for Memory Mapped Registers. */ /* 32 bit registers */ #define ASF_STAT 0x00 /* ASF status register */ #define CHIPID 0x04 /* Chip ID regsiter */ #define MIB_DATA 0x10 /* MIB data register */ #define MIB_ADDR 0x14 /* MIB address register */ #define STAT0 0x30 /* Status0 register */ #define INT0 0x38 /* Interrupt0 register */ #define INTEN0 0x40 /* Interrupt0 enable register*/ #define CMD0 0x48 /* Command0 register */ #define CMD2 0x50 /* Command2 register */ #define CMD3 0x54 /* Command3 resiter */ #define CMD7 0x64 /* Command7 register */ #define CTRL1 0x6C /* Control1 register */ #define CTRL2 0x70 /* Control2 register */ #define XMT_RING_LIMIT 0x7C /* Transmit ring limit register */ #define AUTOPOLL0 0x88 /* Auto-poll0 register */ #define AUTOPOLL1 0x8A /* Auto-poll1 register */ #define AUTOPOLL2 0x8C /* Auto-poll2 register */ #define AUTOPOLL3 0x8E /* Auto-poll3 register */ #define AUTOPOLL4 0x90 /* Auto-poll4 register */ #define AUTOPOLL5 0x92 /* Auto-poll5 register */ #define AP_VALUE 0x98 /* Auto-poll value register */ #define DLY_INT_A 0xA8 /* Group A delayed interrupt register */ #define DLY_INT_B 0xAC /* Group B delayed interrupt register */ #define FLOW_CONTROL 0xC8 /* Flow control register */ #define PHY_ACCESS 0xD0 /* PHY access register */ #define STVAL 0xD8 /* Software timer value register */ #define XMT_RING_BASE_ADDR0 0x100 /* Transmit ring0 base addr register */ #define XMT_RING_BASE_ADDR1 0x108 /* Transmit ring1 base addr register */ #define XMT_RING_BASE_ADDR2 0x110 /* Transmit ring2 base addr register */ #define XMT_RING_BASE_ADDR3 0x118 /* Transmit ring2 base addr register */ #define RCV_RING_BASE_ADDR0 0x120 /* Transmit ring0 base addr register */ #define PMAT0 0x190 /* OnNow pattern register0 */ #define PMAT1 0x194 /* OnNow pattern register1 */ /* 16bit registers */ #define XMT_RING_LEN0 0x140 /* Transmit Ring0 length register */ #define XMT_RING_LEN1 0x144 /* Transmit Ring1 length register */ #define XMT_RING_LEN2 0x148 /* Transmit Ring2 length register */ #define XMT_RING_LEN3 0x14C /* Transmit Ring3 length register */ #define RCV_RING_LEN0 0x150 /* Receive Ring0 length register */ #define SRAM_SIZE 0x178 /* SRAM size register */ #define SRAM_BOUNDARY 0x17A /* SRAM boundary register */ /* 48bit register */ #define PADR 0x160 /* Physical address register */ #define IFS1 0x18C /* Inter-frame spacing Part1 register */ #define IFS 0x18D /* Inter-frame spacing register */ #define IPG 0x18E /* Inter-frame gap register */ /* 64bit register */ #define LADRF 0x168 /* Logical address filter register */ /* Register Bit Definitions */ typedef enum { ASF_INIT_DONE = (1 << 1), ASF_INIT_PRESENT = (1 << 0), }STAT_ASF_BITS; typedef enum { MIB_CMD_ACTIVE = (1 << 15 ), MIB_RD_CMD = (1 << 13 ), MIB_CLEAR = (1 << 12 ), MIB_ADDRESS = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)| (1 << 4) | (1 << 5), }MIB_ADDR_BITS; typedef enum { PMAT_DET = (1 << 12), MP_DET = (1 << 11), LC_DET = (1 << 10), SPEED_MASK = (1 << 9)|(1 << 8)|(1 << 7), FULL_DPLX = (1 << 6), LINK_STATS = (1 << 5), AUTONEG_COMPLETE = (1 << 4), MIIPD = (1 << 3), RX_SUSPENDED = (1 << 2), TX_SUSPENDED = (1 << 1), RUNNING = (1 << 0), }STAT0_BITS; #define PHY_SPEED_10 0x2 #define PHY_SPEED_100 0x3 /* INT0 0x38, 32bit register */ typedef enum { INTR = (1 << 31), PCSINT = (1 << 28), LCINT = (1 << 27), APINT5 = (1 << 26), APINT4 = (1 << 25), APINT3 = (1 << 24), TINT_SUM = (1 << 23), APINT2 = (1 << 22), APINT1 = (1 << 21), APINT0 = (1 << 20), MIIPDTINT = (1 << 19), MCCINT = (1 << 17), MREINT = (1 << 16), RINT_SUM = (1 << 15), SPNDINT = (1 << 14), MPINT = (1 << 13), SINT = (1 << 12), TINT3 = (1 << 11), TINT2 = (1 << 10), TINT1 = (1 << 9), TINT0 = (1 << 8), UINT = (1 << 7), STINT = (1 << 4), RINT0 = (1 << 0), }INT0_BITS; typedef enum { VAL3 = (1 << 31), /* VAL bit for byte 3 */ VAL2 = (1 << 23), /* VAL bit for byte 2 */ VAL1 = (1 << 15), /* VAL bit for byte 1 */ VAL0 = (1 << 7), /* VAL bit for byte 0 */ }VAL_BITS; typedef enum { /* VAL3 */ LCINTEN = (1 << 27), APINT5EN = (1 << 26), APINT4EN = (1 << 25), APINT3EN = (1 << 24), /* VAL2 */ APINT2EN = (1 << 22), APINT1EN = (1 << 21), APINT0EN = (1 << 20), MIIPDTINTEN = (1 << 19), MCCIINTEN = (1 << 18), MCCINTEN = (1 << 17), MREINTEN = (1 << 16), /* VAL1 */ SPNDINTEN = (1 << 14), MPINTEN = (1 << 13), TINTEN3 = (1 << 11), SINTEN = (1 << 12), TINTEN2 = (1 << 10), TINTEN1 = (1 << 9), TINTEN0 = (1 << 8), /* VAL0 */ STINTEN = (1 << 4), RINTEN0 = (1 << 0), INTEN0_CLEAR = 0x1F7F7F1F, /* Command style register */ }INTEN0_BITS; typedef enum { /* VAL2 */ RDMD0 = (1 << 16), /* VAL1 */ TDMD3 = (1 << 11), TDMD2 = (1 << 10), TDMD1 = (1 << 9), TDMD0 = (1 << 8), /* VAL0 */ UINTCMD = (1 << 6), RX_FAST_SPND = (1 << 5), TX_FAST_SPND = (1 << 4), RX_SPND = (1 << 3), TX_SPND = (1 << 2), INTREN = (1 << 1), RUN = (1 << 0), CMD0_CLEAR = 0x000F0F7F, /* Command style register */ }CMD0_BITS; typedef enum { /* VAL3 */ CONDUIT_MODE = (1 << 29), /* VAL2 */ RPA = (1 << 19), DRCVPA = (1 << 18), DRCVBC = (1 << 17), PROM = (1 << 16), /* VAL1 */ ASTRP_RCV = (1 << 13), RCV_DROP0 = (1 << 12), EMBA = (1 << 11), DXMT2PD = (1 << 10), LTINTEN = (1 << 9), DXMTFCS = (1 << 8), /* VAL0 */ APAD_XMT = (1 << 6), DRTY = (1 << 5), INLOOP = (1 << 4), EXLOOP = (1 << 3), REX_RTRY = (1 << 2), REX_UFLO = (1 << 1), REX_LCOL = (1 << 0), CMD2_CLEAR = 0x3F7F3F7F, /* Command style register */ }CMD2_BITS; typedef enum { /* VAL3 */ ASF_INIT_DONE_ALIAS = (1 << 29), /* VAL2 */ JUMBO = (1 << 21), VSIZE = (1 << 20), VLONLY = (1 << 19), VL_TAG_DEL = (1 << 18), /* VAL1 */ EN_PMGR = (1 << 14), INTLEVEL = (1 << 13), FORCE_FULL_DUPLEX = (1 << 12), FORCE_LINK_STATUS = (1 << 11), APEP = (1 << 10), MPPLBA = (1 << 9), /* VAL0 */ RESET_PHY_PULSE = (1 << 2), RESET_PHY = (1 << 1), PHY_RST_POL = (1 << 0), }CMD3_BITS; typedef enum { /* VAL0 */ PMAT_SAVE_MATCH = (1 << 4), PMAT_MODE = (1 << 3), MPEN_SW = (1 << 1), LCMODE_SW = (1 << 0), CMD7_CLEAR = 0x0000001B /* Command style register */ }CMD7_BITS; typedef enum { RESET_PHY_WIDTH = (0xF << 16) | (0xF<< 20), /* 0x00FF0000 */ XMTSP_MASK = (1 << 9) | (1 << 8), /* 9:8 */ XMTSP_128 = (1 << 9), /* 9 */ XMTSP_64 = (1 << 8), CACHE_ALIGN = (1 << 4), BURST_LIMIT_MASK = (0xF << 0 ), CTRL1_DEFAULT = 0x00010111, }CTRL1_BITS; typedef enum { FMDC_MASK = (1 << 9)|(1 << 8), /* 9:8 */ XPHYRST = (1 << 7), XPHYANE = (1 << 6), XPHYFD = (1 << 5), XPHYSP = (1 << 4) | (1 << 3), /* 4:3 */ APDW_MASK = (1 << 2) | (1 << 1) | (1 << 0), /* 2:0 */ }CTRL2_BITS; /* XMT_RING_LIMIT 0x7C, 32bit register */ typedef enum { XMT_RING2_LIMIT = (0xFF << 16), /* 23:16 */ XMT_RING1_LIMIT = (0xFF << 8), /* 15:8 */ XMT_RING0_LIMIT = (0xFF << 0), /* 7:0 */ }XMT_RING_LIMIT_BITS; typedef enum { AP_REG0_EN = (1 << 15), AP_REG0_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ AP_PHY0_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ }AUTOPOLL0_BITS; /* AUTOPOLL1 0x8A, 16bit register */ typedef enum { AP_REG1_EN = (1 << 15), AP_REG1_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ AP_PRE_SUP1 = (1 << 6), AP_PHY1_DFLT = (1 << 5), AP_PHY1_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ }AUTOPOLL1_BITS; typedef enum { AP_REG2_EN = (1 << 15), AP_REG2_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ AP_PRE_SUP2 = (1 << 6), AP_PHY2_DFLT = (1 << 5), AP_PHY2_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ }AUTOPOLL2_BITS; typedef enum { AP_REG3_EN = (1 << 15), AP_REG3_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ AP_PRE_SUP3 = (1 << 6), AP_PHY3_DFLT = (1 << 5), AP_PHY3_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ }AUTOPOLL3_BITS; typedef enum { AP_REG4_EN = (1 << 15), AP_REG4_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ AP_PRE_SUP4 = (1 << 6), AP_PHY4_DFLT = (1 << 5), AP_PHY4_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ }AUTOPOLL4_BITS; typedef enum { AP_REG5_EN = (1 << 15), AP_REG5_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ AP_PRE_SUP5 = (1 << 6), AP_PHY5_DFLT = (1 << 5), AP_PHY5_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ }AUTOPOLL5_BITS; /* AP_VALUE 0x98, 32bit ragister */ typedef enum { AP_VAL_ACTIVE = (1 << 31), AP_VAL_RD_CMD = ( 1 << 29), AP_ADDR = (1 << 18)|(1 << 17)|(1 << 16), /* 18:16 */ AP_VAL = (0xF << 0) | (0xF << 4) |( 0xF << 8) | (0xF << 12), /* 15:0 */ }AP_VALUE_BITS; typedef enum { DLY_INT_A_R3 = (1 << 31), DLY_INT_A_R2 = (1 << 30), DLY_INT_A_R1 = (1 << 29), DLY_INT_A_R0 = (1 << 28), DLY_INT_A_T3 = (1 << 27), DLY_INT_A_T2 = (1 << 26), DLY_INT_A_T1 = (1 << 25), DLY_INT_A_T0 = ( 1 << 24), EVENT_COUNT_A = (0xF << 16) | (0x1 << 20),/* 20:16 */ MAX_DELAY_TIME_A = (0xF << 0) | (0xF << 4) | (1 << 8)| (1 << 9) | (1 << 10), /* 10:0 */ }DLY_INT_A_BITS; typedef enum { DLY_INT_B_R3 = (1 << 31), DLY_INT_B_R2 = (1 << 30), DLY_INT_B_R1 = (1 << 29), DLY_INT_B_R0 = (1 << 28), DLY_INT_B_T3 = (1 << 27), DLY_INT_B_T2 = (1 << 26), DLY_INT_B_T1 = (1 << 25), DLY_INT_B_T0 = ( 1 << 24), EVENT_COUNT_B = (0xF << 16) | (0x1 << 20),/* 20:16 */ MAX_DELAY_TIME_B = (0xF << 0) | (0xF << 4) | (1 << 8)| (1 << 9) | (1 << 10), /* 10:0 */ }DLY_INT_B_BITS; /* FLOW_CONTROL 0xC8, 32bit register */ typedef enum { PAUSE_LEN_CHG = (1 << 30), FTPE = (1 << 22), FRPE = (1 << 21), NAPA = (1 << 20), NPA = (1 << 19), FIXP = ( 1 << 18), FCCMD = ( 1 << 16), PAUSE_LEN = (0xF << 0) | (0xF << 4) |( 0xF << 8) | (0xF << 12), /* 15:0 */ }FLOW_CONTROL_BITS; /* PHY_ ACCESS 0xD0, 32bit register */ typedef enum { PHY_CMD_ACTIVE = (1 << 31), PHY_WR_CMD = (1 << 30), PHY_RD_CMD = (1 << 29), PHY_RD_ERR = (1 << 28), PHY_PRE_SUP = (1 << 27), PHY_ADDR = (1 << 21) | (1 << 22) | (1 << 23)| (1 << 24) |(1 << 25),/* 25:21 */ PHY_REG_ADDR = (1 << 16) | (1 << 17) | (1 << 18)| (1 << 19) | (1 << 20),/* 20:16 */ PHY_DATA = (0xF << 0)|(0xF << 4) |(0xF << 8)| (0xF << 12),/* 15:0 */ }PHY_ACCESS_BITS; /* PMAT0 0x190, 32bit register */ typedef enum { PMR_ACTIVE = (1 << 31), PMR_WR_CMD = (1 << 30), PMR_RD_CMD = (1 << 29), PMR_BANK = (1 <<28), PMR_ADDR = (0xF << 16)|(1 << 20)|(1 << 21)| (1 << 22),/* 22:16 */ PMR_B4 = (0xF << 0) | (0xF << 4),/* 15:0 */ }PMAT0_BITS; /* PMAT1 0x194, 32bit register */ typedef enum { PMR_B3 = (0xF << 24) | (0xF <<28),/* 31:24 */ PMR_B2 = (0xF << 16) |(0xF << 20),/* 23:16 */ PMR_B1 = (0xF << 8) | (0xF <<12), /* 15:8 */ PMR_B0 = (0xF << 0)|(0xF << 4),/* 7:0 */ }PMAT1_BITS; /************************************************************************/ /* */ /* MIB counter definitions */ /* */ /************************************************************************/ #define rcv_miss_pkts 0x00 #define rcv_octets 0x01 #define rcv_broadcast_pkts 0x02 #define rcv_multicast_pkts 0x03 #define rcv_undersize_pkts 0x04 #define rcv_oversize_pkts 0x05 #define rcv_fragments 0x06 #define rcv_jabbers 0x07 #define rcv_unicast_pkts 0x08 #define rcv_alignment_errors 0x09 #define rcv_fcs_errors 0x0A #define rcv_good_octets 0x0B #define rcv_mac_ctrl 0x0C #define rcv_flow_ctrl 0x0D #define rcv_pkts_64_octets 0x0E #define rcv_pkts_65to127_octets 0x0F #define rcv_pkts_128to255_octets 0x10 #define rcv_pkts_256to511_octets 0x11 #define rcv_pkts_512to1023_octets 0x12 #define rcv_pkts_1024to1518_octets 0x13 #define rcv_unsupported_opcode 0x14 #define rcv_symbol_errors 0x15 #define rcv_drop_pkts_ring1 0x16 #define rcv_drop_pkts_ring2 0x17 #define rcv_drop_pkts_ring3 0x18 #define rcv_drop_pkts_ring4 0x19 #define rcv_jumbo_pkts 0x1A #define xmt_underrun_pkts 0x20 #define xmt_octets 0x21 #define xmt_packets 0x22 #define xmt_broadcast_pkts 0x23 #define xmt_multicast_pkts 0x24 #define xmt_collisions 0x25 #define xmt_unicast_pkts 0x26 #define xmt_one_collision 0x27 #define xmt_multiple_collision 0x28 #define xmt_deferred_transmit 0x29 #define xmt_late_collision 0x2A #define xmt_excessive_defer 0x2B #define xmt_loss_carrier 0x2C #define xmt_excessive_collision 0x2D #define xmt_back_pressure 0x2E #define xmt_flow_ctrl 0x2F #define xmt_pkts_64_octets 0x30 #define xmt_pkts_65to127_octets 0x31 #define xmt_pkts_128to255_octets 0x32 #define xmt_pkts_256to511_octets 0x33 #define xmt_pkts_512to1023_octets 0x34 #define xmt_pkts_1024to1518_octet 0x35 #define xmt_oversize_pkts 0x36 #define xmt_jumbo_pkts 0x37 /* ipg parameters */ #define DEFAULT_IPG 0x60 #define IFS1_DELTA 36 #define IPG_CONVERGE_JIFFIES (HZ/2) #define IPG_STABLE_TIME 5 #define MIN_IPG 96 #define MAX_IPG 255 #define IPG_STEP 16 #define CSTATE 1 #define SSTATE 2 /* amd8111e decriptor flag definitions */ typedef enum { OWN_BIT = (1 << 15), ADD_FCS_BIT = (1 << 13), LTINT_BIT = (1 << 12), STP_BIT = (1 << 9), ENP_BIT = (1 << 8), KILL_BIT = (1 << 6), TCC_VLAN_INSERT = (1 << 1), TCC_VLAN_REPLACE = (1 << 1) |( 1<< 0), }TX_FLAG_BITS; typedef enum { ERR_BIT = (1 << 14), FRAM_BIT = (1 << 13), OFLO_BIT = (1 << 12), CRC_BIT = (1 << 11), PAM_BIT = (1 << 6), LAFM_BIT = (1 << 5), BAM_BIT = (1 << 4), TT_VLAN_TAGGED = (1 << 3) |(1 << 2),/* 0x000 */ TT_PRTY_TAGGED = (1 << 3),/* 0x0008 */ }RX_FLAG_BITS; #define RESET_RX_FLAGS 0x0000 #define TT_MASK 0x000c #define TCC_MASK 0x0003 /* driver ioctl parameters */ #define AMD8111E_REG_DUMP_LEN 13*sizeof(u32) /* crc generator constants */ #define CRC32 0xedb88320 #define INITCRC 0xFFFFFFFF /* kernel provided writeq does not write 64 bits into the amd8111e device register instead writes only higher 32bits data into lower 32bits of the register. BUG? */ #define amd8111e_writeq(_UlData,_memMap) \ writel(*(u32*)(&_UlData), _memMap); \ writel(*(u32*)((u8*)(&_UlData)+4), _memMap+4) /* maps the external speed options to internal value */ typedef enum { SPEED_AUTONEG, SPEED10_HALF, SPEED10_FULL, SPEED100_HALF, SPEED100_FULL, }EXT_PHY_OPTION; #endif /* _AMD8111E_H */ debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/0000775000000000000000000000000012524676037020230 5ustar debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k_reset.c0000664000000000000000000007631412524662415022620 0ustar /* * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2006-2008 Nick Kossifidis * Copyright (c) 2007-2008 Luis Rodriguez * Copyright (c) 2007-2008 Pavel Roskin * Copyright (c) 2007-2008 Jiri Slaby * * Lightly modified for gPXE, July 2009, by Joshua Oreman . * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ FILE_LICENCE ( MIT ); #define _ATH5K_RESET /*****************************\ Reset functions and helpers \*****************************/ #include /* To determine if a card is pci-e */ #include #include "ath5k.h" #include "reg.h" #include "base.h" /* Find last set bit; fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32 */ static int fls(int x) { int r = 32; if (!x) return 0; if (!(x & 0xffff0000u)) { x <<= 16; r -= 16; } if (!(x & 0xff000000u)) { x <<= 8; r -= 8; } if (!(x & 0xf0000000u)) { x <<= 4; r -= 4; } if (!(x & 0xc0000000u)) { x <<= 2; r -= 2; } if (!(x & 0x80000000u)) { x <<= 1; r -= 1; } return r; } /** * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 * * @ah: the &struct ath5k_hw * @channel: the currently set channel upon reset * * Write the delta slope coefficient (used on pilot tracking ?) for OFDM * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset(). * * Since delta slope is floating point we split it on its exponent and * mantissa and provide these values on hw. * * For more infos i think this patent is related * http://www.freepatentsonline.com/7184495.html */ static int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, struct net80211_channel *channel) { /* Get exponent and mantissa and set it */ u32 coef_scaled, coef_exp, coef_man, ds_coef_exp, ds_coef_man, clock; if (!(ah->ah_version == AR5K_AR5212) || !(channel->hw_value & CHANNEL_OFDM)) { DBG("ath5k: attempt to set OFDM timings on non-OFDM channel\n"); return -EFAULT; } /* Get coefficient * ALGO: coef = (5 * clock * carrier_freq) / 2) * we scale coef by shifting clock value by 24 for * better precision since we use integers */ /* TODO: Half/quarter rate */ clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO); coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; /* Get exponent * ALGO: coef_exp = 14 - highest set bit position */ coef_exp = fls(coef_scaled) - 1; /* Doesn't make sense if it's zero*/ if (!coef_scaled || !coef_exp) return -EINVAL; /* Note: we've shifted coef_scaled by 24 */ coef_exp = 14 - (coef_exp - 24); /* Get mantissa (significant digits) * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */ coef_man = coef_scaled + (1 << (24 - coef_exp - 1)); /* Calculate delta slope coefficient exponent * and mantissa (remove scaling) and set them on hw */ ds_coef_man = coef_man >> (24 - coef_exp); ds_coef_exp = coef_exp - 16; AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man); AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp); return 0; } /* * index into rates for control rates, we can set it up like this because * this is only used for AR5212 and we know it supports G mode */ static const unsigned int control_rates[] = { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 }; /** * ath5k_hw_write_rate_duration - fill rate code to duration table * * @ah: the &struct ath5k_hw * @mode: one of enum ath5k_driver_mode * * Write the rate code to duration table upon hw reset. This is a helper for * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on * the hardware, based on current mode, for each rate. The rates which are * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have * different rate code so we write their value twice (one for long preample * and one for short). * * Note: Band doesn't matter here, if we set the values for OFDM it works * on both a and g modes. So all we have to do is set values for all g rates * that include all OFDM and CCK rates. If we operate in turbo or xr/half/ * quarter rate mode, we need to use another set of bitrates (that's why we * need the mode parameter) but we don't handle these proprietary modes yet. */ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, unsigned int mode __unused) { struct ath5k_softc *sc = ah->ah_sc; u16 rate; int i; /* Write rate duration table */ for (i = 0; i < sc->hwinfo->nr_rates[NET80211_BAND_2GHZ]; i++) { u32 reg; u16 tx_time; rate = sc->hwinfo->rates[NET80211_BAND_2GHZ][i]; /* Set ACK timeout */ reg = AR5K_RATE_DUR(ath5k_bitrate_to_hw_rix(rate)); /* An ACK frame consists of 10 bytes. If you add the FCS, * it's 14 bytes. Note we use the control rate and not the * actual rate for this rate. See mac80211 tx.c * ieee80211_duration() for a brief description of * what rate we should choose to TX ACKs. */ tx_time = net80211_duration(sc->dev, 14, rate); ath5k_hw_reg_write(ah, tx_time, reg); if (rate != 20 && rate != 55 && rate != 110) continue; /* * We're not distinguishing short preamble here, * This is true, all we'll get is a longer value here * which is not necessarilly bad. */ ath5k_hw_reg_write(ah, tx_time, reg + (AR5K_SET_SHORT_PREAMBLE << 2)); } } /* * Reset chipset */ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) { int ret; u32 mask = val ? val : ~0U; /* Read-and-clear RX Descriptor Pointer*/ ath5k_hw_reg_read(ah, AR5K_RXDP); /* * Reset the device and wait until success */ ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL); /* Wait at least 128 PCI clocks */ udelay(15); if (ah->ah_version == AR5K_AR5210) { val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY; mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY; } else { val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; } ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, 0); /* * Reset configuration register (for hw byte-swap). Note that this * is only set for big endian. We do the necessary magic in * AR5K_INIT_CFG. */ if ((val & AR5K_RESET_CTL_PCU) == 0) ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG); return ret; } /* * Sleep control */ int ath5k_hw_wake(struct ath5k_hw *ah) { unsigned int i; u32 staid, data; staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1); staid &= ~AR5K_STA_ID1_PWR_SV; /* Preserve sleep duration */ data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL); if (data & 0xffc00000) data = 0; else data = data & 0xfffcffff; ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); udelay(15); for (i = 50; i > 0; i--) { /* Check if the chip did wake up */ if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_SPWR_DN) == 0) break; /* Wait a bit and retry */ udelay(200); ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); } /* Fail if the chip didn't wake up */ if (i <= 0) return -EIO; ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1); return 0; } /* * Bring up MAC + PHY Chips and program PLL * TODO: Half/Quarter rate support */ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, int initial __unused) { struct pci_device *pdev = ah->ah_sc->pdev; u32 turbo, mode, clock, bus_flags; int ret; turbo = 0; mode = 0; clock = 0; /* Wakeup the device */ ret = ath5k_hw_wake(ah); if (ret) { DBG("ath5k: failed to wake up the MAC chip\n"); return ret; } if (ah->ah_version != AR5K_AR5210) { /* * Get channel mode flags */ if (ah->ah_radio >= AR5K_RF5112) { mode = AR5K_PHY_MODE_RAD_RF5112; clock = AR5K_PHY_PLL_RF5112; } else { mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/ clock = AR5K_PHY_PLL_RF5111; /*Zero*/ } if (flags & CHANNEL_2GHZ) { mode |= AR5K_PHY_MODE_FREQ_2GHZ; clock |= AR5K_PHY_PLL_44MHZ; if (flags & CHANNEL_CCK) { mode |= AR5K_PHY_MODE_MOD_CCK; } else if (flags & CHANNEL_OFDM) { /* XXX Dynamic OFDM/CCK is not supported by the * AR5211 so we set MOD_OFDM for plain g (no * CCK headers) operation. We need to test * this, 5211 might support ofdm-only g after * all, there are also initial register values * in the code for g mode (see initvals.c). */ if (ah->ah_version == AR5K_AR5211) mode |= AR5K_PHY_MODE_MOD_OFDM; else mode |= AR5K_PHY_MODE_MOD_DYN; } else { DBG("ath5k: invalid radio modulation mode\n"); return -EINVAL; } } else if (flags & CHANNEL_5GHZ) { mode |= AR5K_PHY_MODE_FREQ_5GHZ; if (ah->ah_radio == AR5K_RF5413) clock = AR5K_PHY_PLL_40MHZ_5413; else clock |= AR5K_PHY_PLL_40MHZ; if (flags & CHANNEL_OFDM) mode |= AR5K_PHY_MODE_MOD_OFDM; else { DBG("ath5k: invalid radio modulation mode\n"); return -EINVAL; } } else { DBG("ath5k: invalid radio frequency mode\n"); return -EINVAL; } if (flags & CHANNEL_TURBO) turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT; } else { /* Reset the device */ /* ...enable Atheros turbo mode if requested */ if (flags & CHANNEL_TURBO) ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE, AR5K_PHY_TURBO); } /* reseting PCI on PCI-E cards results card to hang * and always return 0xffff... so we ingore that flag * for PCI-E cards */ if (pci_find_capability(pdev, PCI_CAP_ID_EXP)) bus_flags = 0; else bus_flags = AR5K_RESET_CTL_PCI; /* Reset chipset */ if (ah->ah_version == AR5K_AR5210) { ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA | AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI); mdelay(2); } else { ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND | bus_flags); } if (ret) { DBG("ath5k: failed to reset the MAC chip\n"); return -EIO; } /* ...wakeup again!*/ ret = ath5k_hw_wake(ah); if (ret) { DBG("ath5k: failed to resume the MAC chip\n"); return ret; } /* ...final warm reset */ if (ath5k_hw_nic_reset(ah, 0)) { DBG("ath5k: failed to warm reset the MAC chip\n"); return -EIO; } if (ah->ah_version != AR5K_AR5210) { /* ...update PLL if needed */ if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) { ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL); udelay(300); } /* ...set the PHY operating mode */ ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE); ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO); } return 0; } static int ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, struct net80211_channel *channel) { u8 refclk_freq; if ((ah->ah_radio == AR5K_RF5112) || (ah->ah_radio == AR5K_RF5413) || (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) refclk_freq = 40; else refclk_freq = 32; if ((channel->center_freq % refclk_freq != 0) && ((channel->center_freq % refclk_freq < 10) || (channel->center_freq % refclk_freq > 22))) return 1; else return 0; } /* TODO: Half/Quarter rate */ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, struct net80211_channel *channel) { if (ah->ah_version == AR5K_AR5212 && ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { /* Setup ADC control */ ath5k_hw_reg_write(ah, (AR5K_REG_SM(2, AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) | AR5K_REG_SM(2, AR5K_PHY_ADC_CTL_INBUFGAIN_ON) | AR5K_PHY_ADC_CTL_PWD_DAC_OFF | AR5K_PHY_ADC_CTL_PWD_ADC_OFF), AR5K_PHY_ADC_CTL); /* Disable barker RSSI threshold */ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL, AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR); AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL, AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2); /* Set the mute mask */ ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK); } /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */ if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B) ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH); /* Enable DCU double buffering */ if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B) AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_DCU_DBL_BUF_DIS); /* Set DAC/ADC delays */ if (ah->ah_version == AR5K_AR5212) { u32 scal; if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)) scal = AR5K_PHY_SCAL_32MHZ_2417; else if (ath5k_eeprom_is_hb63(ah)) scal = AR5K_PHY_SCAL_32MHZ_HB63; else scal = AR5K_PHY_SCAL_32MHZ; ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL); } /* Set fast ADC */ if ((ah->ah_radio == AR5K_RF5413) || (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { u32 fast_adc = 1; if (channel->center_freq == 2462 || channel->center_freq == 2467) fast_adc = 0; /* Only update if needed */ if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc) ath5k_hw_reg_write(ah, fast_adc, AR5K_PHY_FAST_ADC); } /* Fix for first revision of the RF5112 RF chipset */ if (ah->ah_radio == AR5K_RF5112 && ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) { u32 data; ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, AR5K_PHY_CCKTXCTL); if (channel->hw_value & CHANNEL_5GHZ) data = 0xffb81020; else data = 0xffb80d20; ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL); } if (ah->ah_mac_srev < AR5K_SREV_AR5211) { u32 usec_reg; /* 5311 has different tx/rx latency masks * from 5211, since we deal 5311 the same * as 5211 when setting initvals, shift * values here to their proper locations */ usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211); ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 | AR5K_USEC_32 | AR5K_USEC_TX_LATENCY_5211 | AR5K_REG_SM(29, AR5K_USEC_RX_LATENCY_5210)), AR5K_USEC_5211); /* Clear QCU/DCU clock gating register */ ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT); /* Set DAC/ADC delays */ ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL); /* Enable PCU FIFO corruption ECO */ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, AR5K_DIAG_SW_ECO_ENABLE); } } static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, struct net80211_channel *channel, u8 *ant, u8 ee_mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; s16 cck_ofdm_pwr_delta; /* Adjust power delta for channel 14 */ if (channel->center_freq == 2484) cck_ofdm_pwr_delta = ((ee->ee_cck_ofdm_power_delta - ee->ee_scaled_cck_delta) * 2) / 10; else cck_ofdm_pwr_delta = (ee->ee_cck_ofdm_power_delta * 2) / 10; /* Set CCK to OFDM power delta on tx power * adjustment register */ if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { if (channel->hw_value == CHANNEL_G) ath5k_hw_reg_write(ah, AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1), AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) | AR5K_REG_SM((cck_ofdm_pwr_delta * -1), AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX), AR5K_PHY_TX_PWR_ADJ); else ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ); } else { /* For older revs we scale power on sw during tx power * setup */ ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta; ah->ah_txpower.txp_cck_ofdm_gainf_delta = ee->ee_cck_ofdm_gain_delta; } /* Set antenna idle switch table */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL, AR5K_PHY_ANT_CTL_SWTABLE_IDLE, (ah->ah_antenna[ee_mode][0] | AR5K_PHY_ANT_CTL_TXRX_EN)); /* Set antenna switch table */ ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]], AR5K_PHY_ANT_SWITCH_TABLE_0); ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]], AR5K_PHY_ANT_SWITCH_TABLE_1); /* Noise floor threshold */ ath5k_hw_reg_write(ah, AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]), AR5K_PHY_NFTHRES); if ((channel->hw_value & CHANNEL_TURBO) && (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) { /* Switch settling time (Turbo) */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, AR5K_PHY_SETTLING_SWITCH, ee->ee_switch_settling_turbo[ee_mode]); /* Tx/Rx attenuation (Turbo) */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN, AR5K_PHY_GAIN_TXRX_ATTEN, ee->ee_atn_tx_rx_turbo[ee_mode]); /* ADC/PGA desired size (Turbo) */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, AR5K_PHY_DESIRED_SIZE_ADC, ee->ee_adc_desired_size_turbo[ee_mode]); AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, AR5K_PHY_DESIRED_SIZE_PGA, ee->ee_pga_desired_size_turbo[ee_mode]); /* Tx/Rx margin (Turbo) */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ, AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, ee->ee_margin_tx_rx_turbo[ee_mode]); } else { /* Switch settling time */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, AR5K_PHY_SETTLING_SWITCH, ee->ee_switch_settling[ee_mode]); /* Tx/Rx attenuation */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN, AR5K_PHY_GAIN_TXRX_ATTEN, ee->ee_atn_tx_rx[ee_mode]); /* ADC/PGA desired size */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, AR5K_PHY_DESIRED_SIZE_ADC, ee->ee_adc_desired_size[ee_mode]); AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, AR5K_PHY_DESIRED_SIZE_PGA, ee->ee_pga_desired_size[ee_mode]); /* Tx/Rx margin */ if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ, AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, ee->ee_margin_tx_rx[ee_mode]); } /* XPA delays */ ath5k_hw_reg_write(ah, (ee->ee_tx_end2xpa_disable[ee_mode] << 24) | (ee->ee_tx_end2xpa_disable[ee_mode] << 16) | (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) | (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4); /* XLNA delay */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3, AR5K_PHY_RF_CTL3_TXE2XLNA_ON, ee->ee_tx_end2xlna_enable[ee_mode]); /* Thresh64 (ANI) */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF, AR5K_PHY_NF_THRESH62, ee->ee_thr_62[ee_mode]); /* False detect backoff for channels * that have spur noise. Write the new * cyclic power RSSI threshold. */ if (ath5k_hw_chan_has_spur_noise(ah, channel)) AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR, AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, AR5K_INIT_CYCRSSI_THR1 + ee->ee_false_detect[ee_mode]); else AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR, AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, AR5K_INIT_CYCRSSI_THR1); /* I/Q correction * TODO: Per channel i/q infos ? */ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE | (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | ee->ee_q_cal[ee_mode]); /* Heavy clipping -disable for now */ if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE); return; } /* * Main reset function */ int ath5k_hw_reset(struct ath5k_hw *ah, struct net80211_channel *channel, int change_channel) { u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo; u32 phy_tst1; u8 mode, freq, ee_mode, ant[2]; int i, ret; s_ant = 0; ee_mode = 0; staid1_flags = 0; tsf_up = 0; tsf_lo = 0; freq = 0; mode = 0; /* * Save some registers before a reset */ /*DCU/Antenna selection not available on 5210*/ if (ah->ah_version != AR5K_AR5210) { switch (channel->hw_value & CHANNEL_MODES) { case CHANNEL_A: mode = AR5K_MODE_11A; freq = AR5K_INI_RFGAIN_5GHZ; ee_mode = AR5K_EEPROM_MODE_11A; break; case CHANNEL_G: mode = AR5K_MODE_11G; freq = AR5K_INI_RFGAIN_2GHZ; ee_mode = AR5K_EEPROM_MODE_11G; break; case CHANNEL_B: mode = AR5K_MODE_11B; freq = AR5K_INI_RFGAIN_2GHZ; ee_mode = AR5K_EEPROM_MODE_11B; break; case CHANNEL_T: mode = AR5K_MODE_11A_TURBO; freq = AR5K_INI_RFGAIN_5GHZ; ee_mode = AR5K_EEPROM_MODE_11A; break; case CHANNEL_TG: if (ah->ah_version == AR5K_AR5211) { DBG("ath5k: TurboG not available on 5211\n"); return -EINVAL; } mode = AR5K_MODE_11G_TURBO; freq = AR5K_INI_RFGAIN_2GHZ; ee_mode = AR5K_EEPROM_MODE_11G; break; case CHANNEL_XR: if (ah->ah_version == AR5K_AR5211) { DBG("ath5k: XR mode not available on 5211\n"); return -EINVAL; } mode = AR5K_MODE_XR; freq = AR5K_INI_RFGAIN_5GHZ; ee_mode = AR5K_EEPROM_MODE_11A; break; default: DBG("ath5k: invalid channel (%d MHz)\n", channel->center_freq); return -EINVAL; } if (change_channel) { /* * Save frame sequence count * For revs. after Oahu, only save * seq num for DCU 0 (Global seq num) */ if (ah->ah_mac_srev < AR5K_SREV_AR5211) { for (i = 0; i < 10; i++) s_seq[i] = ath5k_hw_reg_read(ah, AR5K_QUEUE_DCU_SEQNUM(i)); } else { s_seq[0] = ath5k_hw_reg_read(ah, AR5K_QUEUE_DCU_SEQNUM(0)); } } /* Save default antenna */ s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); if (ah->ah_version == AR5K_AR5212) { /* Since we are going to write rf buffer * check if we have any pending gain_F * optimization settings */ if (change_channel && ah->ah_rf_banks != NULL) ath5k_hw_gainf_calibrate(ah); } } /*GPIOs*/ s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE; s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR); s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO); /* AR5K_STA_ID1 flags, only preserve antenna * settings and ack/cts rate mode */ staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & (AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_DESC_ANTENNA | AR5K_STA_ID1_RTS_DEF_ANTENNA | AR5K_STA_ID1_ACKCTS_6MB | AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_SELFGEN_DEF_ANT); /* Wakeup the device */ ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, 0); if (ret) return ret; /* PHY access enable */ if (ah->ah_mac_srev >= AR5K_SREV_AR5211) ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); else ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40, AR5K_PHY(0)); /* Write initial settings */ ret = ath5k_hw_write_initvals(ah, mode, change_channel); if (ret) return ret; /* * 5211/5212 Specific */ if (ah->ah_version != AR5K_AR5210) { /* * Write initial RF gain settings * This should work for both 5111/5112 */ ret = ath5k_hw_rfgain_init(ah, freq); if (ret) return ret; mdelay(1); /* * Tweak initval settings for revised * chipsets and add some more config * bits */ ath5k_hw_tweak_initval_settings(ah, channel); /* * Set TX power (FIXME) */ ret = ath5k_hw_txpower(ah, channel, ee_mode, AR5K_TUNE_DEFAULT_TXPOWER); if (ret) return ret; /* Write rate duration table only on AR5212 */ if (ah->ah_version == AR5K_AR5212) ath5k_hw_write_rate_duration(ah, mode); /* * Write RF buffer */ ret = ath5k_hw_rfregs_init(ah, channel, mode); if (ret) return ret; /* Write OFDM timings on 5212*/ if (ah->ah_version == AR5K_AR5212 && channel->hw_value & CHANNEL_OFDM) { ret = ath5k_hw_write_ofdm_timings(ah, channel); if (ret) return ret; } /*Enable/disable 802.11b mode on 5111 (enable 2111 frequency converter + CCK)*/ if (ah->ah_radio == AR5K_RF5111) { if (mode == AR5K_MODE_11B) AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_B_MODE); else AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_B_MODE); } /* * In case a fixed antenna was set as default * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE * registers. */ if (s_ant != 0) { if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */ ant[0] = ant[1] = AR5K_ANT_FIXED_A; else /* 2 - Aux */ ant[0] = ant[1] = AR5K_ANT_FIXED_B; } else { ant[0] = AR5K_ANT_FIXED_A; ant[1] = AR5K_ANT_FIXED_B; } /* Commit values from EEPROM */ ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode); } else { /* * For 5210 we do all initialization using * initvals, so we don't have to modify * any settings (5210 also only supports * a/aturbo modes) */ mdelay(1); /* Disable phy and wait */ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); mdelay(1); } /* * Restore saved values */ /*DCU/Antenna selection not available on 5210*/ if (ah->ah_version != AR5K_AR5210) { if (change_channel) { if (ah->ah_mac_srev < AR5K_SREV_AR5211) { for (i = 0; i < 10; i++) ath5k_hw_reg_write(ah, s_seq[i], AR5K_QUEUE_DCU_SEQNUM(i)); } else { ath5k_hw_reg_write(ah, s_seq[0], AR5K_QUEUE_DCU_SEQNUM(0)); } } ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA); } /* Ledstate */ AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]); /* Gpio settings */ ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR); ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); /* Restore sta_id flags and preserve our mac address*/ ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id), AR5K_STA_ID0); ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id), AR5K_STA_ID1); /* * Configure PCU */ /* Restore bssid and bssid mask */ /* XXX: add ah->aid once mac80211 gives this to us */ ath5k_hw_set_associd(ah, ah->ah_bssid, 0); /* Set PCU config */ ath5k_hw_set_opmode(ah); /* Clear any pending interrupts * PISR/SISR Not available on 5210 */ if (ah->ah_version != AR5K_AR5210) ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); /* Set RSSI/BRSSI thresholds * * Note: If we decide to set this value * dynamicaly, have in mind that when AR5K_RSSI_THR * register is read it might return 0x40 if we haven't * wrote anything to it plus BMISS RSSI threshold is zeroed. * So doing a save/restore procedure here isn't the right * choice. Instead store it on ath5k_hw */ ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES | AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S), AR5K_RSSI_THR); /* MIC QoS support */ if (ah->ah_mac_srev >= AR5K_SREV_AR2413) { ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL); ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL); } /* QoS NOACK Policy */ if (ah->ah_version == AR5K_AR5212) { ath5k_hw_reg_write(ah, AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) | AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) | AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET), AR5K_QOS_NOACK); } /* * Configure PHY */ /* Set channel on PHY */ ret = ath5k_hw_channel(ah, channel); if (ret) return ret; /* * Enable the PHY and wait until completion * This includes BaseBand and Synthesizer * activation. */ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); /* * On 5211+ read activation -> rx delay * and use it. * * TODO: Half/quarter rate support */ if (ah->ah_version != AR5K_AR5210) { u32 delay; delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & AR5K_PHY_RX_DELAY_M; delay = (channel->hw_value & CHANNEL_CCK) ? ((delay << 2) / 22) : (delay / 10); udelay(100 + (2 * delay)); } else { mdelay(1); } /* * Perform ADC test to see if baseband is ready * Set tx hold and check adc test register */ phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); for (i = 0; i <= 20; i++) { if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) break; udelay(200); } ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); /* * Start automatic gain control calibration * * During AGC calibration RX path is re-routed to * a power detector so we don't receive anything. * * This method is used to calibrate some static offsets * used together with on-the fly I/Q calibration (the * one performed via ath5k_hw_phy_calibrate), that doesn't * interrupt rx path. * * While rx path is re-routed to the power detector we also * start a noise floor calibration, to measure the * card's noise floor (the noise we measure when we are not * transmiting or receiving anything). * * If we are in a noisy environment AGC calibration may time * out and/or noise floor calibration might timeout. */ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL); /* At the same time start I/Q calibration for QAM constellation * -no need for CCK- */ ah->ah_calibration = 0; if (!(mode == AR5K_MODE_11B)) { ah->ah_calibration = 1; AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN); } /* Wait for gain calibration to finish (we check for I/Q calibration * during ath5k_phy_calibrate) */ if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL, 0, 0)) { DBG("ath5k: gain calibration timeout (%d MHz)\n", channel->center_freq); } /* * If we run NF calibration before AGC, it always times out. * Binary HAL starts NF and AGC calibration at the same time * and only waits for AGC to finish. Also if AGC or NF cal. * times out, reset doesn't fail on binary HAL. I believe * that's wrong because since rx path is routed to a detector, * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211 * enables noise floor calibration after offset calibration and if noise * floor calibration fails, reset fails. I believe that's * a better approach, we just need to find a polling interval * that suits best, even if reset continues we need to make * sure that rx path is ready. */ ath5k_hw_noise_floor_calibration(ah, channel->center_freq); /* * Configure QCUs/DCUs */ /* TODO: HW Compression support for data queues */ /* TODO: Burst prefetch for data queues */ /* * Reset queues and start beacon timers at the end of the reset routine * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping * Note: If we want we can assign multiple qcus on one dcu. */ ret = ath5k_hw_reset_tx_queue(ah); if (ret) { DBG("ath5k: failed to reset TX queue\n"); return ret; } /* * Configure DMA/Interrupts */ /* * Set Rx/Tx DMA Configuration * * Set standard DMA size (128). Note that * a DMA size of 512 causes rx overruns and tx errors * on pci-e cards (tested on 5424 but since rx overruns * also occur on 5416/5418 with madwifi we set 128 * for all PCI-E cards to be safe). * * XXX: need to check 5210 for this * TODO: Check out tx triger level, it's always 64 on dumps but I * guess we can tweak it and see how it goes ;-) */ if (ah->ah_version != AR5K_AR5210) { AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B); } /* Pre-enable interrupts on 5211/5212*/ if (ah->ah_version != AR5K_AR5210) ath5k_hw_set_imr(ah, ah->ah_imr); /* * Setup RFKill interrupt if rfkill flag is set on eeprom. * TODO: Use gpio pin and polarity infos from eeprom * TODO: Handle this in ath5k_intr because it'll result * a nasty interrupt storm. */ #if 0 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) { ath5k_hw_set_gpio_input(ah, 0); ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0); if (ah->ah_gpio[0] == 0) ath5k_hw_set_gpio_intr(ah, 0, 1); else ath5k_hw_set_gpio_intr(ah, 0, 0); } #endif /* * Disable beacons and reset the register */ AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE | AR5K_BEACON_RESET_TSF); return 0; } #undef _ATH5K_RESET debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/eeprom.h0000664000000000000000000004102412524662415021664 0ustar /* * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2006-2008 Nick Kossifidis * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ /* * Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE) */ #define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ #define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ #define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */ #define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */ #define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */ #define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */ #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ #define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) #define AR5K_EEPROM_INFO_CKSUM 0xffff #define AR5K_EEPROM_INFO(_n) (AR5K_EEPROM_INFO_BASE + (_n)) #define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1) /* EEPROM Version */ #define AR5K_EEPROM_VERSION_3_0 0x3000 /* No idea what's going on before this version */ #define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2Ghz (ar5211_rfregs) */ #define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */ #define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */ #define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain, ee_cck_ofdm_power_delta (eeprom_read_modes) */ #define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */ #define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */ #define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */ #define AR5K_EEPROM_VERSION_4_3 0x4003 /* power calibration changes */ #define AR5K_EEPROM_VERSION_4_4 0x4004 #define AR5K_EEPROM_VERSION_4_5 0x4005 #define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */ #define AR5K_EEPROM_VERSION_4_7 0x3007 /* 4007 ? */ #define AR5K_EEPROM_VERSION_4_9 0x4009 /* EAR futureproofing */ #define AR5K_EEPROM_VERSION_5_0 0x5000 /* Has 2413 PDADC calibration etc */ #define AR5K_EEPROM_VERSION_5_1 0x5001 /* Has capability values */ #define AR5K_EEPROM_VERSION_5_3 0x5003 /* Has spur mitigation tables */ #define AR5K_EEPROM_MODE_11A 0 #define AR5K_EEPROM_MODE_11B 1 #define AR5K_EEPROM_MODE_11G 2 #define AR5K_EEPROM_HDR AR5K_EEPROM_INFO(2) /* Header that contains the device caps */ #define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) #define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) #define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) #define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */ #define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */ #define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) #define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ #define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */ #define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c #define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2 #define AR5K_EEPROM_RFKILL_POLARITY 0x00000002 #define AR5K_EEPROM_RFKILL_POLARITY_S 1 /* Newer EEPROMs are using a different offset */ #define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \ (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0) #define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3) #define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((s8)(((_v) >> 8) & 0xff)) #define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((s8)((_v) & 0xff)) /* Misc values available since EEPROM 4.0 */ #define AR5K_EEPROM_MISC0 AR5K_EEPROM_INFO(4) #define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff) #define AR5K_EEPROM_HDR_XR2_DIS(_v) (((_v) >> 12) & 0x1) #define AR5K_EEPROM_HDR_XR5_DIS(_v) (((_v) >> 13) & 0x1) #define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3) #define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5) #define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) #define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) #define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1) #define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6) #define AR5K_EEPROM_EEP_FILE_VERSION(_v) (((_v) >> 8) & 0xff) #define AR5K_EEPROM_EAR_FILE_VERSION(_v) ((_v) & 0xff) #define AR5K_EEPROM_MISC3 AR5K_EEPROM_INFO(7) #define AR5K_EEPROM_ART_BUILD_NUM(_v) (((_v) >> 10) & 0x3f) #define AR5K_EEPROM_EAR_FILE_ID(_v) ((_v) & 0xff) #define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8) #define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff) #define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) #define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) #define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9) #define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) #define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) #define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) #define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) #define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) #define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) #define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) #define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10) #define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x8) #define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x8) #define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) #define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) #define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) #define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 9) & 0x1) #define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 10) & 0x1) /* calibration settings */ #define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) #define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2) #define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d) #define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */ #define AR5K_EEPROM_GROUPS_START(_v) AR5K_EEPROM_OFF(_v, 0x0100, 0x0150) /* Start of Groups */ #define AR5K_EEPROM_GROUP1_OFFSET 0x0 #define AR5K_EEPROM_GROUP2_OFFSET 0x5 #define AR5K_EEPROM_GROUP3_OFFSET 0x37 #define AR5K_EEPROM_GROUP4_OFFSET 0x46 #define AR5K_EEPROM_GROUP5_OFFSET 0x55 #define AR5K_EEPROM_GROUP6_OFFSET 0x65 #define AR5K_EEPROM_GROUP7_OFFSET 0x69 #define AR5K_EEPROM_GROUP8_OFFSET 0x6f #define AR5K_EEPROM_TARGET_PWR_OFF_11A(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \ AR5K_EEPROM_GROUP5_OFFSET, 0x0000) #define AR5K_EEPROM_TARGET_PWR_OFF_11B(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \ AR5K_EEPROM_GROUP6_OFFSET, 0x0010) #define AR5K_EEPROM_TARGET_PWR_OFF_11G(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \ AR5K_EEPROM_GROUP7_OFFSET, 0x0014) /* [3.1 - 3.3] */ #define AR5K_EEPROM_OBDB0_2GHZ 0x00ec #define AR5K_EEPROM_OBDB1_2GHZ 0x00ed #define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */ #define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */ #define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */ #define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */ #define AR5K_EEPROM_PROTECT_WR_32_63 0x0008 #define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */ #define AR5K_EEPROM_PROTECT_WR_64_127 0x0020 #define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */ #define AR5K_EEPROM_PROTECT_WR_128_191 0x0080 #define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */ #define AR5K_EEPROM_PROTECT_WR_192_207 0x0200 #define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */ #define AR5K_EEPROM_PROTECT_WR_208_223 0x0800 #define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */ #define AR5K_EEPROM_PROTECT_WR_224_239 0x2000 #define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */ #define AR5K_EEPROM_PROTECT_WR_240_255 0x8000 /* Some EEPROM defines */ #define AR5K_EEPROM_EEP_SCALE 100 #define AR5K_EEPROM_EEP_DELTA 10 #define AR5K_EEPROM_N_MODES 3 #define AR5K_EEPROM_N_5GHZ_CHAN 10 #define AR5K_EEPROM_N_2GHZ_CHAN 3 #define AR5K_EEPROM_N_2GHZ_CHAN_2413 4 #define AR5K_EEPROM_N_2GHZ_CHAN_MAX 4 #define AR5K_EEPROM_MAX_CHAN 10 #define AR5K_EEPROM_N_PWR_POINTS_5111 11 #define AR5K_EEPROM_N_PCDAC 11 #define AR5K_EEPROM_N_PHASE_CAL 5 #define AR5K_EEPROM_N_TEST_FREQ 8 #define AR5K_EEPROM_N_EDGES 8 #define AR5K_EEPROM_N_INTERCEPTS 11 #define AR5K_EEPROM_FREQ_M(_v) AR5K_EEPROM_OFF(_v, 0x7f, 0xff) #define AR5K_EEPROM_PCDAC_M 0x3f #define AR5K_EEPROM_PCDAC_START 1 #define AR5K_EEPROM_PCDAC_STOP 63 #define AR5K_EEPROM_PCDAC_STEP 1 #define AR5K_EEPROM_NON_EDGE_M 0x40 #define AR5K_EEPROM_CHANNEL_POWER 8 #define AR5K_EEPROM_N_OBDB 4 #define AR5K_EEPROM_OBDB_DIS 0xffff #define AR5K_EEPROM_CHANNEL_DIS 0xff #define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10) #define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32) #define AR5K_EEPROM_MAX_CTLS 32 #define AR5K_EEPROM_N_PD_CURVES 4 #define AR5K_EEPROM_N_XPD0_POINTS 4 #define AR5K_EEPROM_N_XPD3_POINTS 3 #define AR5K_EEPROM_N_PD_GAINS 4 #define AR5K_EEPROM_N_PD_POINTS 5 #define AR5K_EEPROM_N_INTERCEPT_10_2GHZ 35 #define AR5K_EEPROM_N_INTERCEPT_10_5GHZ 55 #define AR5K_EEPROM_POWER_M 0x3f #define AR5K_EEPROM_POWER_MIN 0 #define AR5K_EEPROM_POWER_MAX 3150 #define AR5K_EEPROM_POWER_STEP 50 #define AR5K_EEPROM_POWER_TABLE_SIZE 64 #define AR5K_EEPROM_N_POWER_LOC_11B 4 #define AR5K_EEPROM_N_POWER_LOC_11G 6 #define AR5K_EEPROM_I_GAIN 10 #define AR5K_EEPROM_CCK_OFDM_DELTA 15 #define AR5K_EEPROM_N_IQ_CAL 2 #define AR5K_EEPROM_READ(_o, _v) do { \ ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \ if (ret) \ return ret; \ } while (0) #define AR5K_EEPROM_READ_HDR(_o, _v) \ AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \ enum ath5k_ant_setting { AR5K_ANT_VARIABLE = 0, /* variable by programming */ AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */ AR5K_ANT_FIXED_B = 2, /* fixed to 11b frequencies */ AR5K_ANT_MAX = 3, }; enum ath5k_ctl_mode { AR5K_CTL_11A = 0, AR5K_CTL_11B = 1, AR5K_CTL_11G = 2, AR5K_CTL_TURBO = 3, AR5K_CTL_TURBOG = 4, AR5K_CTL_2GHT20 = 5, AR5K_CTL_5GHT20 = 6, AR5K_CTL_2GHT40 = 7, AR5K_CTL_5GHT40 = 8, AR5K_CTL_MODE_M = 15, }; /* Default CTL ids for the 3 main reg domains. * Atheros only uses these by default but vendors * can have up to 32 different CTLs for different * scenarios. Note that theese values are ORed with * the mode id (above) so we can have up to 24 CTL * datasets out of these 3 main regdomains. That leaves * 8 ids that can be used by vendors and since 0x20 is * missing from HAL sources i guess this is the set of * custom CTLs vendors can use. */ #define AR5K_CTL_FCC 0x10 #define AR5K_CTL_CUSTOM 0x20 #define AR5K_CTL_ETSI 0x30 #define AR5K_CTL_MKK 0x40 /* Indicates a CTL with only mode set and * no reg domain mapping, such CTLs are used * for world roaming domains or simply when * a reg domain is not set */ #define AR5K_CTL_NO_REGDOMAIN 0xf0 /* Indicates an empty (invalid) CTL */ #define AR5K_CTL_NO_CTL 0xff /* Per channel calibration data, used for power table setup */ struct ath5k_chan_pcal_info_rf5111 { /* Power levels in half dbm units * for one power curve. */ u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111]; /* PCDAC table steps * for the above values */ u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111]; /* Starting PCDAC step */ u8 pcdac_min; /* Final PCDAC step */ u8 pcdac_max; }; struct ath5k_chan_pcal_info_rf5112 { /* Power levels in quarter dBm units * for lower (0) and higher (3) * level curves in 0.25dB units */ s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS]; s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS]; /* PCDAC table steps * for the above values */ u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS]; u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS]; }; struct ath5k_chan_pcal_info_rf2413 { /* Starting pwr/pddac values */ s8 pwr_i[AR5K_EEPROM_N_PD_GAINS]; u8 pddac_i[AR5K_EEPROM_N_PD_GAINS]; /* (pwr,pddac) points * power levels in 0.5dB units */ s8 pwr[AR5K_EEPROM_N_PD_GAINS] [AR5K_EEPROM_N_PD_POINTS]; u8 pddac[AR5K_EEPROM_N_PD_GAINS] [AR5K_EEPROM_N_PD_POINTS]; }; enum ath5k_powertable_type { AR5K_PWRTABLE_PWR_TO_PCDAC = 0, AR5K_PWRTABLE_LINEAR_PCDAC = 1, AR5K_PWRTABLE_PWR_TO_PDADC = 2, }; struct ath5k_pdgain_info { u8 pd_points; u8 *pd_step; /* Power values are in * 0.25dB units */ s16 *pd_pwr; }; struct ath5k_chan_pcal_info { /* Frequency */ u16 freq; /* Tx power boundaries */ s16 max_pwr; s16 min_pwr; union { struct ath5k_chan_pcal_info_rf5111 rf5111_info; struct ath5k_chan_pcal_info_rf5112 rf5112_info; struct ath5k_chan_pcal_info_rf2413 rf2413_info; }; /* Raw values used by phy code * Curves are stored in order from lower * gain to higher gain (max txpower -> min txpower) */ struct ath5k_pdgain_info *pd_curves; }; /* Per rate calibration data for each mode, * used for rate power table setup. * Note: Values in 0.5dB units */ struct ath5k_rate_pcal_info { u16 freq; /* Frequency */ /* Power level for 6-24Mbit/s rates or * 1Mb rate */ u16 target_power_6to24; /* Power level for 36Mbit rate or * 2Mb rate */ u16 target_power_36; /* Power level for 48Mbit rate or * 5.5Mbit rate */ u16 target_power_48; /* Power level for 54Mbit rate or * 11Mbit rate */ u16 target_power_54; }; /* Power edges for conformance test limits */ struct ath5k_edge_power { u16 freq; u16 edge; /* in half dBm */ int flag; }; /* EEPROM calibration data */ struct ath5k_eeprom_info { /* Header information */ u16 ee_magic; u16 ee_protect; u16 ee_regdomain; u16 ee_version; u16 ee_header; u16 ee_ant_gain; u16 ee_misc0; u16 ee_misc1; u16 ee_misc2; u16 ee_misc3; u16 ee_misc4; u16 ee_misc5; u16 ee_misc6; u16 ee_cck_ofdm_gain_delta; u16 ee_cck_ofdm_power_delta; u16 ee_scaled_cck_delta; /* RF Calibration settings (reset, rfregs) */ u16 ee_i_cal[AR5K_EEPROM_N_MODES]; u16 ee_q_cal[AR5K_EEPROM_N_MODES]; u16 ee_fixed_bias[AR5K_EEPROM_N_MODES]; u16 ee_turbo_max_power[AR5K_EEPROM_N_MODES]; u16 ee_xr_power[AR5K_EEPROM_N_MODES]; u16 ee_switch_settling[AR5K_EEPROM_N_MODES]; u16 ee_atn_tx_rx[AR5K_EEPROM_N_MODES]; u16 ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC]; u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; u16 ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES]; u16 ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES]; u16 ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES]; u16 ee_thr_62[AR5K_EEPROM_N_MODES]; u16 ee_xlna_gain[AR5K_EEPROM_N_MODES]; u16 ee_xpd[AR5K_EEPROM_N_MODES]; u16 ee_x_gain[AR5K_EEPROM_N_MODES]; u16 ee_i_gain[AR5K_EEPROM_N_MODES]; u16 ee_margin_tx_rx[AR5K_EEPROM_N_MODES]; u16 ee_switch_settling_turbo[AR5K_EEPROM_N_MODES]; u16 ee_margin_tx_rx_turbo[AR5K_EEPROM_N_MODES]; u16 ee_atn_tx_rx_turbo[AR5K_EEPROM_N_MODES]; /* Power calibration data */ u16 ee_false_detect[AR5K_EEPROM_N_MODES]; /* Number of pd gain curves per mode */ u8 ee_pd_gains[AR5K_EEPROM_N_MODES]; /* Back mapping pdcurve number -> pdcurve index in pd->pd_curves */ u8 ee_pdc_to_idx[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PD_GAINS]; u8 ee_n_piers[AR5K_EEPROM_N_MODES]; struct ath5k_chan_pcal_info ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN]; struct ath5k_chan_pcal_info ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX]; struct ath5k_chan_pcal_info ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX]; /* Per rate target power levels */ u8 ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES]; struct ath5k_rate_pcal_info ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN]; struct ath5k_rate_pcal_info ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX]; struct ath5k_rate_pcal_info ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX]; /* Conformance test limits (Unused) */ u8 ee_ctls; u8 ee_ctl[AR5K_EEPROM_MAX_CTLS]; struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES * AR5K_EEPROM_MAX_CTLS]; /* Noise Floor Calibration settings */ s16 ee_noise_floor_thr[AR5K_EEPROM_N_MODES]; s8 ee_adc_desired_size[AR5K_EEPROM_N_MODES]; s8 ee_pga_desired_size[AR5K_EEPROM_N_MODES]; s8 ee_adc_desired_size_turbo[AR5K_EEPROM_N_MODES]; s8 ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES]; s8 ee_pd_gain_overlap; u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; }; debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k_qcu.c0000664000000000000000000002763012524662415022263 0ustar /* * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2006-2008 Nick Kossifidis * * Lightly modified for gPXE, July 2009, by Joshua Oreman . * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ FILE_LICENCE ( MIT ); /********************************************\ Queue Control Unit, DFS Control Unit Functions \********************************************/ #include "ath5k.h" #include "reg.h" #include "base.h" /* * Set properties for a transmit queue */ int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, const struct ath5k_txq_info *queue_info) { if (ah->ah_txq.tqi_type == AR5K_TX_QUEUE_INACTIVE) return -EIO; memcpy(&ah->ah_txq, queue_info, sizeof(struct ath5k_txq_info)); /*XXX: Is this supported on 5210 ?*/ if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA && ((queue_info->tqi_subtype == AR5K_WME_AC_VI) || (queue_info->tqi_subtype == AR5K_WME_AC_VO))) || queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD) ah->ah_txq.tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; return 0; } /* * Initialize a transmit queue */ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, struct ath5k_txq_info *queue_info) { unsigned int queue; int ret; /* We only use one queue */ queue = 0; /* * Setup internal queue structure */ memset(&ah->ah_txq, 0, sizeof(struct ath5k_txq_info)); ah->ah_txq.tqi_type = queue_type; if (queue_info != NULL) { queue_info->tqi_type = queue_type; ret = ath5k_hw_set_tx_queueprops(ah, queue_info); if (ret) return ret; } /* * We use ah_txq_status to hold a temp value for * the Secondary interrupt mask registers on 5211+ * check out ath5k_hw_reset_tx_queue */ AR5K_Q_ENABLE_BITS(ah->ah_txq_status, 0); return 0; } /* * Set a transmit queue inactive */ void ath5k_hw_release_tx_queue(struct ath5k_hw *ah) { /* This queue will be skipped in further operations */ ah->ah_txq.tqi_type = AR5K_TX_QUEUE_INACTIVE; /*For SIMR setup*/ AR5K_Q_DISABLE_BITS(ah->ah_txq_status, 0); } /* * Set DFS properties for a transmit queue on DCU */ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah) { u32 cw_min, cw_max, retry_lg, retry_sh; struct ath5k_txq_info *tq = &ah->ah_txq; const int queue = 0; tq = &ah->ah_txq; if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE) return 0; if (ah->ah_version == AR5K_AR5210) { /* Only handle data queues, others will be ignored */ if (tq->tqi_type != AR5K_TX_QUEUE_DATA) return 0; /* Set Slot time */ ath5k_hw_reg_write(ah, ah->ah_turbo ? AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME, AR5K_SLOT_TIME); /* Set ACK_CTS timeout */ ath5k_hw_reg_write(ah, ah->ah_turbo ? AR5K_INIT_ACK_CTS_TIMEOUT_TURBO : AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME); /* Set Transmit Latency */ ath5k_hw_reg_write(ah, ah->ah_turbo ? AR5K_INIT_TRANSMIT_LATENCY_TURBO : AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210); /* Set IFS0 */ if (ah->ah_turbo) { ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO + (ah->ah_aifs + tq->tqi_aifs) * AR5K_INIT_SLOT_TIME_TURBO) << AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO, AR5K_IFS0); } else { ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS + (ah->ah_aifs + tq->tqi_aifs) * AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS, AR5K_IFS0); } /* Set IFS1 */ ath5k_hw_reg_write(ah, ah->ah_turbo ? AR5K_INIT_PROTO_TIME_CNTRL_TURBO : AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1); /* Set AR5K_PHY_SETTLING */ ath5k_hw_reg_write(ah, ah->ah_turbo ? (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) | 0x38 : (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) | 0x1C, AR5K_PHY_SETTLING); /* Set Frame Control Register */ ath5k_hw_reg_write(ah, ah->ah_turbo ? (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT | 0x2020) : (AR5K_PHY_FRAME_CTL_INI | 0x1020), AR5K_PHY_FRAME_CTL_5210); } /* * Calculate cwmin/max by channel mode */ cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN; cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX; ah->ah_aifs = AR5K_TUNE_AIFS; /*XR is only supported on 5212*/ if (IS_CHAN_XR(ah->ah_current_channel) && ah->ah_version == AR5K_AR5212) { cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR; cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR; ah->ah_aifs = AR5K_TUNE_AIFS_XR; /*B mode is not supported on 5210*/ } else if (IS_CHAN_B(ah->ah_current_channel) && ah->ah_version != AR5K_AR5210) { cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B; cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B; ah->ah_aifs = AR5K_TUNE_AIFS_11B; } cw_min = 1; while (cw_min < ah->ah_cw_min) cw_min = (cw_min << 1) | 1; cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) : ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1); cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) : ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1); /* * Calculate and set retry limits */ if (ah->ah_software_retry) { /* XXX Need to test this */ retry_lg = ah->ah_limit_tx_retries; retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ? AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg; } else { retry_lg = AR5K_INIT_LG_RETRY; retry_sh = AR5K_INIT_SH_RETRY; } /*No QCU/DCU [5210]*/ if (ah->ah_version == AR5K_AR5210) { ath5k_hw_reg_write(ah, (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, AR5K_NODCU_RETRY_LMT_SLG_RETRY) | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, AR5K_NODCU_RETRY_LMT_SSH_RETRY) | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY) | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY), AR5K_NODCU_RETRY_LMT); } else { /*QCU/DCU [5211+]*/ ath5k_hw_reg_write(ah, AR5K_REG_SM(AR5K_INIT_SLG_RETRY, AR5K_DCU_RETRY_LMT_SLG_RETRY) | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, AR5K_DCU_RETRY_LMT_SSH_RETRY) | AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) | AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY), AR5K_QUEUE_DFS_RETRY_LIMIT(queue)); /*===Rest is also for QCU/DCU only [5211+]===*/ /* * Set initial content window (cw_min/cw_max) * and arbitrated interframe space (aifs)... */ ath5k_hw_reg_write(ah, AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS), AR5K_QUEUE_DFS_LOCAL_IFS(queue)); /* * Set misc registers */ /* Enable DCU early termination for this queue */ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), AR5K_QCU_MISC_DCU_EARLY); /* Enable DCU to wait for next fragment from QCU */ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), AR5K_DCU_MISC_FRAG_WAIT); /* On Maui and Spirit use the global seqnum on DCU */ if (ah->ah_mac_version < AR5K_SREV_AR5211) AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), AR5K_DCU_MISC_SEQNUM_CTL); if (tq->tqi_cbr_period) { ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period, AR5K_QCU_CBRCFG_INTVAL) | AR5K_REG_SM(tq->tqi_cbr_overflow_limit, AR5K_QCU_CBRCFG_ORN_THRES), AR5K_QUEUE_CBRCFG(queue)); AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), AR5K_QCU_MISC_FRSHED_CBR); if (tq->tqi_cbr_overflow_limit) AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), AR5K_QCU_MISC_CBR_THRES_ENABLE); } if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_ID_CAB)) ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time, AR5K_QCU_RDYTIMECFG_INTVAL) | AR5K_QCU_RDYTIMECFG_ENABLE, AR5K_QUEUE_RDYTIMECFG(queue)); if (tq->tqi_burst_time) { ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time, AR5K_DCU_CHAN_TIME_DUR) | AR5K_DCU_CHAN_TIME_ENABLE, AR5K_QUEUE_DFS_CHANNEL_TIME(queue)); if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), AR5K_QCU_MISC_RDY_VEOL_POLICY); } if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS, AR5K_QUEUE_DFS_MISC(queue)); if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG, AR5K_QUEUE_DFS_MISC(queue)); /* TODO: Handle frame compression */ /* * Enable interrupts for this tx queue * in the secondary interrupt mask registers */ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE) AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue); if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE) AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue); if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE) AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue); if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE) AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue); if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE) AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue); if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE) AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue); if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE) AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue); if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE) AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue); if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE) AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue); /* Update secondary interrupt mask registers */ /* Filter out inactive queues */ ah->ah_txq_imr_txok &= ah->ah_txq_status; ah->ah_txq_imr_txerr &= ah->ah_txq_status; ah->ah_txq_imr_txurn &= ah->ah_txq_status; ah->ah_txq_imr_txdesc &= ah->ah_txq_status; ah->ah_txq_imr_txeol &= ah->ah_txq_status; ah->ah_txq_imr_cbrorn &= ah->ah_txq_status; ah->ah_txq_imr_cbrurn &= ah->ah_txq_status; ah->ah_txq_imr_qtrig &= ah->ah_txq_status; ah->ah_txq_imr_nofrm &= ah->ah_txq_status; ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok, AR5K_SIMR0_QCU_TXOK) | AR5K_REG_SM(ah->ah_txq_imr_txdesc, AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0); ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr, AR5K_SIMR1_QCU_TXERR) | AR5K_REG_SM(ah->ah_txq_imr_txeol, AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1); /* Update simr2 but don't overwrite rest simr2 settings */ AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN); AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_REG_SM(ah->ah_txq_imr_txurn, AR5K_SIMR2_QCU_TXURN)); ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn, AR5K_SIMR3_QCBRORN) | AR5K_REG_SM(ah->ah_txq_imr_cbrurn, AR5K_SIMR3_QCBRURN), AR5K_SIMR3); ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig, AR5K_SIMR4_QTRIG), AR5K_SIMR4); /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm, AR5K_TXNOFRM_QCU), AR5K_TXNOFRM); /* No queue has TXNOFRM enabled, disable the interrupt * by setting AR5K_TXNOFRM to zero */ if (ah->ah_txq_imr_nofrm == 0) ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM); /* Set QCU mask for this DCU to save power */ AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue); } return 0; } /* * Set slot time on DCU */ int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) { if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX) return -EINVAL; if (ah->ah_version == AR5K_AR5210) ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time, ah->ah_turbo), AR5K_SLOT_TIME); else ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT); return 0; } debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k_desc.c0000664000000000000000000003576212524662415022416 0ustar /* * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2006-2008 Nick Kossifidis * Copyright (c) 2007-2008 Pavel Roskin * * Lightly modified for gPXE, July 2009, by Joshua Oreman . * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ FILE_LICENCE ( MIT ); /******************************\ Hardware Descriptor Functions \******************************/ #include "ath5k.h" #include "reg.h" #include "base.h" /* * TX Descriptors */ #define FCS_LEN 4 /* * Initialize the 2-word tx control descriptor on 5210/5211 */ static int ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type, unsigned int tx_power __unused, unsigned int tx_rate0, unsigned int tx_tries0, unsigned int key_index __unused, unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate __unused, unsigned int rtscts_duration) { u32 frame_type; struct ath5k_hw_2w_tx_ctl *tx_ctl; unsigned int frame_len; tx_ctl = &desc->ud.ds_tx5210.tx_ctl; /* * Validate input * - Zero retries don't make sense. * - A zero rate will put the HW into a mode where it continously sends * noise on the channel, so it is important to avoid this. */ if (tx_tries0 == 0) { DBG("ath5k: zero retries\n"); return -EINVAL; } if (tx_rate0 == 0) { DBG("ath5k: zero rate\n"); return -EINVAL; } /* Clear descriptor */ memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc)); /* Setup control descriptor */ /* Verify and set frame length */ frame_len = pkt_len + FCS_LEN; if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; /* Verify and set buffer length */ if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN) return -EINVAL; tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; /* * Verify and set header length * XXX: I only found that on 5210 code, does it work on 5211 ? */ if (ah->ah_version == AR5K_AR5210) { if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN) return -EINVAL; tx_ctl->tx_control_0 |= AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); } /*Diferences between 5210-5211*/ if (ah->ah_version == AR5K_AR5210) { switch (type) { case AR5K_PKT_TYPE_BEACON: case AR5K_PKT_TYPE_PROBE_RESP: frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; case AR5K_PKT_TYPE_PIFS: frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; default: frame_type = type /*<< 2 ?*/; } tx_ctl->tx_control_0 |= AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) | AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); } else { tx_ctl->tx_control_0 |= AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) | AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT); tx_ctl->tx_control_1 |= AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE); } #define _TX_FLAGS(_c, _flag) \ if (flags & AR5K_TXDESC_##_flag) { \ tx_ctl->tx_control_##_c |= \ AR5K_2W_TX_DESC_CTL##_c##_##_flag; \ } _TX_FLAGS(0, CLRDMASK); _TX_FLAGS(0, VEOL); _TX_FLAGS(0, INTREQ); _TX_FLAGS(0, RTSENA); _TX_FLAGS(1, NOACK); #undef _TX_FLAGS /* * RTS/CTS Duration [5210 ?] */ if ((ah->ah_version == AR5K_AR5210) && (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA))) tx_ctl->tx_control_1 |= rtscts_duration & AR5K_2W_TX_DESC_CTL1_RTS_DURATION; return 0; } /* * Initialize the 4-word tx control descriptor on 5212 */ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len __unused, enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, unsigned int key_index __unused, unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate, unsigned int rtscts_duration) { struct ath5k_hw_4w_tx_ctl *tx_ctl; unsigned int frame_len; tx_ctl = &desc->ud.ds_tx5212.tx_ctl; /* * Validate input * - Zero retries don't make sense. * - A zero rate will put the HW into a mode where it continously sends * noise on the channel, so it is important to avoid this. */ if (tx_tries0 == 0) { DBG("ath5k: zero retries\n"); return -EINVAL; } if (tx_rate0 == 0) { DBG("ath5k: zero rate\n"); return -EINVAL; } tx_power += ah->ah_txpower.txp_offset; if (tx_power > AR5K_TUNE_MAX_TXPOWER) tx_power = AR5K_TUNE_MAX_TXPOWER; /* Clear descriptor */ memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); /* Setup control descriptor */ /* Verify and set frame length */ frame_len = pkt_len + FCS_LEN; if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; /* Verify and set buffer length */ if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) return -EINVAL; tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; tx_ctl->tx_control_0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); tx_ctl->tx_control_1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; #define _TX_FLAGS(_c, _flag) \ if (flags & AR5K_TXDESC_##_flag) { \ tx_ctl->tx_control_##_c |= \ AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ } _TX_FLAGS(0, CLRDMASK); _TX_FLAGS(0, VEOL); _TX_FLAGS(0, INTREQ); _TX_FLAGS(0, RTSENA); _TX_FLAGS(0, CTSENA); _TX_FLAGS(1, NOACK); #undef _TX_FLAGS /* * RTS/CTS */ if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) { if ((flags & AR5K_TXDESC_RTSENA) && (flags & AR5K_TXDESC_CTSENA)) return -EINVAL; tx_ctl->tx_control_2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION; tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate, AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); } return 0; } /* * Proccess the tx status descriptor on 5210/5211 */ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah __unused, struct ath5k_desc *desc, struct ath5k_tx_status *ts) { struct ath5k_hw_2w_tx_ctl *tx_ctl; struct ath5k_hw_tx_status *tx_status; tx_ctl = &desc->ud.ds_tx5210.tx_ctl; tx_status = &desc->ud.ds_tx5210.tx_stat; /* No frame has been send or error */ if ((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0) return -EINPROGRESS; /* * Get descriptor status */ ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); /*TODO: ts->ts_virtcol + test*/ ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, AR5K_DESC_TX_STATUS1_SEQ_NUM); ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); ts->ts_antenna = 1; ts->ts_status = 0; ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); ts->ts_retry[0] = ts->ts_longretry; ts->ts_final_idx = 0; if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) ts->ts_status |= AR5K_TXERR_XRETRY; if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) ts->ts_status |= AR5K_TXERR_FIFO; if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) ts->ts_status |= AR5K_TXERR_FILT; } return 0; } /* * Proccess a tx status descriptor on 5212 */ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah __unused, struct ath5k_desc *desc, struct ath5k_tx_status *ts) { struct ath5k_hw_4w_tx_ctl *tx_ctl; struct ath5k_hw_tx_status *tx_status; tx_ctl = &desc->ud.ds_tx5212.tx_ctl; tx_status = &desc->ud.ds_tx5212.tx_stat; /* No frame has been send or error */ if (!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE)) return -EINPROGRESS; /* * Get descriptor status */ ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, AR5K_DESC_TX_STATUS1_SEQ_NUM); ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); ts->ts_antenna = (tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; ts->ts_status = 0; ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX); ts->ts_retry[0] = ts->ts_longretry; ts->ts_rate[0] = tx_ctl->tx_control_3 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; /* TX error */ if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) ts->ts_status |= AR5K_TXERR_XRETRY; if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) ts->ts_status |= AR5K_TXERR_FIFO; if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) ts->ts_status |= AR5K_TXERR_FILT; } return 0; } /* * RX Descriptors */ /* * Initialize an rx control descriptor */ static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah __unused, struct ath5k_desc *desc, u32 size, unsigned int flags) { struct ath5k_hw_rx_ctl *rx_ctl; rx_ctl = &desc->ud.ds_rx.rx_ctl; /* * Clear the descriptor * If we don't clean the status descriptor, * while scanning we get too many results, * most of them virtual, after some secs * of scanning system hangs. M.F. */ memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc)); /* Setup descriptor */ rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; if (rx_ctl->rx_control_1 != size) return -EINVAL; if (flags & AR5K_RXDESC_INTREQ) rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; return 0; } /* * Proccess the rx status descriptor on 5210/5211 */ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah __unused, struct ath5k_desc *desc, struct ath5k_rx_status *rs) { struct ath5k_hw_rx_status *rx_status; rx_status = &desc->ud.ds_rx.u.rx_stat; /* No frame received / not ready */ if (!(rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_DONE)) return -EINPROGRESS; /* * Frame receive status */ rs->rs_datalen = rx_status->rx_status_0 & AR5K_5210_RX_DESC_STATUS0_DATA_LEN; rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA); rs->rs_more = !!(rx_status->rx_status_0 & AR5K_5210_RX_DESC_STATUS0_MORE); /* TODO: this timestamp is 13 bit, later on we assume 15 bit */ rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); rs->rs_status = 0; rs->rs_phyerr = 0; rs->rs_keyix = AR5K_RXKEYIX_INVALID; /* * Receive/descriptor errors */ if (!(rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_CRC_ERROR) rs->rs_status |= AR5K_RXERR_CRC; if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN) rs->rs_status |= AR5K_RXERR_FIFO; if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { rs->rs_status |= AR5K_RXERR_PHY; rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1, AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); } if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) rs->rs_status |= AR5K_RXERR_DECRYPT; } return 0; } /* * Proccess the rx status descriptor on 5212 */ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah __unused, struct ath5k_desc *desc, struct ath5k_rx_status *rs) { struct ath5k_hw_rx_status *rx_status; struct ath5k_hw_rx_error *rx_err; rx_status = &desc->ud.ds_rx.u.rx_stat; /* Overlay on error */ rx_err = &desc->ud.ds_rx.u.rx_err; /* No frame received / not ready */ if (!(rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_DONE)) return -EINPROGRESS; /* * Frame receive status */ rs->rs_datalen = rx_status->rx_status_0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN; rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); rs->rs_more = !!(rx_status->rx_status_0 & AR5K_5212_RX_DESC_STATUS0_MORE); rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); rs->rs_status = 0; rs->rs_phyerr = 0; rs->rs_keyix = AR5K_RXKEYIX_INVALID; /* * Receive/descriptor errors */ if (!(rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) rs->rs_status |= AR5K_RXERR_CRC; if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { rs->rs_status |= AR5K_RXERR_PHY; rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); } if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) rs->rs_status |= AR5K_RXERR_DECRYPT; if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) rs->rs_status |= AR5K_RXERR_MIC; } return 0; } /* * Init function pointers inside ath5k_hw struct */ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah) { if (ah->ah_version != AR5K_AR5210 && ah->ah_version != AR5K_AR5211 && ah->ah_version != AR5K_AR5212) return -ENOTSUP; if (ah->ah_version == AR5K_AR5212) { ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status; } else { ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; } if (ah->ah_version == AR5K_AR5212) ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status; else if (ah->ah_version <= AR5K_AR5211) ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status; return 0; } debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k_caps.c0000664000000000000000000001032312524662415022410 0ustar /* * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2006-2008 Nick Kossifidis * Copyright (c) 2007-2008 Jiri Slaby * * Lightly modified for gPXE, July 2009, by Joshua Oreman . * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ FILE_LICENCE ( MIT ); /**************\ * Capabilities * \**************/ #include "ath5k.h" #include "reg.h" #include "base.h" /* * Fill the capabilities struct * TODO: Merge this with EEPROM code when we are done with it */ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) { u16 ee_header; /* Capabilities stored in the EEPROM */ ee_header = ah->ah_capabilities.cap_eeprom.ee_header; if (ah->ah_version == AR5K_AR5210) { /* * Set radio capabilities * (The AR5110 only supports the middle 5GHz band) */ ah->ah_capabilities.cap_range.range_5ghz_min = 5120; ah->ah_capabilities.cap_range.range_5ghz_max = 5430; ah->ah_capabilities.cap_range.range_2ghz_min = 0; ah->ah_capabilities.cap_range.range_2ghz_max = 0; /* Set supported modes */ ah->ah_capabilities.cap_mode |= AR5K_MODE_BIT_11A; ah->ah_capabilities.cap_mode |= AR5K_MODE_BIT_11A_TURBO; } else { /* * XXX The tranceiver supports frequencies from 4920 to 6100GHz * XXX and from 2312 to 2732GHz. There are problems with the * XXX current ieee80211 implementation because the IEEE * XXX channel mapping does not support negative channel * XXX numbers (2312MHz is channel -19). Of course, this * XXX doesn't matter because these channels are out of range * XXX but some regulation domains like MKK (Japan) will * XXX support frequencies somewhere around 4.8GHz. */ /* * Set radio capabilities */ if (AR5K_EEPROM_HDR_11A(ee_header)) { /* 4920 */ ah->ah_capabilities.cap_range.range_5ghz_min = 5005; ah->ah_capabilities.cap_range.range_5ghz_max = 6100; /* Set supported modes */ ah->ah_capabilities.cap_mode |= AR5K_MODE_BIT_11A; ah->ah_capabilities.cap_mode |= AR5K_MODE_BIT_11A_TURBO; if (ah->ah_version == AR5K_AR5212) ah->ah_capabilities.cap_mode |= AR5K_MODE_BIT_11G_TURBO; } /* Enable 802.11b if a 2GHz capable radio (2111/5112) is * connected */ if (AR5K_EEPROM_HDR_11B(ee_header) || (AR5K_EEPROM_HDR_11G(ee_header) && ah->ah_version != AR5K_AR5211)) { /* 2312 */ ah->ah_capabilities.cap_range.range_2ghz_min = 2412; ah->ah_capabilities.cap_range.range_2ghz_max = 2732; if (AR5K_EEPROM_HDR_11B(ee_header)) ah->ah_capabilities.cap_mode |= AR5K_MODE_BIT_11B; if (AR5K_EEPROM_HDR_11G(ee_header) && ah->ah_version != AR5K_AR5211) ah->ah_capabilities.cap_mode |= AR5K_MODE_BIT_11G; } } /* GPIO */ ah->ah_gpio_npins = AR5K_NUM_GPIO; /* Set number of supported TX queues */ ah->ah_capabilities.cap_queues.q_tx_num = 1; return 0; } /* Main function used by the driver part to check caps */ int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability __unused, u32 *result) { switch (cap_type) { case AR5K_CAP_NUM_TXQUEUES: if (result) { *result = 1; goto yes; } case AR5K_CAP_VEOL: goto yes; case AR5K_CAP_COMPRESSION: if (ah->ah_version == AR5K_AR5212) goto yes; else goto no; case AR5K_CAP_BURST: goto yes; case AR5K_CAP_TPC: goto yes; case AR5K_CAP_BSSIDMASK: if (ah->ah_version == AR5K_AR5212) goto yes; else goto no; case AR5K_CAP_XR: if (ah->ah_version == AR5K_AR5212) goto yes; else goto no; default: goto no; } no: return -EINVAL; yes: return 0; } debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k_initvals.c0000664000000000000000000020507012524662415023320 0ustar /* * Initial register settings functions * * Copyright (c) 2004-2007 Reyk Floeter * Copyright (c) 2006-2009 Nick Kossifidis * Copyright (c) 2007-2008 Jiri Slaby * * Lightly modified for gPXE, July 2009, by Joshua Oreman . * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ FILE_LICENCE ( MIT ); #include #include "ath5k.h" #include "reg.h" #include "base.h" /* * Mode-independent initial register writes */ struct ath5k_ini { u16 ini_register; u32 ini_value; enum { AR5K_INI_WRITE = 0, /* Default */ AR5K_INI_READ = 1, /* Cleared on read */ } ini_mode; }; /* * Mode specific initial register values */ struct ath5k_ini_mode { u16 mode_register; u32 mode_value[5]; }; /* Initial register settings for AR5210 */ static const struct ath5k_ini ar5210_ini[] = { /* PCU and MAC registers */ { AR5K_NOQCU_TXDP0, 0, AR5K_INI_WRITE }, { AR5K_NOQCU_TXDP1, 0, AR5K_INI_WRITE }, { AR5K_RXDP, 0, AR5K_INI_WRITE }, { AR5K_CR, 0, AR5K_INI_WRITE }, { AR5K_ISR, 0, AR5K_INI_READ }, { AR5K_IMR, 0, AR5K_INI_WRITE }, { AR5K_IER, AR5K_IER_DISABLE, AR5K_INI_WRITE }, { AR5K_BSR, 0, AR5K_INI_READ }, { AR5K_TXCFG, AR5K_DMASIZE_128B, AR5K_INI_WRITE }, { AR5K_RXCFG, AR5K_DMASIZE_128B, AR5K_INI_WRITE }, { AR5K_CFG, AR5K_INIT_CFG, AR5K_INI_WRITE }, { AR5K_TOPS, 8, AR5K_INI_WRITE }, { AR5K_RXNOFRM, 8, AR5K_INI_WRITE }, { AR5K_RPGTO, 0, AR5K_INI_WRITE }, { AR5K_TXNOFRM, 0, AR5K_INI_WRITE }, { AR5K_SFR, 0, AR5K_INI_WRITE }, { AR5K_MIBC, 0, AR5K_INI_WRITE }, { AR5K_MISC, 0, AR5K_INI_WRITE }, { AR5K_RX_FILTER_5210, 0, AR5K_INI_WRITE }, { AR5K_MCAST_FILTER0_5210, 0, AR5K_INI_WRITE }, { AR5K_MCAST_FILTER1_5210, 0, AR5K_INI_WRITE }, { AR5K_TX_MASK0, 0, AR5K_INI_WRITE }, { AR5K_TX_MASK1, 0, AR5K_INI_WRITE }, { AR5K_CLR_TMASK, 0, AR5K_INI_WRITE }, { AR5K_TRIG_LVL, AR5K_TUNE_MIN_TX_FIFO_THRES, AR5K_INI_WRITE }, { AR5K_DIAG_SW_5210, 0, AR5K_INI_WRITE }, { AR5K_RSSI_THR, AR5K_TUNE_RSSI_THRES, AR5K_INI_WRITE }, { AR5K_TSF_L32_5210, 0, AR5K_INI_WRITE }, { AR5K_TIMER0_5210, 0, AR5K_INI_WRITE }, { AR5K_TIMER1_5210, 0xffffffff, AR5K_INI_WRITE }, { AR5K_TIMER2_5210, 0xffffffff, AR5K_INI_WRITE }, { AR5K_TIMER3_5210, 1, AR5K_INI_WRITE }, { AR5K_CFP_DUR_5210, 0, AR5K_INI_WRITE }, { AR5K_CFP_PERIOD_5210, 0, AR5K_INI_WRITE }, /* PHY registers */ { AR5K_PHY(0), 0x00000047, AR5K_INI_WRITE }, { AR5K_PHY_AGC, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(3), 0x09848ea6, AR5K_INI_WRITE }, { AR5K_PHY(4), 0x3d32e000, AR5K_INI_WRITE }, { AR5K_PHY(5), 0x0000076b, AR5K_INI_WRITE }, { AR5K_PHY_ACT, AR5K_PHY_ACT_DISABLE, AR5K_INI_WRITE }, { AR5K_PHY(8), 0x02020200, AR5K_INI_WRITE }, { AR5K_PHY(9), 0x00000e0e, AR5K_INI_WRITE }, { AR5K_PHY(10), 0x0a020201, AR5K_INI_WRITE }, { AR5K_PHY(11), 0x00036ffc, AR5K_INI_WRITE }, { AR5K_PHY(12), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(13), 0x00000e0e, AR5K_INI_WRITE }, { AR5K_PHY(14), 0x00000007, AR5K_INI_WRITE }, { AR5K_PHY(15), 0x00020100, AR5K_INI_WRITE }, { AR5K_PHY(16), 0x89630000, AR5K_INI_WRITE }, { AR5K_PHY(17), 0x1372169c, AR5K_INI_WRITE }, { AR5K_PHY(18), 0x0018b633, AR5K_INI_WRITE }, { AR5K_PHY(19), 0x1284613c, AR5K_INI_WRITE }, { AR5K_PHY(20), 0x0de8b8e0, AR5K_INI_WRITE }, { AR5K_PHY(21), 0x00074859, AR5K_INI_WRITE }, { AR5K_PHY(22), 0x7e80beba, AR5K_INI_WRITE }, { AR5K_PHY(23), 0x313a665e, AR5K_INI_WRITE }, { AR5K_PHY_AGCCTL, 0x00001d08, AR5K_INI_WRITE }, { AR5K_PHY(25), 0x0001ce00, AR5K_INI_WRITE }, { AR5K_PHY(26), 0x409a4190, AR5K_INI_WRITE }, { AR5K_PHY(28), 0x0000000f, AR5K_INI_WRITE }, { AR5K_PHY(29), 0x00000080, AR5K_INI_WRITE }, { AR5K_PHY(30), 0x00000004, AR5K_INI_WRITE }, { AR5K_PHY(31), 0x00000018, AR5K_INI_WRITE }, /* 0x987c */ { AR5K_PHY(64), 0x00000000, AR5K_INI_WRITE }, /* 0x9900 */ { AR5K_PHY(65), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(66), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(67), 0x00800000, AR5K_INI_WRITE }, { AR5K_PHY(68), 0x00000003, AR5K_INI_WRITE }, /* BB gain table (64bytes) */ { AR5K_BB_GAIN(0), 0x00000000, AR5K_INI_WRITE }, { AR5K_BB_GAIN(1), 0x00000020, AR5K_INI_WRITE }, { AR5K_BB_GAIN(2), 0x00000010, AR5K_INI_WRITE }, { AR5K_BB_GAIN(3), 0x00000030, AR5K_INI_WRITE }, { AR5K_BB_GAIN(4), 0x00000008, AR5K_INI_WRITE }, { AR5K_BB_GAIN(5), 0x00000028, AR5K_INI_WRITE }, { AR5K_BB_GAIN(6), 0x00000028, AR5K_INI_WRITE }, { AR5K_BB_GAIN(7), 0x00000004, AR5K_INI_WRITE }, { AR5K_BB_GAIN(8), 0x00000024, AR5K_INI_WRITE }, { AR5K_BB_GAIN(9), 0x00000014, AR5K_INI_WRITE }, { AR5K_BB_GAIN(10), 0x00000034, AR5K_INI_WRITE }, { AR5K_BB_GAIN(11), 0x0000000c, AR5K_INI_WRITE }, { AR5K_BB_GAIN(12), 0x0000002c, AR5K_INI_WRITE }, { AR5K_BB_GAIN(13), 0x00000002, AR5K_INI_WRITE }, { AR5K_BB_GAIN(14), 0x00000022, AR5K_INI_WRITE }, { AR5K_BB_GAIN(15), 0x00000012, AR5K_INI_WRITE }, { AR5K_BB_GAIN(16), 0x00000032, AR5K_INI_WRITE }, { AR5K_BB_GAIN(17), 0x0000000a, AR5K_INI_WRITE }, { AR5K_BB_GAIN(18), 0x0000002a, AR5K_INI_WRITE }, { AR5K_BB_GAIN(19), 0x00000001, AR5K_INI_WRITE }, { AR5K_BB_GAIN(20), 0x00000021, AR5K_INI_WRITE }, { AR5K_BB_GAIN(21), 0x00000011, AR5K_INI_WRITE }, { AR5K_BB_GAIN(22), 0x00000031, AR5K_INI_WRITE }, { AR5K_BB_GAIN(23), 0x00000009, AR5K_INI_WRITE }, { AR5K_BB_GAIN(24), 0x00000029, AR5K_INI_WRITE }, { AR5K_BB_GAIN(25), 0x00000005, AR5K_INI_WRITE }, { AR5K_BB_GAIN(26), 0x00000025, AR5K_INI_WRITE }, { AR5K_BB_GAIN(27), 0x00000015, AR5K_INI_WRITE }, { AR5K_BB_GAIN(28), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(29), 0x0000000d, AR5K_INI_WRITE }, { AR5K_BB_GAIN(30), 0x0000002d, AR5K_INI_WRITE }, { AR5K_BB_GAIN(31), 0x00000003, AR5K_INI_WRITE }, { AR5K_BB_GAIN(32), 0x00000023, AR5K_INI_WRITE }, { AR5K_BB_GAIN(33), 0x00000013, AR5K_INI_WRITE }, { AR5K_BB_GAIN(34), 0x00000033, AR5K_INI_WRITE }, { AR5K_BB_GAIN(35), 0x0000000b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(36), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(37), 0x00000007, AR5K_INI_WRITE }, { AR5K_BB_GAIN(38), 0x00000027, AR5K_INI_WRITE }, { AR5K_BB_GAIN(39), 0x00000017, AR5K_INI_WRITE }, { AR5K_BB_GAIN(40), 0x00000037, AR5K_INI_WRITE }, { AR5K_BB_GAIN(41), 0x0000000f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(42), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(43), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(44), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(45), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(46), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(47), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(48), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(49), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(50), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(51), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(52), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(53), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(54), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(55), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(56), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(57), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(58), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(59), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(60), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(61), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(62), 0x0000002f, AR5K_INI_WRITE }, { AR5K_BB_GAIN(63), 0x0000002f, AR5K_INI_WRITE }, /* 5110 RF gain table (64btes) */ { AR5K_RF_GAIN(0), 0x0000001d, AR5K_INI_WRITE }, { AR5K_RF_GAIN(1), 0x0000005d, AR5K_INI_WRITE }, { AR5K_RF_GAIN(2), 0x0000009d, AR5K_INI_WRITE }, { AR5K_RF_GAIN(3), 0x000000dd, AR5K_INI_WRITE }, { AR5K_RF_GAIN(4), 0x0000011d, AR5K_INI_WRITE }, { AR5K_RF_GAIN(5), 0x00000021, AR5K_INI_WRITE }, { AR5K_RF_GAIN(6), 0x00000061, AR5K_INI_WRITE }, { AR5K_RF_GAIN(7), 0x000000a1, AR5K_INI_WRITE }, { AR5K_RF_GAIN(8), 0x000000e1, AR5K_INI_WRITE }, { AR5K_RF_GAIN(9), 0x00000031, AR5K_INI_WRITE }, { AR5K_RF_GAIN(10), 0x00000071, AR5K_INI_WRITE }, { AR5K_RF_GAIN(11), 0x000000b1, AR5K_INI_WRITE }, { AR5K_RF_GAIN(12), 0x0000001c, AR5K_INI_WRITE }, { AR5K_RF_GAIN(13), 0x0000005c, AR5K_INI_WRITE }, { AR5K_RF_GAIN(14), 0x00000029, AR5K_INI_WRITE }, { AR5K_RF_GAIN(15), 0x00000069, AR5K_INI_WRITE }, { AR5K_RF_GAIN(16), 0x000000a9, AR5K_INI_WRITE }, { AR5K_RF_GAIN(17), 0x00000020, AR5K_INI_WRITE }, { AR5K_RF_GAIN(18), 0x00000019, AR5K_INI_WRITE }, { AR5K_RF_GAIN(19), 0x00000059, AR5K_INI_WRITE }, { AR5K_RF_GAIN(20), 0x00000099, AR5K_INI_WRITE }, { AR5K_RF_GAIN(21), 0x00000030, AR5K_INI_WRITE }, { AR5K_RF_GAIN(22), 0x00000005, AR5K_INI_WRITE }, { AR5K_RF_GAIN(23), 0x00000025, AR5K_INI_WRITE }, { AR5K_RF_GAIN(24), 0x00000065, AR5K_INI_WRITE }, { AR5K_RF_GAIN(25), 0x000000a5, AR5K_INI_WRITE }, { AR5K_RF_GAIN(26), 0x00000028, AR5K_INI_WRITE }, { AR5K_RF_GAIN(27), 0x00000068, AR5K_INI_WRITE }, { AR5K_RF_GAIN(28), 0x0000001f, AR5K_INI_WRITE }, { AR5K_RF_GAIN(29), 0x0000001e, AR5K_INI_WRITE }, { AR5K_RF_GAIN(30), 0x00000018, AR5K_INI_WRITE }, { AR5K_RF_GAIN(31), 0x00000058, AR5K_INI_WRITE }, { AR5K_RF_GAIN(32), 0x00000098, AR5K_INI_WRITE }, { AR5K_RF_GAIN(33), 0x00000003, AR5K_INI_WRITE }, { AR5K_RF_GAIN(34), 0x00000004, AR5K_INI_WRITE }, { AR5K_RF_GAIN(35), 0x00000044, AR5K_INI_WRITE }, { AR5K_RF_GAIN(36), 0x00000084, AR5K_INI_WRITE }, { AR5K_RF_GAIN(37), 0x00000013, AR5K_INI_WRITE }, { AR5K_RF_GAIN(38), 0x00000012, AR5K_INI_WRITE }, { AR5K_RF_GAIN(39), 0x00000052, AR5K_INI_WRITE }, { AR5K_RF_GAIN(40), 0x00000092, AR5K_INI_WRITE }, { AR5K_RF_GAIN(41), 0x000000d2, AR5K_INI_WRITE }, { AR5K_RF_GAIN(42), 0x0000002b, AR5K_INI_WRITE }, { AR5K_RF_GAIN(43), 0x0000002a, AR5K_INI_WRITE }, { AR5K_RF_GAIN(44), 0x0000006a, AR5K_INI_WRITE }, { AR5K_RF_GAIN(45), 0x000000aa, AR5K_INI_WRITE }, { AR5K_RF_GAIN(46), 0x0000001b, AR5K_INI_WRITE }, { AR5K_RF_GAIN(47), 0x0000001a, AR5K_INI_WRITE }, { AR5K_RF_GAIN(48), 0x0000005a, AR5K_INI_WRITE }, { AR5K_RF_GAIN(49), 0x0000009a, AR5K_INI_WRITE }, { AR5K_RF_GAIN(50), 0x000000da, AR5K_INI_WRITE }, { AR5K_RF_GAIN(51), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(52), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(53), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(54), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(55), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(56), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(57), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(58), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(59), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(60), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(61), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(62), 0x00000006, AR5K_INI_WRITE }, { AR5K_RF_GAIN(63), 0x00000006, AR5K_INI_WRITE }, /* PHY activation */ { AR5K_PHY(53), 0x00000020, AR5K_INI_WRITE }, { AR5K_PHY(51), 0x00000004, AR5K_INI_WRITE }, { AR5K_PHY(50), 0x00060106, AR5K_INI_WRITE }, { AR5K_PHY(39), 0x0000006d, AR5K_INI_WRITE }, { AR5K_PHY(48), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(52), 0x00000014, AR5K_INI_WRITE }, { AR5K_PHY_ACT, AR5K_PHY_ACT_ENABLE, AR5K_INI_WRITE }, }; /* Initial register settings for AR5211 */ static const struct ath5k_ini ar5211_ini[] = { { AR5K_RXDP, 0x00000000, AR5K_INI_WRITE }, { AR5K_RTSD0, 0x84849c9c, AR5K_INI_WRITE }, { AR5K_RTSD1, 0x7c7c7c7c, AR5K_INI_WRITE }, { AR5K_RXCFG, 0x00000005, AR5K_INI_WRITE }, { AR5K_MIBC, 0x00000000, AR5K_INI_WRITE }, { AR5K_TOPS, 0x00000008, AR5K_INI_WRITE }, { AR5K_RXNOFRM, 0x00000008, AR5K_INI_WRITE }, { AR5K_TXNOFRM, 0x00000010, AR5K_INI_WRITE }, { AR5K_RPGTO, 0x00000000, AR5K_INI_WRITE }, { AR5K_RFCNT, 0x0000001f, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(0), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(1), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(2), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(3), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(4), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(5), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(6), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(7), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(8), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(9), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_FP, 0x00000000, AR5K_INI_WRITE }, { AR5K_STA_ID1, 0x00000000, AR5K_INI_WRITE }, { AR5K_BSS_ID0, 0x00000000, AR5K_INI_WRITE }, { AR5K_BSS_ID1, 0x00000000, AR5K_INI_WRITE }, { AR5K_RSSI_THR, 0x00000000, AR5K_INI_WRITE }, { AR5K_CFP_PERIOD_5211, 0x00000000, AR5K_INI_WRITE }, { AR5K_TIMER0_5211, 0x00000030, AR5K_INI_WRITE }, { AR5K_TIMER1_5211, 0x0007ffff, AR5K_INI_WRITE }, { AR5K_TIMER2_5211, 0x01ffffff, AR5K_INI_WRITE }, { AR5K_TIMER3_5211, 0x00000031, AR5K_INI_WRITE }, { AR5K_CFP_DUR_5211, 0x00000000, AR5K_INI_WRITE }, { AR5K_RX_FILTER_5211, 0x00000000, AR5K_INI_WRITE }, { AR5K_MCAST_FILTER0_5211, 0x00000000, AR5K_INI_WRITE }, { AR5K_MCAST_FILTER1_5211, 0x00000002, AR5K_INI_WRITE }, { AR5K_DIAG_SW_5211, 0x00000000, AR5K_INI_WRITE }, { AR5K_ADDAC_TEST, 0x00000000, AR5K_INI_WRITE }, { AR5K_DEFAULT_ANTENNA, 0x00000000, AR5K_INI_WRITE }, /* PHY registers */ { AR5K_PHY_AGC, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(3), 0x2d849093, AR5K_INI_WRITE }, { AR5K_PHY(4), 0x7d32e000, AR5K_INI_WRITE }, { AR5K_PHY(5), 0x00000f6b, AR5K_INI_WRITE }, { AR5K_PHY_ACT, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(11), 0x00026ffe, AR5K_INI_WRITE }, { AR5K_PHY(12), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(15), 0x00020100, AR5K_INI_WRITE }, { AR5K_PHY(16), 0x206a017a, AR5K_INI_WRITE }, { AR5K_PHY(19), 0x1284613c, AR5K_INI_WRITE }, { AR5K_PHY(21), 0x00000859, AR5K_INI_WRITE }, { AR5K_PHY(26), 0x409a4190, AR5K_INI_WRITE }, /* 0x9868 */ { AR5K_PHY(27), 0x050cb081, AR5K_INI_WRITE }, { AR5K_PHY(28), 0x0000000f, AR5K_INI_WRITE }, { AR5K_PHY(29), 0x00000080, AR5K_INI_WRITE }, { AR5K_PHY(30), 0x0000000c, AR5K_INI_WRITE }, { AR5K_PHY(64), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(65), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(66), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(67), 0x00800000, AR5K_INI_WRITE }, { AR5K_PHY(68), 0x00000001, AR5K_INI_WRITE }, { AR5K_PHY(71), 0x0000092a, AR5K_INI_WRITE }, { AR5K_PHY_IQ, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(73), 0x00058a05, AR5K_INI_WRITE }, { AR5K_PHY(74), 0x00000001, AR5K_INI_WRITE }, { AR5K_PHY(75), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_PAPD_PROBE, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(77), 0x00000000, AR5K_INI_WRITE }, /* 0x9934 */ { AR5K_PHY(78), 0x00000000, AR5K_INI_WRITE }, /* 0x9938 */ { AR5K_PHY(79), 0x0000003f, AR5K_INI_WRITE }, /* 0x993c */ { AR5K_PHY(80), 0x00000004, AR5K_INI_WRITE }, { AR5K_PHY(82), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(83), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(84), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_RADAR, 0x5d50f14c, AR5K_INI_WRITE }, { AR5K_PHY(86), 0x00000018, AR5K_INI_WRITE }, { AR5K_PHY(87), 0x004b6a8e, AR5K_INI_WRITE }, /* Initial Power table (32bytes) * common on all cards/modes. * Note: Table is rewritten during * txpower setup later using calibration * data etc. so next write is non-common */ { AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(4), 0x09ff09ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(5), 0x0aff0aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(6), 0x0bff0bff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(7), 0x0cff0cff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(8), 0x0dff0dff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(9), 0x0fff0eff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(10), 0x12ff12ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(11), 0x14ff13ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(12), 0x16ff15ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(13), 0x19ff17ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(14), 0x1bff1aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(15), 0x1eff1dff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(16), 0x23ff20ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(17), 0x27ff25ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(18), 0x2cff29ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(19), 0x31ff2fff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(20), 0x37ff34ff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(21), 0x3aff3aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(22), 0x3aff3aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(23), 0x3aff3aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(24), 0x3aff3aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(25), 0x3aff3aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(26), 0x3aff3aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(27), 0x3aff3aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff, AR5K_INI_WRITE }, { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff, AR5K_INI_WRITE }, { AR5K_PHY_CCKTXCTL, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(642), 0x503e4646, AR5K_INI_WRITE }, { AR5K_PHY_GAIN_2GHZ, 0x6480416c, AR5K_INI_WRITE }, { AR5K_PHY(644), 0x0199a003, AR5K_INI_WRITE }, { AR5K_PHY(645), 0x044cd610, AR5K_INI_WRITE }, { AR5K_PHY(646), 0x13800040, AR5K_INI_WRITE }, { AR5K_PHY(647), 0x1be00060, AR5K_INI_WRITE }, { AR5K_PHY(648), 0x0c53800a, AR5K_INI_WRITE }, { AR5K_PHY(649), 0x0014df3b, AR5K_INI_WRITE }, { AR5K_PHY(650), 0x000001b5, AR5K_INI_WRITE }, { AR5K_PHY(651), 0x00000020, AR5K_INI_WRITE }, }; /* Initial mode-specific settings for AR5211 * 5211 supports OFDM-only g (draft g) but we * need to test it ! */ static const struct ath5k_ini_mode ar5211_ini_mode[] = { { AR5K_TXCFG, /* a aTurbo b g (OFDM) */ { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } }, { AR5K_QUEUE_DFS_LOCAL_IFS(0), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(1), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(2), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(3), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(4), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(5), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(6), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(7), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(8), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(9), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, { AR5K_DCU_GBL_IFS_SLOT, { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } }, { AR5K_DCU_GBL_IFS_SIFS, { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } }, { AR5K_DCU_GBL_IFS_EIFS, { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } }, { AR5K_DCU_GBL_IFS_MISC, { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } }, { AR5K_TIME_OUT, { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } }, { AR5K_USEC_5211, { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } }, { AR5K_PHY_TURBO, { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } }, { AR5K_PHY(8), { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } }, { AR5K_PHY(9), { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } }, { AR5K_PHY(10), { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } }, { AR5K_PHY(13), { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, { AR5K_PHY(14), { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } }, { AR5K_PHY(17), { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } }, { AR5K_PHY(18), { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } }, { AR5K_PHY(20), { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } }, { AR5K_PHY_SIG, { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } }, { AR5K_PHY_AGCCOARSE, { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } }, { AR5K_PHY_AGCCTL, { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } }, { AR5K_PHY_NF, { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, { AR5K_PHY_RX_DELAY, { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } }, { AR5K_PHY(70), { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } }, { AR5K_PHY_FRAME_CTL_5211, { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } }, { AR5K_PHY_PCDAC_TXPOWER_BASE, { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } }, { AR5K_RF_BUFFER_CONTROL_4, { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } }, }; /* Initial register settings for AR5212 */ static const struct ath5k_ini ar5212_ini_common_start[] = { { AR5K_RXDP, 0x00000000, AR5K_INI_WRITE }, { AR5K_RXCFG, 0x00000005, AR5K_INI_WRITE }, { AR5K_MIBC, 0x00000000, AR5K_INI_WRITE }, { AR5K_TOPS, 0x00000008, AR5K_INI_WRITE }, { AR5K_RXNOFRM, 0x00000008, AR5K_INI_WRITE }, { AR5K_TXNOFRM, 0x00000010, AR5K_INI_WRITE }, { AR5K_RPGTO, 0x00000000, AR5K_INI_WRITE }, { AR5K_RFCNT, 0x0000001f, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(0), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(1), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(2), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(3), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(4), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(5), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(6), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(7), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(8), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUEUE_TXDP(9), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_FP, 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TXP, 0x00000000, AR5K_INI_WRITE }, /* Tx filter table 0 (32 entries) */ { AR5K_DCU_TX_FILTER_0(0), 0x00000000, AR5K_INI_WRITE }, /* DCU 0 */ { AR5K_DCU_TX_FILTER_0(1), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(2), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(3), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(4), 0x00000000, AR5K_INI_WRITE }, /* DCU 1 */ { AR5K_DCU_TX_FILTER_0(5), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(6), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(7), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(8), 0x00000000, AR5K_INI_WRITE }, /* DCU 2 */ { AR5K_DCU_TX_FILTER_0(9), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(10), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(11), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(12), 0x00000000, AR5K_INI_WRITE }, /* DCU 3 */ { AR5K_DCU_TX_FILTER_0(13), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(14), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(15), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(16), 0x00000000, AR5K_INI_WRITE }, /* DCU 4 */ { AR5K_DCU_TX_FILTER_0(17), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(18), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(19), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(20), 0x00000000, AR5K_INI_WRITE }, /* DCU 5 */ { AR5K_DCU_TX_FILTER_0(21), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(22), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(23), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(24), 0x00000000, AR5K_INI_WRITE }, /* DCU 6 */ { AR5K_DCU_TX_FILTER_0(25), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(26), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(27), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(28), 0x00000000, AR5K_INI_WRITE }, /* DCU 7 */ { AR5K_DCU_TX_FILTER_0(29), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(30), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_0(31), 0x00000000, AR5K_INI_WRITE }, /* Tx filter table 1 (16 entries) */ { AR5K_DCU_TX_FILTER_1(0), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(1), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(2), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(3), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(4), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(5), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(6), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(7), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(8), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(9), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(10), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(11), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(12), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(13), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(14), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_1(15), 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_CLR, 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_SET, 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_CLR, 0x00000000, AR5K_INI_WRITE }, { AR5K_DCU_TX_FILTER_SET, 0x00000000, AR5K_INI_WRITE }, { AR5K_STA_ID1, 0x00000000, AR5K_INI_WRITE }, { AR5K_BSS_ID0, 0x00000000, AR5K_INI_WRITE }, { AR5K_BSS_ID1, 0x00000000, AR5K_INI_WRITE }, { AR5K_BEACON_5211, 0x00000000, AR5K_INI_WRITE }, { AR5K_CFP_PERIOD_5211, 0x00000000, AR5K_INI_WRITE }, { AR5K_TIMER0_5211, 0x00000030, AR5K_INI_WRITE }, { AR5K_TIMER1_5211, 0x0007ffff, AR5K_INI_WRITE }, { AR5K_TIMER2_5211, 0x01ffffff, AR5K_INI_WRITE }, { AR5K_TIMER3_5211, 0x00000031, AR5K_INI_WRITE }, { AR5K_CFP_DUR_5211, 0x00000000, AR5K_INI_WRITE }, { AR5K_RX_FILTER_5211, 0x00000000, AR5K_INI_WRITE }, { AR5K_DIAG_SW_5211, 0x00000000, AR5K_INI_WRITE }, { AR5K_ADDAC_TEST, 0x00000000, AR5K_INI_WRITE }, { AR5K_DEFAULT_ANTENNA, 0x00000000, AR5K_INI_WRITE }, { AR5K_FRAME_CTL_QOSM, 0x000fc78f, AR5K_INI_WRITE }, { AR5K_XRMODE, 0x2a82301a, AR5K_INI_WRITE }, { AR5K_XRDELAY, 0x05dc01e0, AR5K_INI_WRITE }, { AR5K_XRTIMEOUT, 0x1f402710, AR5K_INI_WRITE }, { AR5K_XRCHIRP, 0x01f40000, AR5K_INI_WRITE }, { AR5K_XRSTOMP, 0x00001e1c, AR5K_INI_WRITE }, { AR5K_SLEEP0, 0x0002aaaa, AR5K_INI_WRITE }, { AR5K_SLEEP1, 0x02005555, AR5K_INI_WRITE }, { AR5K_SLEEP2, 0x00000000, AR5K_INI_WRITE }, { AR5K_BSS_IDM0, 0xffffffff, AR5K_INI_WRITE }, { AR5K_BSS_IDM1, 0x0000ffff, AR5K_INI_WRITE }, { AR5K_TXPC, 0x00000000, AR5K_INI_WRITE }, { AR5K_PROFCNT_TX, 0x00000000, AR5K_INI_WRITE }, { AR5K_PROFCNT_RX, 0x00000000, AR5K_INI_WRITE }, { AR5K_PROFCNT_RXCLR, 0x00000000, AR5K_INI_WRITE }, { AR5K_PROFCNT_CYCLE, 0x00000000, AR5K_INI_WRITE }, { AR5K_QUIET_CTL1, 0x00000088, AR5K_INI_WRITE }, /* Initial rate duration table (32 entries )*/ { AR5K_RATE_DUR(0), 0x00000000, AR5K_INI_WRITE }, { AR5K_RATE_DUR(1), 0x0000008c, AR5K_INI_WRITE }, { AR5K_RATE_DUR(2), 0x000000e4, AR5K_INI_WRITE }, { AR5K_RATE_DUR(3), 0x000002d5, AR5K_INI_WRITE }, { AR5K_RATE_DUR(4), 0x00000000, AR5K_INI_WRITE }, { AR5K_RATE_DUR(5), 0x00000000, AR5K_INI_WRITE }, { AR5K_RATE_DUR(6), 0x000000a0, AR5K_INI_WRITE }, { AR5K_RATE_DUR(7), 0x000001c9, AR5K_INI_WRITE }, { AR5K_RATE_DUR(8), 0x0000002c, AR5K_INI_WRITE }, { AR5K_RATE_DUR(9), 0x0000002c, AR5K_INI_WRITE }, { AR5K_RATE_DUR(10), 0x00000030, AR5K_INI_WRITE }, { AR5K_RATE_DUR(11), 0x0000003c, AR5K_INI_WRITE }, { AR5K_RATE_DUR(12), 0x0000002c, AR5K_INI_WRITE }, { AR5K_RATE_DUR(13), 0x0000002c, AR5K_INI_WRITE }, { AR5K_RATE_DUR(14), 0x00000030, AR5K_INI_WRITE }, { AR5K_RATE_DUR(15), 0x0000003c, AR5K_INI_WRITE }, { AR5K_RATE_DUR(16), 0x00000000, AR5K_INI_WRITE }, { AR5K_RATE_DUR(17), 0x00000000, AR5K_INI_WRITE }, { AR5K_RATE_DUR(18), 0x00000000, AR5K_INI_WRITE }, { AR5K_RATE_DUR(19), 0x00000000, AR5K_INI_WRITE }, { AR5K_RATE_DUR(20), 0x00000000, AR5K_INI_WRITE }, { AR5K_RATE_DUR(21), 0x00000000, AR5K_INI_WRITE }, { AR5K_RATE_DUR(22), 0x00000000, AR5K_INI_WRITE }, { AR5K_RATE_DUR(23), 0x00000000, AR5K_INI_WRITE }, { AR5K_RATE_DUR(24), 0x000000d5, AR5K_INI_WRITE }, { AR5K_RATE_DUR(25), 0x000000df, AR5K_INI_WRITE }, { AR5K_RATE_DUR(26), 0x00000102, AR5K_INI_WRITE }, { AR5K_RATE_DUR(27), 0x0000013a, AR5K_INI_WRITE }, { AR5K_RATE_DUR(28), 0x00000075, AR5K_INI_WRITE }, { AR5K_RATE_DUR(29), 0x0000007f, AR5K_INI_WRITE }, { AR5K_RATE_DUR(30), 0x000000a2, AR5K_INI_WRITE }, { AR5K_RATE_DUR(31), 0x00000000, AR5K_INI_WRITE }, { AR5K_QUIET_CTL2, 0x00010002, AR5K_INI_WRITE }, { AR5K_TSF_PARM, 0x00000001, AR5K_INI_WRITE }, { AR5K_QOS_NOACK, 0x000000c0, AR5K_INI_WRITE }, { AR5K_PHY_ERR_FIL, 0x00000000, AR5K_INI_WRITE }, { AR5K_XRLAT_TX, 0x00000168, AR5K_INI_WRITE }, { AR5K_ACKSIFS, 0x00000000, AR5K_INI_WRITE }, /* Rate -> db table * notice ...03<-02<-01<-00 ! */ { AR5K_RATE2DB(0), 0x03020100, AR5K_INI_WRITE }, { AR5K_RATE2DB(1), 0x07060504, AR5K_INI_WRITE }, { AR5K_RATE2DB(2), 0x0b0a0908, AR5K_INI_WRITE }, { AR5K_RATE2DB(3), 0x0f0e0d0c, AR5K_INI_WRITE }, { AR5K_RATE2DB(4), 0x13121110, AR5K_INI_WRITE }, { AR5K_RATE2DB(5), 0x17161514, AR5K_INI_WRITE }, { AR5K_RATE2DB(6), 0x1b1a1918, AR5K_INI_WRITE }, { AR5K_RATE2DB(7), 0x1f1e1d1c, AR5K_INI_WRITE }, /* Db -> Rate table */ { AR5K_DB2RATE(0), 0x03020100, AR5K_INI_WRITE }, { AR5K_DB2RATE(1), 0x07060504, AR5K_INI_WRITE }, { AR5K_DB2RATE(2), 0x0b0a0908, AR5K_INI_WRITE }, { AR5K_DB2RATE(3), 0x0f0e0d0c, AR5K_INI_WRITE }, { AR5K_DB2RATE(4), 0x13121110, AR5K_INI_WRITE }, { AR5K_DB2RATE(5), 0x17161514, AR5K_INI_WRITE }, { AR5K_DB2RATE(6), 0x1b1a1918, AR5K_INI_WRITE }, { AR5K_DB2RATE(7), 0x1f1e1d1c, AR5K_INI_WRITE }, /* PHY registers (Common settings * for all chips/modes) */ { AR5K_PHY(3), 0xad848e19, AR5K_INI_WRITE }, { AR5K_PHY(4), 0x7d28e000, AR5K_INI_WRITE }, { AR5K_PHY_TIMING_3, 0x9c0a9f6b, AR5K_INI_WRITE }, { AR5K_PHY_ACT, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY(16), 0x206a017a, AR5K_INI_WRITE }, { AR5K_PHY(21), 0x00000859, AR5K_INI_WRITE }, { AR5K_PHY_BIN_MASK_1, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_BIN_MASK_2, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_BIN_MASK_3, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_BIN_MASK_CTL, 0x00800000, AR5K_INI_WRITE }, { AR5K_PHY_ANT_CTL, 0x00000001, AR5K_INI_WRITE }, /*{ AR5K_PHY(71), 0x0000092a, AR5K_INI_WRITE },*/ /* Old value */ { AR5K_PHY_MAX_RX_LEN, 0x00000c80, AR5K_INI_WRITE }, { AR5K_PHY_IQ, 0x05100000, AR5K_INI_WRITE }, { AR5K_PHY_WARM_RESET, 0x00000001, AR5K_INI_WRITE }, { AR5K_PHY_CTL, 0x00000004, AR5K_INI_WRITE }, { AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022, AR5K_INI_WRITE }, { AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d, AR5K_INI_WRITE }, { AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f, AR5K_INI_WRITE }, { AR5K_PHY(82), 0x9280b212, AR5K_INI_WRITE }, { AR5K_PHY_RADAR, 0x5d50e188, AR5K_INI_WRITE }, /*{ AR5K_PHY(86), 0x000000ff, AR5K_INI_WRITE },*/ { AR5K_PHY(87), 0x004b6a8e, AR5K_INI_WRITE }, { AR5K_PHY_NFTHRES, 0x000003ce, AR5K_INI_WRITE }, { AR5K_PHY_RESTART, 0x192fb515, AR5K_INI_WRITE }, { AR5K_PHY(94), 0x00000001, AR5K_INI_WRITE }, { AR5K_PHY_RFBUS_REQ, 0x00000000, AR5K_INI_WRITE }, /*{ AR5K_PHY(644), 0x0080a333, AR5K_INI_WRITE },*/ /* Old value */ /*{ AR5K_PHY(645), 0x00206c10, AR5K_INI_WRITE },*/ /* Old value */ { AR5K_PHY(644), 0x00806333, AR5K_INI_WRITE }, { AR5K_PHY(645), 0x00106c10, AR5K_INI_WRITE }, { AR5K_PHY(646), 0x009c4060, AR5K_INI_WRITE }, /* { AR5K_PHY(647), 0x1483800a, AR5K_INI_WRITE }, */ /* { AR5K_PHY(648), 0x01831061, AR5K_INI_WRITE }, */ /* Old value */ { AR5K_PHY(648), 0x018830c6, AR5K_INI_WRITE }, { AR5K_PHY(649), 0x00000400, AR5K_INI_WRITE }, /*{ AR5K_PHY(650), 0x000001b5, AR5K_INI_WRITE },*/ { AR5K_PHY(651), 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_TXPOWER_RATE3, 0x20202020, AR5K_INI_WRITE }, { AR5K_PHY_TXPOWER_RATE2, 0x20202020, AR5K_INI_WRITE }, /*{ AR5K_PHY(655), 0x13c889af, AR5K_INI_WRITE },*/ { AR5K_PHY(656), 0x38490a20, AR5K_INI_WRITE }, { AR5K_PHY(657), 0x00007bb6, AR5K_INI_WRITE }, { AR5K_PHY(658), 0x0fff3ffc, AR5K_INI_WRITE }, }; /* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */ static const struct ath5k_ini_mode ar5212_ini_mode_start[] = { { AR5K_QUEUE_DFS_LOCAL_IFS(0), /* a/XR aTurbo b g (DYN) gTurbo */ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(1), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(2), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(3), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(4), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(5), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(6), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(7), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(8), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, { AR5K_QUEUE_DFS_LOCAL_IFS(9), { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, { AR5K_DCU_GBL_IFS_SIFS, { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } }, { AR5K_DCU_GBL_IFS_SLOT, { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } }, { AR5K_DCU_GBL_IFS_EIFS, { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } }, { AR5K_DCU_GBL_IFS_MISC, { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } }, { AR5K_TIME_OUT, { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } }, { AR5K_PHY_TURBO, { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } }, { AR5K_PHY(8), { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } }, { AR5K_PHY_RF_CTL2, { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } }, { AR5K_PHY_SETTLING, { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } }, { AR5K_PHY_AGCCTL, { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } }, { AR5K_PHY_NF, { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, { AR5K_PHY_WEAK_OFDM_HIGH_THR, { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } }, { AR5K_PHY(70), { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } }, { AR5K_PHY_OFDM_SELFCORR, { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } }, { 0xa230, { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } }, }; /* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */ static const struct ath5k_ini_mode rf5111_ini_mode_end[] = { { AR5K_TXCFG, /* a/XR aTurbo b g (DYN) gTurbo */ { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } }, { AR5K_USEC_5211, { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } }, { AR5K_PHY_RF_CTL3, { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } }, { AR5K_PHY_RF_CTL4, { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, { AR5K_PHY_PA_CTL, { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, { AR5K_PHY_GAIN, { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } }, { AR5K_PHY_DESIRED_SIZE, { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, { AR5K_PHY_SIG, { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } }, { AR5K_PHY_AGCCOARSE, { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } }, { AR5K_PHY_WEAK_OFDM_LOW_THR, { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } }, { AR5K_PHY_RX_DELAY, { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } }, { AR5K_PHY_FRAME_CTL_5211, { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } }, { AR5K_PHY_GAIN_2GHZ, { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } }, { AR5K_PHY_CCK_RX_CTL_4, { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } }, }; static const struct ath5k_ini rf5111_ini_common_end[] = { { AR5K_DCU_FP, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_AGC, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_ADC_CTL, 0x00022ffe, AR5K_INI_WRITE }, { 0x983c, 0x00020100, AR5K_INI_WRITE }, { AR5K_PHY_GAIN_OFFSET, 0x1284613c, AR5K_INI_WRITE }, { AR5K_PHY_PAPD_PROBE, 0x00004883, AR5K_INI_WRITE }, { 0x9940, 0x00000004, AR5K_INI_WRITE }, { 0x9958, 0x000000ff, AR5K_INI_WRITE }, { 0x9974, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_SPENDING, 0x00000018, AR5K_INI_WRITE }, { AR5K_PHY_CCKTXCTL, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_CCK_CROSSCORR, 0xd03e6788, AR5K_INI_WRITE }, { AR5K_PHY_DAG_CCK_CTL, 0x000001b5, AR5K_INI_WRITE }, { 0xa23c, 0x13c889af, AR5K_INI_WRITE }, }; /* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */ static const struct ath5k_ini_mode rf5112_ini_mode_end[] = { { AR5K_TXCFG, /* a/XR aTurbo b g (DYN) gTurbo */ { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } }, { AR5K_USEC_5211, { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, { AR5K_PHY_RF_CTL3, { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } }, { AR5K_PHY_RF_CTL4, { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, { AR5K_PHY_PA_CTL, { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, { AR5K_PHY_GAIN, { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } }, { AR5K_PHY_DESIRED_SIZE, { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, { AR5K_PHY_SIG, { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } }, { AR5K_PHY_AGCCOARSE, { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } }, { AR5K_PHY_WEAK_OFDM_LOW_THR, { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, { AR5K_PHY_RX_DELAY, { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, { AR5K_PHY_FRAME_CTL_5211, { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } }, { AR5K_PHY_CCKTXCTL, { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } }, { AR5K_PHY_CCK_CROSSCORR, { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, { AR5K_PHY_GAIN_2GHZ, { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } }, { AR5K_PHY_CCK_RX_CTL_4, { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } }, }; static const struct ath5k_ini rf5112_ini_common_end[] = { { AR5K_DCU_FP, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_AGC, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_ADC_CTL, 0x00022ffe, AR5K_INI_WRITE }, { 0x983c, 0x00020100, AR5K_INI_WRITE }, { AR5K_PHY_GAIN_OFFSET, 0x1284613c, AR5K_INI_WRITE }, { AR5K_PHY_PAPD_PROBE, 0x00004882, AR5K_INI_WRITE }, { 0x9940, 0x00000004, AR5K_INI_WRITE }, { 0x9958, 0x000000ff, AR5K_INI_WRITE }, { 0x9974, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_DAG_CCK_CTL, 0x000001b5, AR5K_INI_WRITE }, { 0xa23c, 0x13c889af, AR5K_INI_WRITE }, }; /* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */ static const struct ath5k_ini_mode rf5413_ini_mode_end[] = { { AR5K_TXCFG, /* a/XR aTurbo b g (DYN) gTurbo */ { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } }, { AR5K_USEC_5211, { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, { AR5K_PHY_RF_CTL3, { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } }, { AR5K_PHY_RF_CTL4, { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, { AR5K_PHY_PA_CTL, { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, { AR5K_PHY_GAIN, { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } }, { AR5K_PHY_DESIRED_SIZE, { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } }, { AR5K_PHY_SIG, { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } }, { AR5K_PHY_AGCCOARSE, { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } }, { AR5K_PHY_WEAK_OFDM_LOW_THR, { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, { AR5K_PHY_RX_DELAY, { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, { AR5K_PHY_FRAME_CTL_5211, { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, { AR5K_PHY_CCKTXCTL, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { AR5K_PHY_CCK_CROSSCORR, { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, { AR5K_PHY_GAIN_2GHZ, { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } }, { AR5K_PHY_CCK_RX_CTL_4, { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } }, { 0xa300, { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } }, { 0xa304, { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } }, { 0xa308, { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } }, { 0xa30c, { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } }, { 0xa310, { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } }, { 0xa314, { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } }, { 0xa318, { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } }, { 0xa31c, { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } }, { 0xa320, { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } }, { 0xa324, { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } }, { 0xa328, { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } }, { 0xa32c, { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } }, { 0xa330, { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } }, { 0xa334, { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } }, }; static const struct ath5k_ini rf5413_ini_common_end[] = { { AR5K_DCU_FP, 0x000003e0, AR5K_INI_WRITE }, { AR5K_5414_CBCFG, 0x00000010, AR5K_INI_WRITE }, { AR5K_SEQ_MASK, 0x0000000f, AR5K_INI_WRITE }, { 0x809c, 0x00000000, AR5K_INI_WRITE }, { 0x80a0, 0x00000000, AR5K_INI_WRITE }, { AR5K_MIC_QOS_CTL, 0x00000000, AR5K_INI_WRITE }, { AR5K_MIC_QOS_SEL, 0x00000000, AR5K_INI_WRITE }, { AR5K_MISC_MODE, 0x00000000, AR5K_INI_WRITE }, { AR5K_OFDM_FIL_CNT, 0x00000000, AR5K_INI_WRITE }, { AR5K_CCK_FIL_CNT, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT1, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT1_MASK, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT2, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT2_MASK, 0x00000000, AR5K_INI_WRITE }, { AR5K_TSF_THRES, 0x00000000, AR5K_INI_WRITE }, { 0x8140, 0x800003f9, AR5K_INI_WRITE }, { 0x8144, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_AGC, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_ADC_CTL, 0x0000a000, AR5K_INI_WRITE }, { 0x983c, 0x00200400, AR5K_INI_WRITE }, { AR5K_PHY_GAIN_OFFSET, 0x1284233c, AR5K_INI_WRITE }, { AR5K_PHY_SCR, 0x0000001f, AR5K_INI_WRITE }, { AR5K_PHY_SLMT, 0x00000080, AR5K_INI_WRITE }, { AR5K_PHY_SCAL, 0x0000000e, AR5K_INI_WRITE }, { 0x9958, 0x00081fff, AR5K_INI_WRITE }, { AR5K_PHY_TIMING_7, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_TIMING_8, 0x02800000, AR5K_INI_WRITE }, { AR5K_PHY_TIMING_11, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000, AR5K_INI_WRITE }, { 0x99e4, 0xaaaaaaaa, AR5K_INI_WRITE }, { 0x99e8, 0x3c466478, AR5K_INI_WRITE }, { 0x99ec, 0x000000aa, AR5K_INI_WRITE }, { AR5K_PHY_SCLOCK, 0x0000000c, AR5K_INI_WRITE }, { AR5K_PHY_SDELAY, 0x000000ff, AR5K_INI_WRITE }, { AR5K_PHY_SPENDING, 0x00000014, AR5K_INI_WRITE }, { AR5K_PHY_DAG_CCK_CTL, 0x000009b5, AR5K_INI_WRITE }, { 0xa23c, 0x93c889af, AR5K_INI_WRITE }, { AR5K_PHY_FAST_ADC, 0x00000001, AR5K_INI_WRITE }, { 0xa250, 0x0000a000, AR5K_INI_WRITE }, { AR5K_PHY_BLUETOOTH, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_TPC_RG1, 0x0cc75380, AR5K_INI_WRITE }, { 0xa25c, 0x0f0f0f01, AR5K_INI_WRITE }, { 0xa260, 0x5f690f01, AR5K_INI_WRITE }, { 0xa264, 0x00418a11, AR5K_INI_WRITE }, { 0xa268, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_TPC_RG5, 0x0c30c16a, AR5K_INI_WRITE }, { 0xa270, 0x00820820, AR5K_INI_WRITE }, { 0xa274, 0x081b7caa, AR5K_INI_WRITE }, { 0xa278, 0x1ce739ce, AR5K_INI_WRITE }, { 0xa27c, 0x051701ce, AR5K_INI_WRITE }, { 0xa338, 0x00000000, AR5K_INI_WRITE }, { 0xa33c, 0x00000000, AR5K_INI_WRITE }, { 0xa340, 0x00000000, AR5K_INI_WRITE }, { 0xa344, 0x00000000, AR5K_INI_WRITE }, { 0xa348, 0x3fffffff, AR5K_INI_WRITE }, { 0xa34c, 0x3fffffff, AR5K_INI_WRITE }, { 0xa350, 0x3fffffff, AR5K_INI_WRITE }, { 0xa354, 0x0003ffff, AR5K_INI_WRITE }, { 0xa358, 0x79a8aa1f, AR5K_INI_WRITE }, { 0xa35c, 0x066c420f, AR5K_INI_WRITE }, { 0xa360, 0x0f282207, AR5K_INI_WRITE }, { 0xa364, 0x17601685, AR5K_INI_WRITE }, { 0xa368, 0x1f801104, AR5K_INI_WRITE }, { 0xa36c, 0x37a00c03, AR5K_INI_WRITE }, { 0xa370, 0x3fc40883, AR5K_INI_WRITE }, { 0xa374, 0x57c00803, AR5K_INI_WRITE }, { 0xa378, 0x5fd80682, AR5K_INI_WRITE }, { 0xa37c, 0x7fe00482, AR5K_INI_WRITE }, { 0xa380, 0x7f3c7bba, AR5K_INI_WRITE }, { 0xa384, 0xf3307ff0, AR5K_INI_WRITE }, }; /* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */ /* XXX: a mode ? */ static const struct ath5k_ini_mode rf2413_ini_mode_end[] = { { AR5K_TXCFG, /* a/XR aTurbo b g (DYN) gTurbo */ { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } }, { AR5K_USEC_5211, { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, { AR5K_PHY_RF_CTL3, { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } }, { AR5K_PHY_RF_CTL4, { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } }, { AR5K_PHY_PA_CTL, { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } }, { AR5K_PHY_GAIN, { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } }, { AR5K_PHY_DESIRED_SIZE, { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } }, { AR5K_PHY_SIG, { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } }, { AR5K_PHY_AGCCOARSE, { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } }, { AR5K_PHY_WEAK_OFDM_LOW_THR, { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, { AR5K_PHY_RX_DELAY, { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, { AR5K_PHY_FRAME_CTL_5211, { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, { AR5K_PHY_CCKTXCTL, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { AR5K_PHY_CCK_CROSSCORR, { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, { AR5K_PHY_GAIN_2GHZ, { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } }, { AR5K_PHY_CCK_RX_CTL_4, { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } }, }; static const struct ath5k_ini rf2413_ini_common_end[] = { { AR5K_DCU_FP, 0x000003e0, AR5K_INI_WRITE }, { AR5K_SEQ_MASK, 0x0000000f, AR5K_INI_WRITE }, { AR5K_MIC_QOS_CTL, 0x00000000, AR5K_INI_WRITE }, { AR5K_MIC_QOS_SEL, 0x00000000, AR5K_INI_WRITE }, { AR5K_MISC_MODE, 0x00000000, AR5K_INI_WRITE }, { AR5K_OFDM_FIL_CNT, 0x00000000, AR5K_INI_WRITE }, { AR5K_CCK_FIL_CNT, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT1, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT1_MASK, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT2, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT2_MASK, 0x00000000, AR5K_INI_WRITE }, { AR5K_TSF_THRES, 0x00000000, AR5K_INI_WRITE }, { 0x8140, 0x800000a8, AR5K_INI_WRITE }, { 0x8144, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_AGC, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_ADC_CTL, 0x0000a000, AR5K_INI_WRITE }, { 0x983c, 0x00200400, AR5K_INI_WRITE }, { AR5K_PHY_GAIN_OFFSET, 0x1284233c, AR5K_INI_WRITE }, { AR5K_PHY_SCR, 0x0000001f, AR5K_INI_WRITE }, { AR5K_PHY_SLMT, 0x00000080, AR5K_INI_WRITE }, { AR5K_PHY_SCAL, 0x0000000e, AR5K_INI_WRITE }, { 0x9958, 0x000000ff, AR5K_INI_WRITE }, { AR5K_PHY_TIMING_7, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_TIMING_8, 0x02800000, AR5K_INI_WRITE }, { AR5K_PHY_TIMING_11, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000, AR5K_INI_WRITE }, { 0x99e4, 0xaaaaaaaa, AR5K_INI_WRITE }, { 0x99e8, 0x3c466478, AR5K_INI_WRITE }, { 0x99ec, 0x000000aa, AR5K_INI_WRITE }, { AR5K_PHY_SCLOCK, 0x0000000c, AR5K_INI_WRITE }, { AR5K_PHY_SDELAY, 0x000000ff, AR5K_INI_WRITE }, { AR5K_PHY_SPENDING, 0x00000014, AR5K_INI_WRITE }, { AR5K_PHY_DAG_CCK_CTL, 0x000009b5, AR5K_INI_WRITE }, { 0xa23c, 0x93c889af, AR5K_INI_WRITE }, { AR5K_PHY_FAST_ADC, 0x00000001, AR5K_INI_WRITE }, { 0xa250, 0x0000a000, AR5K_INI_WRITE }, { AR5K_PHY_BLUETOOTH, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_TPC_RG1, 0x0cc75380, AR5K_INI_WRITE }, { 0xa25c, 0x0f0f0f01, AR5K_INI_WRITE }, { 0xa260, 0x5f690f01, AR5K_INI_WRITE }, { 0xa264, 0x00418a11, AR5K_INI_WRITE }, { 0xa268, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_TPC_RG5, 0x0c30c16a, AR5K_INI_WRITE }, { 0xa270, 0x00820820, AR5K_INI_WRITE }, { 0xa274, 0x001b7caa, AR5K_INI_WRITE }, { 0xa278, 0x1ce739ce, AR5K_INI_WRITE }, { 0xa27c, 0x051701ce, AR5K_INI_WRITE }, { 0xa300, 0x18010000, AR5K_INI_WRITE }, { 0xa304, 0x30032602, AR5K_INI_WRITE }, { 0xa308, 0x48073e06, AR5K_INI_WRITE }, { 0xa30c, 0x560b4c0a, AR5K_INI_WRITE }, { 0xa310, 0x641a600f, AR5K_INI_WRITE }, { 0xa314, 0x784f6e1b, AR5K_INI_WRITE }, { 0xa318, 0x868f7c5a, AR5K_INI_WRITE }, { 0xa31c, 0x8ecf865b, AR5K_INI_WRITE }, { 0xa320, 0x9d4f970f, AR5K_INI_WRITE }, { 0xa324, 0xa5cfa18f, AR5K_INI_WRITE }, { 0xa328, 0xb55faf1f, AR5K_INI_WRITE }, { 0xa32c, 0xbddfb99f, AR5K_INI_WRITE }, { 0xa330, 0xcd7fc73f, AR5K_INI_WRITE }, { 0xa334, 0xd5ffd1bf, AR5K_INI_WRITE }, { 0xa338, 0x00000000, AR5K_INI_WRITE }, { 0xa33c, 0x00000000, AR5K_INI_WRITE }, { 0xa340, 0x00000000, AR5K_INI_WRITE }, { 0xa344, 0x00000000, AR5K_INI_WRITE }, { 0xa348, 0x3fffffff, AR5K_INI_WRITE }, { 0xa34c, 0x3fffffff, AR5K_INI_WRITE }, { 0xa350, 0x3fffffff, AR5K_INI_WRITE }, { 0xa354, 0x0003ffff, AR5K_INI_WRITE }, { 0xa358, 0x79a8aa1f, AR5K_INI_WRITE }, { 0xa35c, 0x066c420f, AR5K_INI_WRITE }, { 0xa360, 0x0f282207, AR5K_INI_WRITE }, { 0xa364, 0x17601685, AR5K_INI_WRITE }, { 0xa368, 0x1f801104, AR5K_INI_WRITE }, { 0xa36c, 0x37a00c03, AR5K_INI_WRITE }, { 0xa370, 0x3fc40883, AR5K_INI_WRITE }, { 0xa374, 0x57c00803, AR5K_INI_WRITE }, { 0xa378, 0x5fd80682, AR5K_INI_WRITE }, { 0xa37c, 0x7fe00482, AR5K_INI_WRITE }, { 0xa380, 0x7f3c7bba, AR5K_INI_WRITE }, { 0xa384, 0xf3307ff0, AR5K_INI_WRITE }, }; /* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */ /* XXX: a mode ? */ static const struct ath5k_ini_mode rf2425_ini_mode_end[] = { { AR5K_TXCFG, /* a/XR aTurbo b g (DYN) gTurbo */ { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } }, { AR5K_USEC_5211, { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, { AR5K_PHY_TURBO, { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } }, { AR5K_PHY_RF_CTL3, { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } }, { AR5K_PHY_RF_CTL4, { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, { AR5K_PHY_PA_CTL, { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } }, { AR5K_PHY_SETTLING, { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } }, { AR5K_PHY_GAIN, { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } }, { AR5K_PHY_DESIRED_SIZE, { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } }, { AR5K_PHY_SIG, { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } }, { AR5K_PHY_AGCCOARSE, { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } }, { AR5K_PHY_WEAK_OFDM_LOW_THR, { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, { AR5K_PHY_RX_DELAY, { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, { AR5K_PHY_FRAME_CTL_5211, { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, { AR5K_PHY_CCKTXCTL, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { AR5K_PHY_CCK_CROSSCORR, { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, { AR5K_PHY_GAIN_2GHZ, { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } }, { AR5K_PHY_CCK_RX_CTL_4, { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } }, { 0xa324, { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, { 0xa328, { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, { 0xa32c, { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, { 0xa330, { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, { 0xa334, { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, }; static const struct ath5k_ini rf2425_ini_common_end[] = { { AR5K_DCU_FP, 0x000003e0, AR5K_INI_WRITE }, { AR5K_SEQ_MASK, 0x0000000f, AR5K_INI_WRITE }, { 0x809c, 0x00000000, AR5K_INI_WRITE }, { 0x80a0, 0x00000000, AR5K_INI_WRITE }, { AR5K_MIC_QOS_CTL, 0x00000000, AR5K_INI_WRITE }, { AR5K_MIC_QOS_SEL, 0x00000000, AR5K_INI_WRITE }, { AR5K_MISC_MODE, 0x00000000, AR5K_INI_WRITE }, { AR5K_OFDM_FIL_CNT, 0x00000000, AR5K_INI_WRITE }, { AR5K_CCK_FIL_CNT, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT1, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT1_MASK, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT2, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHYERR_CNT2_MASK, 0x00000000, AR5K_INI_WRITE }, { AR5K_TSF_THRES, 0x00000000, AR5K_INI_WRITE }, { 0x8140, 0x800003f9, AR5K_INI_WRITE }, { 0x8144, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_AGC, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_ADC_CTL, 0x0000a000, AR5K_INI_WRITE }, { 0x983c, 0x00200400, AR5K_INI_WRITE }, { AR5K_PHY_GAIN_OFFSET, 0x1284233c, AR5K_INI_WRITE }, { AR5K_PHY_SCR, 0x0000001f, AR5K_INI_WRITE }, { AR5K_PHY_SLMT, 0x00000080, AR5K_INI_WRITE }, { AR5K_PHY_SCAL, 0x0000000e, AR5K_INI_WRITE }, { 0x9958, 0x00081fff, AR5K_INI_WRITE }, { AR5K_PHY_TIMING_7, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_TIMING_8, 0x02800000, AR5K_INI_WRITE }, { AR5K_PHY_TIMING_11, 0x00000000, AR5K_INI_WRITE }, { 0x99dc, 0xfebadbe8, AR5K_INI_WRITE }, { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000, AR5K_INI_WRITE }, { 0x99e4, 0xaaaaaaaa, AR5K_INI_WRITE }, { 0x99e8, 0x3c466478, AR5K_INI_WRITE }, { 0x99ec, 0x000000aa, AR5K_INI_WRITE }, { AR5K_PHY_SCLOCK, 0x0000000c, AR5K_INI_WRITE }, { AR5K_PHY_SDELAY, 0x000000ff, AR5K_INI_WRITE }, { AR5K_PHY_SPENDING, 0x00000014, AR5K_INI_WRITE }, { AR5K_PHY_DAG_CCK_CTL, 0x000009b5, AR5K_INI_WRITE }, { AR5K_PHY_TXPOWER_RATE3, 0x20202020, AR5K_INI_WRITE }, { AR5K_PHY_TXPOWER_RATE4, 0x20202020, AR5K_INI_WRITE }, { 0xa23c, 0x93c889af, AR5K_INI_WRITE }, { AR5K_PHY_FAST_ADC, 0x00000001, AR5K_INI_WRITE }, { 0xa250, 0x0000a000, AR5K_INI_WRITE }, { AR5K_PHY_BLUETOOTH, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_TPC_RG1, 0x0cc75380, AR5K_INI_WRITE }, { 0xa25c, 0x0f0f0f01, AR5K_INI_WRITE }, { 0xa260, 0x5f690f01, AR5K_INI_WRITE }, { 0xa264, 0x00418a11, AR5K_INI_WRITE }, { 0xa268, 0x00000000, AR5K_INI_WRITE }, { AR5K_PHY_TPC_RG5, 0x0c30c166, AR5K_INI_WRITE }, { 0xa270, 0x00820820, AR5K_INI_WRITE }, { 0xa274, 0x081a3caa, AR5K_INI_WRITE }, { 0xa278, 0x1ce739ce, AR5K_INI_WRITE }, { 0xa27c, 0x051701ce, AR5K_INI_WRITE }, { 0xa300, 0x16010000, AR5K_INI_WRITE }, { 0xa304, 0x2c032402, AR5K_INI_WRITE }, { 0xa308, 0x48433e42, AR5K_INI_WRITE }, { 0xa30c, 0x5a0f500b, AR5K_INI_WRITE }, { 0xa310, 0x6c4b624a, AR5K_INI_WRITE }, { 0xa314, 0x7e8b748a, AR5K_INI_WRITE }, { 0xa318, 0x96cf8ccb, AR5K_INI_WRITE }, { 0xa31c, 0xa34f9d0f, AR5K_INI_WRITE }, { 0xa320, 0xa7cfa58f, AR5K_INI_WRITE }, { 0xa348, 0x3fffffff, AR5K_INI_WRITE }, { 0xa34c, 0x3fffffff, AR5K_INI_WRITE }, { 0xa350, 0x3fffffff, AR5K_INI_WRITE }, { 0xa354, 0x0003ffff, AR5K_INI_WRITE }, { 0xa358, 0x79a8aa1f, AR5K_INI_WRITE }, { 0xa35c, 0x066c420f, AR5K_INI_WRITE }, { 0xa360, 0x0f282207, AR5K_INI_WRITE }, { 0xa364, 0x17601685, AR5K_INI_WRITE }, { 0xa368, 0x1f801104, AR5K_INI_WRITE }, { 0xa36c, 0x37a00c03, AR5K_INI_WRITE }, { 0xa370, 0x3fc40883, AR5K_INI_WRITE }, { 0xa374, 0x57c00803, AR5K_INI_WRITE }, { 0xa378, 0x5fd80682, AR5K_INI_WRITE }, { 0xa37c, 0x7fe00482, AR5K_INI_WRITE }, { 0xa380, 0x7f3c7bba, AR5K_INI_WRITE }, { 0xa384, 0xf3307ff0, AR5K_INI_WRITE }, }; /* * Initial BaseBand Gain settings for RF5111/5112 (AR5210 comes with * RF5110 only so initial BB Gain settings are included in AR5K_AR5210_INI) */ /* RF5111 Initial BaseBand Gain settings */ static const struct ath5k_ini rf5111_ini_bbgain[] = { { AR5K_BB_GAIN(0), 0x00000000, AR5K_INI_WRITE }, { AR5K_BB_GAIN(1), 0x00000020, AR5K_INI_WRITE }, { AR5K_BB_GAIN(2), 0x00000010, AR5K_INI_WRITE }, { AR5K_BB_GAIN(3), 0x00000030, AR5K_INI_WRITE }, { AR5K_BB_GAIN(4), 0x00000008, AR5K_INI_WRITE }, { AR5K_BB_GAIN(5), 0x00000028, AR5K_INI_WRITE }, { AR5K_BB_GAIN(6), 0x00000004, AR5K_INI_WRITE }, { AR5K_BB_GAIN(7), 0x00000024, AR5K_INI_WRITE }, { AR5K_BB_GAIN(8), 0x00000014, AR5K_INI_WRITE }, { AR5K_BB_GAIN(9), 0x00000034, AR5K_INI_WRITE }, { AR5K_BB_GAIN(10), 0x0000000c, AR5K_INI_WRITE }, { AR5K_BB_GAIN(11), 0x0000002c, AR5K_INI_WRITE }, { AR5K_BB_GAIN(12), 0x00000002, AR5K_INI_WRITE }, { AR5K_BB_GAIN(13), 0x00000022, AR5K_INI_WRITE }, { AR5K_BB_GAIN(14), 0x00000012, AR5K_INI_WRITE }, { AR5K_BB_GAIN(15), 0x00000032, AR5K_INI_WRITE }, { AR5K_BB_GAIN(16), 0x0000000a, AR5K_INI_WRITE }, { AR5K_BB_GAIN(17), 0x0000002a, AR5K_INI_WRITE }, { AR5K_BB_GAIN(18), 0x00000006, AR5K_INI_WRITE }, { AR5K_BB_GAIN(19), 0x00000026, AR5K_INI_WRITE }, { AR5K_BB_GAIN(20), 0x00000016, AR5K_INI_WRITE }, { AR5K_BB_GAIN(21), 0x00000036, AR5K_INI_WRITE }, { AR5K_BB_GAIN(22), 0x0000000e, AR5K_INI_WRITE }, { AR5K_BB_GAIN(23), 0x0000002e, AR5K_INI_WRITE }, { AR5K_BB_GAIN(24), 0x00000001, AR5K_INI_WRITE }, { AR5K_BB_GAIN(25), 0x00000021, AR5K_INI_WRITE }, { AR5K_BB_GAIN(26), 0x00000011, AR5K_INI_WRITE }, { AR5K_BB_GAIN(27), 0x00000031, AR5K_INI_WRITE }, { AR5K_BB_GAIN(28), 0x00000009, AR5K_INI_WRITE }, { AR5K_BB_GAIN(29), 0x00000029, AR5K_INI_WRITE }, { AR5K_BB_GAIN(30), 0x00000005, AR5K_INI_WRITE }, { AR5K_BB_GAIN(31), 0x00000025, AR5K_INI_WRITE }, { AR5K_BB_GAIN(32), 0x00000015, AR5K_INI_WRITE }, { AR5K_BB_GAIN(33), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(34), 0x0000000d, AR5K_INI_WRITE }, { AR5K_BB_GAIN(35), 0x0000002d, AR5K_INI_WRITE }, { AR5K_BB_GAIN(36), 0x00000003, AR5K_INI_WRITE }, { AR5K_BB_GAIN(37), 0x00000023, AR5K_INI_WRITE }, { AR5K_BB_GAIN(38), 0x00000013, AR5K_INI_WRITE }, { AR5K_BB_GAIN(39), 0x00000033, AR5K_INI_WRITE }, { AR5K_BB_GAIN(40), 0x0000000b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(41), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(42), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(43), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(44), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(45), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(46), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(47), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(48), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(49), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(50), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(51), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(52), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(53), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(54), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(55), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(56), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(57), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(58), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(59), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(60), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(61), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(62), 0x00000002, AR5K_INI_WRITE }, { AR5K_BB_GAIN(63), 0x00000016, AR5K_INI_WRITE }, }; /* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414+) */ static const struct ath5k_ini rf5112_ini_bbgain[] = { { AR5K_BB_GAIN(0), 0x00000000, AR5K_INI_WRITE }, { AR5K_BB_GAIN(1), 0x00000001, AR5K_INI_WRITE }, { AR5K_BB_GAIN(2), 0x00000002, AR5K_INI_WRITE }, { AR5K_BB_GAIN(3), 0x00000003, AR5K_INI_WRITE }, { AR5K_BB_GAIN(4), 0x00000004, AR5K_INI_WRITE }, { AR5K_BB_GAIN(5), 0x00000005, AR5K_INI_WRITE }, { AR5K_BB_GAIN(6), 0x00000008, AR5K_INI_WRITE }, { AR5K_BB_GAIN(7), 0x00000009, AR5K_INI_WRITE }, { AR5K_BB_GAIN(8), 0x0000000a, AR5K_INI_WRITE }, { AR5K_BB_GAIN(9), 0x0000000b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(10), 0x0000000c, AR5K_INI_WRITE }, { AR5K_BB_GAIN(11), 0x0000000d, AR5K_INI_WRITE }, { AR5K_BB_GAIN(12), 0x00000010, AR5K_INI_WRITE }, { AR5K_BB_GAIN(13), 0x00000011, AR5K_INI_WRITE }, { AR5K_BB_GAIN(14), 0x00000012, AR5K_INI_WRITE }, { AR5K_BB_GAIN(15), 0x00000013, AR5K_INI_WRITE }, { AR5K_BB_GAIN(16), 0x00000014, AR5K_INI_WRITE }, { AR5K_BB_GAIN(17), 0x00000015, AR5K_INI_WRITE }, { AR5K_BB_GAIN(18), 0x00000018, AR5K_INI_WRITE }, { AR5K_BB_GAIN(19), 0x00000019, AR5K_INI_WRITE }, { AR5K_BB_GAIN(20), 0x0000001a, AR5K_INI_WRITE }, { AR5K_BB_GAIN(21), 0x0000001b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(22), 0x0000001c, AR5K_INI_WRITE }, { AR5K_BB_GAIN(23), 0x0000001d, AR5K_INI_WRITE }, { AR5K_BB_GAIN(24), 0x00000020, AR5K_INI_WRITE }, { AR5K_BB_GAIN(25), 0x00000021, AR5K_INI_WRITE }, { AR5K_BB_GAIN(26), 0x00000022, AR5K_INI_WRITE }, { AR5K_BB_GAIN(27), 0x00000023, AR5K_INI_WRITE }, { AR5K_BB_GAIN(28), 0x00000024, AR5K_INI_WRITE }, { AR5K_BB_GAIN(29), 0x00000025, AR5K_INI_WRITE }, { AR5K_BB_GAIN(30), 0x00000028, AR5K_INI_WRITE }, { AR5K_BB_GAIN(31), 0x00000029, AR5K_INI_WRITE }, { AR5K_BB_GAIN(32), 0x0000002a, AR5K_INI_WRITE }, { AR5K_BB_GAIN(33), 0x0000002b, AR5K_INI_WRITE }, { AR5K_BB_GAIN(34), 0x0000002c, AR5K_INI_WRITE }, { AR5K_BB_GAIN(35), 0x0000002d, AR5K_INI_WRITE }, { AR5K_BB_GAIN(36), 0x00000030, AR5K_INI_WRITE }, { AR5K_BB_GAIN(37), 0x00000031, AR5K_INI_WRITE }, { AR5K_BB_GAIN(38), 0x00000032, AR5K_INI_WRITE }, { AR5K_BB_GAIN(39), 0x00000033, AR5K_INI_WRITE }, { AR5K_BB_GAIN(40), 0x00000034, AR5K_INI_WRITE }, { AR5K_BB_GAIN(41), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(42), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(43), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(44), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(45), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(46), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(47), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(48), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(49), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(50), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(51), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(52), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(53), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(54), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(55), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(56), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(57), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(58), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(59), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(60), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(61), 0x00000035, AR5K_INI_WRITE }, { AR5K_BB_GAIN(62), 0x00000010, AR5K_INI_WRITE }, { AR5K_BB_GAIN(63), 0x0000001a, AR5K_INI_WRITE }, }; /* * Write initial register dump */ static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size, const struct ath5k_ini *ini_regs, int change_channel) { unsigned int i; /* Write initial registers */ for (i = 0; i < size; i++) { /* On channel change there is * no need to mess with PCU */ if (change_channel && ini_regs[i].ini_register >= AR5K_PCU_MIN && ini_regs[i].ini_register <= AR5K_PCU_MAX) continue; switch (ini_regs[i].ini_mode) { case AR5K_INI_READ: /* Cleared on read */ ath5k_hw_reg_read(ah, ini_regs[i].ini_register); break; case AR5K_INI_WRITE: default: AR5K_REG_WAIT(i); ath5k_hw_reg_write(ah, ini_regs[i].ini_value, ini_regs[i].ini_register); } } } static void ath5k_hw_ini_mode_registers(struct ath5k_hw *ah, unsigned int size, const struct ath5k_ini_mode *ini_mode, u8 mode) { unsigned int i; for (i = 0; i < size; i++) { AR5K_REG_WAIT(i); ath5k_hw_reg_write(ah, ini_mode[i].mode_value[mode], (u32)ini_mode[i].mode_register); } } int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, int change_channel) { /* * Write initial register settings */ /* For AR5212 and combatible */ if (ah->ah_version == AR5K_AR5212) { /* First set of mode-specific settings */ ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(ar5212_ini_mode_start), ar5212_ini_mode_start, mode); /* * Write initial settings common for all modes */ ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start), ar5212_ini_common_start, change_channel); /* Second set of mode-specific settings */ switch (ah->ah_radio) { case AR5K_RF5111: ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(rf5111_ini_mode_end), rf5111_ini_mode_end, mode); ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_common_end), rf5111_ini_common_end, change_channel); /* Baseband gain table */ ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain), rf5111_ini_bbgain, change_channel); break; case AR5K_RF5112: ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(rf5112_ini_mode_end), rf5112_ini_mode_end, mode); ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_common_end), rf5112_ini_common_end, change_channel); ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_bbgain), rf5112_ini_bbgain, change_channel); break; case AR5K_RF5413: ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(rf5413_ini_mode_end), rf5413_ini_mode_end, mode); ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5413_ini_common_end), rf5413_ini_common_end, change_channel); ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_bbgain), rf5112_ini_bbgain, change_channel); break; case AR5K_RF2316: case AR5K_RF2413: ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(rf2413_ini_mode_end), rf2413_ini_mode_end, mode); ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf2413_ini_common_end), rf2413_ini_common_end, change_channel); /* Override settings from rf2413_ini_common_end */ if (ah->ah_radio == AR5K_RF2316) { ath5k_hw_reg_write(ah, 0x00004000, AR5K_PHY_AGC); ath5k_hw_reg_write(ah, 0x081b7caa, 0xa274); } ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_bbgain), rf5112_ini_bbgain, change_channel); break; case AR5K_RF2317: case AR5K_RF2425: ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(rf2425_ini_mode_end), rf2425_ini_mode_end, mode); ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf2425_ini_common_end), rf2425_ini_common_end, change_channel); ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5112_ini_bbgain), rf5112_ini_bbgain, change_channel); break; default: return -EINVAL; } /* For AR5211 */ } else if (ah->ah_version == AR5K_AR5211) { /* AR5K_MODE_11B */ if (mode > 2) { DBG("ath5k: unsupported channel mode %d\n", mode); return -EINVAL; } /* Mode-specific settings */ ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(ar5211_ini_mode), ar5211_ini_mode, mode); /* * Write initial settings common for all modes */ ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini), ar5211_ini, change_channel); /* AR5211 only comes with 5111 */ /* Baseband gain table */ ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain), rf5111_ini_bbgain, change_channel); /* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */ } else if (ah->ah_version == AR5K_AR5210) { ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini), ar5210_ini, change_channel); } return 0; } debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/rfbuffer.h0000664000000000000000000013101112524662415022172 0ustar /* * RF Buffer handling functions * * Copyright (c) 2009 Nick Kossifidis * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ /* * There are some special registers on the RF chip * that control various operation settings related mostly to * the analog parts (channel, gain adjustment etc). * * We don't write on those registers directly but * we send a data packet on the chip, using a special register, * that holds all the settings we need. After we 've sent the * data packet, we write on another special register to notify hw * to apply the settings. This is done so that control registers * can be dynamicaly programmed during operation and the settings * are applied faster on the hw. * * We call each data packet an "RF Bank" and all the data we write * (all RF Banks) "RF Buffer". This file holds initial RF Buffer * data for the different RF chips, and various info to match RF * Buffer offsets with specific RF registers so that we can access * them. We tweak these settings on rfregs_init function. * * Also check out reg.h and U.S. Patent 6677779 B1 (about buffer * registers and control registers): * * http://www.google.com/patents?id=qNURAAAAEBAJ */ /* * Struct to hold default mode specific RF * register values (RF Banks) */ struct ath5k_ini_rfbuffer { u8 rfb_bank; /* RF Bank number */ u16 rfb_ctrl_register; /* RF Buffer control register */ u32 rfb_mode_data[5]; /* RF Buffer data for each mode */ }; /* * Struct to hold RF Buffer field * infos used to access certain RF * analog registers */ struct ath5k_rfb_field { u8 len; /* Field length */ u16 pos; /* Offset on the raw packet */ u8 col; /* Column -used for shifting */ }; /* * RF analog register definition */ struct ath5k_rf_reg { u8 bank; /* RF Buffer Bank number */ u8 index; /* Register's index on rf_regs_idx */ struct ath5k_rfb_field field; /* RF Buffer field for this register */ }; /* Map RF registers to indexes * We do this to handle common bits and make our * life easier by using an index for each register * instead of a full rfb_field */ enum ath5k_rf_regs_idx { /* BANK 6 */ AR5K_RF_OB_2GHZ = 0, AR5K_RF_OB_5GHZ, AR5K_RF_DB_2GHZ, AR5K_RF_DB_5GHZ, AR5K_RF_FIXED_BIAS_A, AR5K_RF_FIXED_BIAS_B, AR5K_RF_PWD_XPD, AR5K_RF_XPD_SEL, AR5K_RF_XPD_GAIN, AR5K_RF_PD_GAIN_LO, AR5K_RF_PD_GAIN_HI, AR5K_RF_HIGH_VC_CP, AR5K_RF_MID_VC_CP, AR5K_RF_LOW_VC_CP, AR5K_RF_PUSH_UP, AR5K_RF_PAD2GND, AR5K_RF_XB2_LVL, AR5K_RF_XB5_LVL, AR5K_RF_PWD_ICLOBUF_2G, AR5K_RF_PWD_84, AR5K_RF_PWD_90, AR5K_RF_PWD_130, AR5K_RF_PWD_131, AR5K_RF_PWD_132, AR5K_RF_PWD_136, AR5K_RF_PWD_137, AR5K_RF_PWD_138, AR5K_RF_PWD_166, AR5K_RF_PWD_167, AR5K_RF_DERBY_CHAN_SEL_MODE, /* BANK 7 */ AR5K_RF_GAIN_I, AR5K_RF_PLO_SEL, AR5K_RF_RFGAIN_SEL, AR5K_RF_RFGAIN_STEP, AR5K_RF_WAIT_S, AR5K_RF_WAIT_I, AR5K_RF_MAX_TIME, AR5K_RF_MIXVGA_OVR, AR5K_RF_MIXGAIN_OVR, AR5K_RF_MIXGAIN_STEP, AR5K_RF_PD_DELAY_A, AR5K_RF_PD_DELAY_B, AR5K_RF_PD_DELAY_XR, AR5K_RF_PD_PERIOD_A, AR5K_RF_PD_PERIOD_B, AR5K_RF_PD_PERIOD_XR, }; /*******************\ * RF5111 (Sombrero) * \*******************/ /* BANK 6 len pos col */ #define AR5K_RF5111_OB_2GHZ { 3, 119, 0 } #define AR5K_RF5111_DB_2GHZ { 3, 122, 0 } #define AR5K_RF5111_OB_5GHZ { 3, 104, 0 } #define AR5K_RF5111_DB_5GHZ { 3, 107, 0 } #define AR5K_RF5111_PWD_XPD { 1, 95, 0 } #define AR5K_RF5111_XPD_GAIN { 4, 96, 0 } /* Access to PWD registers */ #define AR5K_RF5111_PWD(_n) { 1, (135 - _n), 3 } /* BANK 7 len pos col */ #define AR5K_RF5111_GAIN_I { 6, 29, 0 } #define AR5K_RF5111_PLO_SEL { 1, 4, 0 } #define AR5K_RF5111_RFGAIN_SEL { 1, 36, 0 } #define AR5K_RF5111_RFGAIN_STEP { 6, 37, 0 } /* Only on AR5212 BaseBand and up */ #define AR5K_RF5111_WAIT_S { 5, 19, 0 } #define AR5K_RF5111_WAIT_I { 5, 24, 0 } #define AR5K_RF5111_MAX_TIME { 2, 49, 0 } static const struct ath5k_rf_reg rf_regs_5111[] = { {6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ}, {6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ}, {6, AR5K_RF_DB_5GHZ, AR5K_RF5111_DB_5GHZ}, {6, AR5K_RF_PWD_XPD, AR5K_RF5111_PWD_XPD}, {6, AR5K_RF_XPD_GAIN, AR5K_RF5111_XPD_GAIN}, {6, AR5K_RF_PWD_84, AR5K_RF5111_PWD(84)}, {6, AR5K_RF_PWD_90, AR5K_RF5111_PWD(90)}, {7, AR5K_RF_GAIN_I, AR5K_RF5111_GAIN_I}, {7, AR5K_RF_PLO_SEL, AR5K_RF5111_PLO_SEL}, {7, AR5K_RF_RFGAIN_SEL, AR5K_RF5111_RFGAIN_SEL}, {7, AR5K_RF_RFGAIN_STEP, AR5K_RF5111_RFGAIN_STEP}, {7, AR5K_RF_WAIT_S, AR5K_RF5111_WAIT_S}, {7, AR5K_RF_WAIT_I, AR5K_RF5111_WAIT_I}, {7, AR5K_RF_MAX_TIME, AR5K_RF5111_MAX_TIME} }; /* Default mode specific settings */ static const struct ath5k_ini_rfbuffer rfb_5111[] = { { 0, 0x989c, /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 0, 0x989c, { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } }, { 0, 0x989c, { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } }, { 0, 0x98d4, { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } }, { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, { 2, 0x98d4, { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } }, { 3, 0x98d8, { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } }, { 6, 0x989c, { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } }, { 6, 0x989c, { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } }, { 6, 0x989c, { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } }, { 6, 0x989c, { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } }, { 6, 0x989c, { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } }, { 6, 0x98d4, { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } }, { 7, 0x989c, { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } }, { 7, 0x989c, { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } }, { 7, 0x989c, { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } }, { 7, 0x989c, { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } }, { 7, 0x989c, { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } }, { 7, 0x989c, { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } }, { 7, 0x989c, { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } }, { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } }, }; /***********************\ * RF5112/RF2112 (Derby) * \***********************/ /* BANK 7 (Common) len pos col */ #define AR5K_RF5112X_GAIN_I { 6, 14, 0 } #define AR5K_RF5112X_MIXVGA_OVR { 1, 36, 0 } #define AR5K_RF5112X_MIXGAIN_OVR { 2, 37, 0 } #define AR5K_RF5112X_MIXGAIN_STEP { 4, 32, 0 } #define AR5K_RF5112X_PD_DELAY_A { 4, 58, 0 } #define AR5K_RF5112X_PD_DELAY_B { 4, 62, 0 } #define AR5K_RF5112X_PD_DELAY_XR { 4, 66, 0 } #define AR5K_RF5112X_PD_PERIOD_A { 4, 70, 0 } #define AR5K_RF5112X_PD_PERIOD_B { 4, 74, 0 } #define AR5K_RF5112X_PD_PERIOD_XR { 4, 78, 0 } /* RFX112 (Derby 1) */ /* BANK 6 len pos col */ #define AR5K_RF5112_OB_2GHZ { 3, 269, 0 } #define AR5K_RF5112_DB_2GHZ { 3, 272, 0 } #define AR5K_RF5112_OB_5GHZ { 3, 261, 0 } #define AR5K_RF5112_DB_5GHZ { 3, 264, 0 } #define AR5K_RF5112_FIXED_BIAS_A { 1, 260, 0 } #define AR5K_RF5112_FIXED_BIAS_B { 1, 259, 0 } #define AR5K_RF5112_XPD_SEL { 1, 284, 0 } #define AR5K_RF5112_XPD_GAIN { 2, 252, 0 } /* Access to PWD registers */ #define AR5K_RF5112_PWD(_n) { 1, (302 - _n), 3 } static const struct ath5k_rf_reg rf_regs_5112[] = { {6, AR5K_RF_OB_2GHZ, AR5K_RF5112_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF5112_DB_2GHZ}, {6, AR5K_RF_OB_5GHZ, AR5K_RF5112_OB_5GHZ}, {6, AR5K_RF_DB_5GHZ, AR5K_RF5112_DB_5GHZ}, {6, AR5K_RF_FIXED_BIAS_A, AR5K_RF5112_FIXED_BIAS_A}, {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112_FIXED_BIAS_B}, {6, AR5K_RF_XPD_SEL, AR5K_RF5112_XPD_SEL}, {6, AR5K_RF_XPD_GAIN, AR5K_RF5112_XPD_GAIN}, {6, AR5K_RF_PWD_130, AR5K_RF5112_PWD(130)}, {6, AR5K_RF_PWD_131, AR5K_RF5112_PWD(131)}, {6, AR5K_RF_PWD_132, AR5K_RF5112_PWD(132)}, {6, AR5K_RF_PWD_136, AR5K_RF5112_PWD(136)}, {6, AR5K_RF_PWD_137, AR5K_RF5112_PWD(137)}, {6, AR5K_RF_PWD_138, AR5K_RF5112_PWD(138)}, {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I}, {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR}, {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR}, {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP}, {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A}, {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B}, {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR}, {7, AR5K_RF_PD_PERIOD_A, AR5K_RF5112X_PD_PERIOD_A}, {7, AR5K_RF_PD_PERIOD_B, AR5K_RF5112X_PD_PERIOD_B}, {7, AR5K_RF_PD_PERIOD_XR, AR5K_RF5112X_PD_PERIOD_XR}, }; /* Default mode specific settings */ static const struct ath5k_ini_rfbuffer rfb_5112[] = { { 1, 0x98d4, /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, { 2, 0x98d0, { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } }, { 3, 0x98dc, { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } }, { 6, 0x989c, { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } }, { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } }, { 6, 0x989c, { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } }, { 6, 0x989c, { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } }, { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } }, { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } }, { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } }, { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, { 6, 0x989c, { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } }, { 6, 0x989c, { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } }, { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } }, { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } }, { 6, 0x989c, { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } }, { 6, 0x989c, { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } }, { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } }, { 6, 0x989c, { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } }, { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } }, { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } }, { 6, 0x989c, { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } }, { 6, 0x989c, { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } }, { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } }, { 6, 0x989c, { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } }, { 6, 0x989c, { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } }, { 6, 0x989c, { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } }, { 6, 0x989c, { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } }, { 6, 0x989c, { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } }, { 6, 0x989c, { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } }, { 6, 0x989c, { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } }, { 6, 0x989c, { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } }, { 6, 0x989c, { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } }, { 6, 0x989c, { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } }, { 6, 0x98d0, { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } }, { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } }, { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } }, { 7, 0x989c, { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } }, { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } }, { 7, 0x989c, { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } }, { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } }, { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } }, { 7, 0x989c, { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } }, { 7, 0x989c, { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } }, { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } }, { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } }, { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } }, { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } }, }; /* RFX112A (Derby 2) */ /* BANK 6 len pos col */ #define AR5K_RF5112A_OB_2GHZ { 3, 287, 0 } #define AR5K_RF5112A_DB_2GHZ { 3, 290, 0 } #define AR5K_RF5112A_OB_5GHZ { 3, 279, 0 } #define AR5K_RF5112A_DB_5GHZ { 3, 282, 0 } #define AR5K_RF5112A_FIXED_BIAS_A { 1, 278, 0 } #define AR5K_RF5112A_FIXED_BIAS_B { 1, 277, 0 } #define AR5K_RF5112A_XPD_SEL { 1, 302, 0 } #define AR5K_RF5112A_PDGAINLO { 2, 270, 0 } #define AR5K_RF5112A_PDGAINHI { 2, 257, 0 } /* Access to PWD registers */ #define AR5K_RF5112A_PWD(_n) { 1, (306 - _n), 3 } /* Voltage regulators */ #define AR5K_RF5112A_HIGH_VC_CP { 2, 90, 2 } #define AR5K_RF5112A_MID_VC_CP { 2, 92, 2 } #define AR5K_RF5112A_LOW_VC_CP { 2, 94, 2 } #define AR5K_RF5112A_PUSH_UP { 1, 254, 2 } /* Power consumption */ #define AR5K_RF5112A_PAD2GND { 1, 281, 1 } #define AR5K_RF5112A_XB2_LVL { 2, 1, 3 } #define AR5K_RF5112A_XB5_LVL { 2, 3, 3 } static const struct ath5k_rf_reg rf_regs_5112a[] = { {6, AR5K_RF_OB_2GHZ, AR5K_RF5112A_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF5112A_DB_2GHZ}, {6, AR5K_RF_OB_5GHZ, AR5K_RF5112A_OB_5GHZ}, {6, AR5K_RF_DB_5GHZ, AR5K_RF5112A_DB_5GHZ}, {6, AR5K_RF_FIXED_BIAS_A, AR5K_RF5112A_FIXED_BIAS_A}, {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112A_FIXED_BIAS_B}, {6, AR5K_RF_XPD_SEL, AR5K_RF5112A_XPD_SEL}, {6, AR5K_RF_PD_GAIN_LO, AR5K_RF5112A_PDGAINLO}, {6, AR5K_RF_PD_GAIN_HI, AR5K_RF5112A_PDGAINHI}, {6, AR5K_RF_PWD_130, AR5K_RF5112A_PWD(130)}, {6, AR5K_RF_PWD_131, AR5K_RF5112A_PWD(131)}, {6, AR5K_RF_PWD_132, AR5K_RF5112A_PWD(132)}, {6, AR5K_RF_PWD_136, AR5K_RF5112A_PWD(136)}, {6, AR5K_RF_PWD_137, AR5K_RF5112A_PWD(137)}, {6, AR5K_RF_PWD_138, AR5K_RF5112A_PWD(138)}, {6, AR5K_RF_PWD_166, AR5K_RF5112A_PWD(166)}, {6, AR5K_RF_PWD_167, AR5K_RF5112A_PWD(167)}, {6, AR5K_RF_HIGH_VC_CP, AR5K_RF5112A_HIGH_VC_CP}, {6, AR5K_RF_MID_VC_CP, AR5K_RF5112A_MID_VC_CP}, {6, AR5K_RF_LOW_VC_CP, AR5K_RF5112A_LOW_VC_CP}, {6, AR5K_RF_PUSH_UP, AR5K_RF5112A_PUSH_UP}, {6, AR5K_RF_PAD2GND, AR5K_RF5112A_PAD2GND}, {6, AR5K_RF_XB2_LVL, AR5K_RF5112A_XB2_LVL}, {6, AR5K_RF_XB5_LVL, AR5K_RF5112A_XB5_LVL}, {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I}, {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR}, {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR}, {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP}, {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A}, {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B}, {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR}, {7, AR5K_RF_PD_PERIOD_A, AR5K_RF5112X_PD_PERIOD_A}, {7, AR5K_RF_PD_PERIOD_B, AR5K_RF5112X_PD_PERIOD_B}, {7, AR5K_RF_PD_PERIOD_XR, AR5K_RF5112X_PD_PERIOD_XR}, }; /* Default mode specific settings */ static const struct ath5k_ini_rfbuffer rfb_5112a[] = { { 1, 0x98d4, /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, { 2, 0x98d0, { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } }, { 3, 0x98dc, { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } }, { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, { 6, 0x989c, { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } }, { 6, 0x989c, { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } }, { 6, 0x989c, { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } }, { 6, 0x989c, { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } }, { 6, 0x989c, { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } }, { 6, 0x989c, { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } }, { 6, 0x989c, { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } }, { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, { 6, 0x989c, { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } }, { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } }, { 6, 0x989c, { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } }, { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } }, { 6, 0x989c, { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } }, { 6, 0x989c, { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } }, { 6, 0x989c, { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } }, { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } }, { 6, 0x989c, { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } }, { 6, 0x989c, { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } }, { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } }, { 6, 0x989c, { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } }, { 6, 0x989c, { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } }, { 6, 0x989c, { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } }, { 6, 0x989c, { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } }, { 6, 0x989c, { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } }, { 6, 0x989c, { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } }, { 6, 0x989c, { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } }, { 6, 0x989c, { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } }, { 6, 0x989c, { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } }, { 6, 0x98d8, { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } }, { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } }, { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } }, { 7, 0x989c, { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } }, { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } }, { 7, 0x989c, { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } }, { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } }, { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } }, { 7, 0x989c, { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } }, { 7, 0x989c, { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } }, { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } }, { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } }, { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } }, { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } }, }; /******************\ * RF2413 (Griffin) * \******************/ /* BANK 6 len pos col */ #define AR5K_RF2413_OB_2GHZ { 3, 168, 0 } #define AR5K_RF2413_DB_2GHZ { 3, 165, 0 } static const struct ath5k_rf_reg rf_regs_2413[] = { {6, AR5K_RF_OB_2GHZ, AR5K_RF2413_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF2413_DB_2GHZ}, }; /* Default mode specific settings * XXX: a/aTurbo ??? */ static const struct ath5k_ini_rfbuffer rfb_2413[] = { { 1, 0x98d4, /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, { 2, 0x98d0, { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } }, { 3, 0x98dc, { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, { 6, 0x989c, { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } }, { 6, 0x989c, { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } }, { 6, 0x989c, { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } }, { 6, 0x989c, { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } }, { 6, 0x989c, { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } }, { 6, 0x989c, { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } }, { 6, 0x989c, { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } }, { 6, 0x989c, { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } }, { 6, 0x989c, { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } }, { 6, 0x989c, { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } }, { 6, 0x989c, { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } }, { 6, 0x989c, { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } }, { 6, 0x989c, { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } }, { 6, 0x98d8, { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } }, { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, }; /***************************\ * RF2315/RF2316 (Cobra SoC) * \***************************/ /* BANK 6 len pos col */ #define AR5K_RF2316_OB_2GHZ { 3, 178, 0 } #define AR5K_RF2316_DB_2GHZ { 3, 175, 0 } static const struct ath5k_rf_reg rf_regs_2316[] = { {6, AR5K_RF_OB_2GHZ, AR5K_RF2316_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF2316_DB_2GHZ}, }; /* Default mode specific settings */ static const struct ath5k_ini_rfbuffer rfb_2316[] = { { 1, 0x98d4, /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, { 2, 0x98d0, { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } }, { 3, 0x98dc, { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } }, { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } }, { 6, 0x989c, { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } }, { 6, 0x989c, { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } }, { 6, 0x989c, { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } }, { 6, 0x989c, { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } }, { 6, 0x989c, { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } }, { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } }, { 6, 0x989c, { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } }, { 6, 0x989c, { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } }, { 6, 0x989c, { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } }, { 6, 0x989c, { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } }, { 6, 0x989c, { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } }, { 6, 0x989c, { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } }, { 6, 0x989c, { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } }, { 6, 0x989c, { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } }, { 6, 0x989c, { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } }, { 6, 0x989c, { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } }, { 6, 0x98c0, { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } }, { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, }; /******************************\ * RF5413/RF5424 (Eagle/Condor) * \******************************/ /* BANK 6 len pos col */ #define AR5K_RF5413_OB_2GHZ { 3, 241, 0 } #define AR5K_RF5413_DB_2GHZ { 3, 238, 0 } #define AR5K_RF5413_OB_5GHZ { 3, 247, 0 } #define AR5K_RF5413_DB_5GHZ { 3, 244, 0 } #define AR5K_RF5413_PWD_ICLOBUF2G { 3, 131, 3 } #define AR5K_RF5413_DERBY_CHAN_SEL_MODE { 1, 291, 2 } static const struct ath5k_rf_reg rf_regs_5413[] = { {6, AR5K_RF_OB_2GHZ, AR5K_RF5413_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF5413_DB_2GHZ}, {6, AR5K_RF_OB_5GHZ, AR5K_RF5413_OB_5GHZ}, {6, AR5K_RF_DB_5GHZ, AR5K_RF5413_DB_5GHZ}, {6, AR5K_RF_PWD_ICLOBUF_2G, AR5K_RF5413_PWD_ICLOBUF2G}, {6, AR5K_RF_DERBY_CHAN_SEL_MODE, AR5K_RF5413_DERBY_CHAN_SEL_MODE}, }; /* Default mode specific settings */ static const struct ath5k_ini_rfbuffer rfb_5413[] = { { 1, 0x98d4, /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, { 2, 0x98d0, { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } }, { 3, 0x98dc, { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } }, { 6, 0x989c, { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } }, { 6, 0x989c, { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } }, { 6, 0x989c, { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } }, { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } }, { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } }, { 6, 0x989c, { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } }, { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, { 6, 0x989c, { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } }, { 6, 0x989c, { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } }, { 6, 0x989c, { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } }, { 6, 0x989c, { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } }, { 6, 0x989c, { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } }, { 6, 0x989c, { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } }, { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } }, { 6, 0x989c, { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } }, { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } }, { 6, 0x989c, { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } }, { 6, 0x989c, { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } }, { 6, 0x989c, { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } }, { 6, 0x989c, { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } }, { 6, 0x989c, { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } }, { 6, 0x989c, { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } }, { 6, 0x989c, { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } }, { 6, 0x98c8, { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } }, { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, }; /***************************\ * RF2425/RF2417 (Swan/Nala) * * AR2317 (Spider SoC) * \***************************/ /* BANK 6 len pos col */ #define AR5K_RF2425_OB_2GHZ { 3, 193, 0 } #define AR5K_RF2425_DB_2GHZ { 3, 190, 0 } static const struct ath5k_rf_reg rf_regs_2425[] = { {6, AR5K_RF_OB_2GHZ, AR5K_RF2425_OB_2GHZ}, {6, AR5K_RF_DB_2GHZ, AR5K_RF2425_DB_2GHZ}, }; /* Default mode specific settings * XXX: a/aTurbo ? */ static const struct ath5k_ini_rfbuffer rfb_2425[] = { { 1, 0x98d4, /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } }, { 3, 0x98dc, { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } }, { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } }, { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } }, { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } }, { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } }, { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } }, { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } }, { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } }, { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } }, { 6, 0x989c, { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } }, { 6, 0x989c, { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } }, { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } }, { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } }, { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, }; /* * TODO: Handle the few differences with swan during * bank modification and get rid of this */ static const struct ath5k_ini_rfbuffer rfb_2317[] = { { 1, 0x98d4, /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, { 2, 0x98d0, { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } }, { 3, 0x98dc, { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } }, { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } }, { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } }, { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } }, { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } }, { 6, 0x989c, { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } }, { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } }, { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } }, { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } }, { 6, 0x989c, { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } }, { 6, 0x989c, { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } }, { 6, 0x989c, { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } }, { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } }, { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, }; /* * TODO: Handle the few differences with swan during * bank modification and get rid of this * XXX: a/aTurbo ? */ static const struct ath5k_ini_rfbuffer rfb_2417[] = { { 1, 0x98d4, /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } }, { 3, 0x98dc, { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } }, { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } }, { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } }, { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } }, { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } }, { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } }, { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } }, { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } }, { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } }, { 6, 0x989c, { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } }, { 6, 0x989c, { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } }, { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } }, { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } }, { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } }, { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } }, { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, }; debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k_phy.c0000664000000000000000000020511712524662415022271 0ustar /* * PHY functions * * Copyright (c) 2004-2007 Reyk Floeter * Copyright (c) 2006-2009 Nick Kossifidis * Copyright (c) 2007-2008 Jiri Slaby * Copyright (c) 2008-2009 Felix Fietkau * * Lightly modified for gPXE, July 2009, by Joshua Oreman . * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ FILE_LICENCE ( MIT ); #define _ATH5K_PHY #include #include #include "ath5k.h" #include "reg.h" #include "base.h" #include "rfbuffer.h" #include "rfgain.h" static inline int min(int x, int y) { return (x < y) ? x : y; } static inline int max(int x, int y) { return (x > y) ? x : y; } /* * Used to modify RF Banks before writing them to AR5K_RF_BUFFER */ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, const struct ath5k_rf_reg *rf_regs, u32 val, u8 reg_id, int set) { const struct ath5k_rf_reg *rfreg = NULL; u8 offset, bank, num_bits, col, position; u16 entry; u32 mask, data, last_bit, bits_shifted, first_bit; u32 *rfb; s32 bits_left; unsigned i; data = 0; rfb = ah->ah_rf_banks; for (i = 0; i < ah->ah_rf_regs_count; i++) { if (rf_regs[i].index == reg_id) { rfreg = &rf_regs[i]; break; } } if (rfb == NULL || rfreg == NULL) { DBG("ath5k: RF register not found!\n"); /* should not happen */ return 0; } bank = rfreg->bank; num_bits = rfreg->field.len; first_bit = rfreg->field.pos; col = rfreg->field.col; /* first_bit is an offset from bank's * start. Since we have all banks on * the same array, we use this offset * to mark each bank's start */ offset = ah->ah_offset[bank]; /* Boundary check */ if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) { DBG("ath5k: RF invalid values at offset %d\n", offset); return 0; } entry = ((first_bit - 1) / 8) + offset; position = (first_bit - 1) % 8; if (set) data = ath5k_hw_bitswap(val, num_bits); for (bits_shifted = 0, bits_left = num_bits; bits_left > 0; position = 0, entry++) { last_bit = (position + bits_left > 8) ? 8 : position + bits_left; mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) << (col * 8); if (set) { rfb[entry] &= ~mask; rfb[entry] |= ((data << position) << (col * 8)) & mask; data >>= (8 - position); } else { data |= (((rfb[entry] & mask) >> (col * 8)) >> position) << bits_shifted; bits_shifted += last_bit - position; } bits_left -= 8 - position; } data = set ? 1 : ath5k_hw_bitswap(data, num_bits); return data; } /**********************\ * RF Gain optimization * \**********************/ /* * This code is used to optimize rf gain on different environments * (temprature mostly) based on feedback from a power detector. * * It's only used on RF5111 and RF5112, later RF chips seem to have * auto adjustment on hw -notice they have a much smaller BANK 7 and * no gain optimization ladder-. * * For more infos check out this patent doc * http://www.freepatentsonline.com/7400691.html * * This paper describes power drops as seen on the receiver due to * probe packets * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues * %20of%20Power%20Control.pdf * * And this is the MadWiFi bug entry related to the above * http://madwifi-project.org/ticket/1659 * with various measurements and diagrams * * TODO: Deal with power drops due to probes by setting an apropriate * tx power on the probe packets ! Make this part of the calibration process. */ /* Initialize ah_gain durring attach */ int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah) { /* Initialize the gain optimization values */ switch (ah->ah_radio) { case AR5K_RF5111: ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default; ah->ah_gain.g_low = 20; ah->ah_gain.g_high = 35; ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; break; case AR5K_RF5112: ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default; ah->ah_gain.g_low = 20; ah->ah_gain.g_high = 85; ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; break; default: return -EINVAL; } return 0; } /* Schedule a gain probe check on the next transmited packet. * That means our next packet is going to be sent with lower * tx power and a Peak to Average Power Detector (PAPD) will try * to measure the gain. * * TODO: Use propper tx power setting for the probe packet so * that we don't observe a serious power drop on the receiver * * XXX: How about forcing a tx packet (bypassing PCU arbitrator etc) * just after we enable the probe so that we don't mess with * standard traffic ? Maybe it's time to use sw interrupts and * a probe tasklet !!! */ static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah) { /* Skip if gain calibration is inactive or * we already handle a probe request */ if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE) return; /* Send the packet with 2dB below max power as * patent doc suggest */ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max_pwr - 4, AR5K_PHY_PAPD_PROBE_TXPOWER) | AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE); ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED; } /* Calculate gain_F measurement correction * based on the current step for RF5112 rev. 2 */ static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah) { u32 mix, step; u32 *rf; const struct ath5k_gain_opt *go; const struct ath5k_gain_opt_step *g_step; const struct ath5k_rf_reg *rf_regs; /* Only RF5112 Rev. 2 supports it */ if ((ah->ah_radio != AR5K_RF5112) || (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A)) return 0; go = &rfgain_opt_5112; rf_regs = rf_regs_5112a; ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a); g_step = &go->go_step[ah->ah_gain.g_step_idx]; if (ah->ah_rf_banks == NULL) return 0; rf = ah->ah_rf_banks; ah->ah_gain.g_f_corr = 0; /* No VGA (Variable Gain Amplifier) override, skip */ if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, 0) != 1) return 0; /* Mix gain stepping */ step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, 0); /* Mix gain override */ mix = g_step->gos_param[0]; switch (mix) { case 3: ah->ah_gain.g_f_corr = step * 2; break; case 2: ah->ah_gain.g_f_corr = (step - 5) * 2; break; case 1: ah->ah_gain.g_f_corr = step; break; default: ah->ah_gain.g_f_corr = 0; break; } return ah->ah_gain.g_f_corr; } /* Check if current gain_F measurement is in the range of our * power detector windows. If we get a measurement outside range * we know it's not accurate (detectors can't measure anything outside * their detection window) so we must ignore it */ static int ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah) { const struct ath5k_rf_reg *rf_regs; u32 step, mix_ovr, level[4]; u32 *rf; if (ah->ah_rf_banks == NULL) return 0; rf = ah->ah_rf_banks; if (ah->ah_radio == AR5K_RF5111) { rf_regs = rf_regs_5111; ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111); step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP, 0); level[0] = 0; level[1] = (step == 63) ? 50 : step + 4; level[2] = (step != 63) ? 64 : level[0]; level[3] = level[2] + 50 ; ah->ah_gain.g_high = level[3] - (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5); ah->ah_gain.g_low = level[0] + (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0); } else { rf_regs = rf_regs_5112; ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112); mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, 0); level[0] = level[2] = 0; if (mix_ovr == 1) { level[1] = level[3] = 83; } else { level[1] = level[3] = 107; ah->ah_gain.g_high = 55; } } return (ah->ah_gain.g_current >= level[0] && ah->ah_gain.g_current <= level[1]) || (ah->ah_gain.g_current >= level[2] && ah->ah_gain.g_current <= level[3]); } /* Perform gain_F adjustment by choosing the right set * of parameters from rf gain optimization ladder */ static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah) { const struct ath5k_gain_opt *go; const struct ath5k_gain_opt_step *g_step; int ret = 0; switch (ah->ah_radio) { case AR5K_RF5111: go = &rfgain_opt_5111; break; case AR5K_RF5112: go = &rfgain_opt_5112; break; default: return 0; } g_step = &go->go_step[ah->ah_gain.g_step_idx]; if (ah->ah_gain.g_current >= ah->ah_gain.g_high) { /* Reached maximum */ if (ah->ah_gain.g_step_idx == 0) return -1; for (ah->ah_gain.g_target = ah->ah_gain.g_current; ah->ah_gain.g_target >= ah->ah_gain.g_high && ah->ah_gain.g_step_idx > 0; g_step = &go->go_step[ah->ah_gain.g_step_idx]) ah->ah_gain.g_target -= 2 * (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain - g_step->gos_gain); ret = 1; goto done; } if (ah->ah_gain.g_current <= ah->ah_gain.g_low) { /* Reached minimum */ if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1)) return -2; for (ah->ah_gain.g_target = ah->ah_gain.g_current; ah->ah_gain.g_target <= ah->ah_gain.g_low && ah->ah_gain.g_step_idx < go->go_steps_count-1; g_step = &go->go_step[ah->ah_gain.g_step_idx]) ah->ah_gain.g_target -= 2 * (go->go_step[++ah->ah_gain.g_step_idx].gos_gain - g_step->gos_gain); ret = 2; goto done; } done: DBG2("ath5k RF adjust: ret %d, gain step %d, current gain %d, " "target gain %d\n", ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current, ah->ah_gain.g_target); return ret; } /* Main callback for thermal rf gain calibration engine * Check for a new gain reading and schedule an adjustment * if needed. * * TODO: Use sw interrupt to schedule reset if gain_F needs * adjustment */ enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah) { u32 data, type; struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; if (ah->ah_rf_banks == NULL || ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE) return AR5K_RFGAIN_INACTIVE; /* No check requested, either engine is inactive * or an adjustment is already requested */ if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED) goto done; /* Read the PAPD (Peak to Average Power Detector) * register */ data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE); /* No probe is scheduled, read gain_F measurement */ if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) { ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S; type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE); /* If tx packet is CCK correct the gain_F measurement * by cck ofdm gain delta */ if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) { if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) ah->ah_gain.g_current += ee->ee_cck_ofdm_gain_delta; else ah->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR; } /* Further correct gain_F measurement for * RF5112A radios */ if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) { ath5k_hw_rf_gainf_corr(ah); ah->ah_gain.g_current = ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ? (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) : 0; } /* Check if measurement is ok and if we need * to adjust gain, schedule a gain adjustment, * else switch back to the acive state */ if (ath5k_hw_rf_check_gainf_readback(ah) && AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) && ath5k_hw_rf_gainf_adjust(ah)) { ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE; } else { ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; } } done: return ah->ah_gain.g_state; } /* Write initial rf gain table to set the RF sensitivity * this one works on all RF chips and has nothing to do * with gain_F calibration */ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) { const struct ath5k_ini_rfgain *ath5k_rfg; unsigned int i, size; switch (ah->ah_radio) { case AR5K_RF5111: ath5k_rfg = rfgain_5111; size = ARRAY_SIZE(rfgain_5111); break; case AR5K_RF5112: ath5k_rfg = rfgain_5112; size = ARRAY_SIZE(rfgain_5112); break; case AR5K_RF2413: ath5k_rfg = rfgain_2413; size = ARRAY_SIZE(rfgain_2413); break; case AR5K_RF2316: ath5k_rfg = rfgain_2316; size = ARRAY_SIZE(rfgain_2316); break; case AR5K_RF5413: ath5k_rfg = rfgain_5413; size = ARRAY_SIZE(rfgain_5413); break; case AR5K_RF2317: case AR5K_RF2425: ath5k_rfg = rfgain_2425; size = ARRAY_SIZE(rfgain_2425); break; default: return -EINVAL; } switch (freq) { case AR5K_INI_RFGAIN_2GHZ: case AR5K_INI_RFGAIN_5GHZ: break; default: return -EINVAL; } for (i = 0; i < size; i++) { AR5K_REG_WAIT(i); ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq], (u32)ath5k_rfg[i].rfg_register); } return 0; } /********************\ * RF Registers setup * \********************/ /* * Setup RF registers by writing rf buffer on hw */ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct net80211_channel *channel, unsigned int mode) { const struct ath5k_rf_reg *rf_regs; const struct ath5k_ini_rfbuffer *ini_rfb; const struct ath5k_gain_opt *go = NULL; const struct ath5k_gain_opt_step *g_step; struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; u8 ee_mode = 0; u32 *rfb; int obdb = -1, bank = -1; unsigned i; switch (ah->ah_radio) { case AR5K_RF5111: rf_regs = rf_regs_5111; ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111); ini_rfb = rfb_5111; ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111); go = &rfgain_opt_5111; break; case AR5K_RF5112: if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) { rf_regs = rf_regs_5112a; ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a); ini_rfb = rfb_5112a; ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a); } else { rf_regs = rf_regs_5112; ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112); ini_rfb = rfb_5112; ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112); } go = &rfgain_opt_5112; break; case AR5K_RF2413: rf_regs = rf_regs_2413; ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413); ini_rfb = rfb_2413; ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413); break; case AR5K_RF2316: rf_regs = rf_regs_2316; ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316); ini_rfb = rfb_2316; ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316); break; case AR5K_RF5413: rf_regs = rf_regs_5413; ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413); ini_rfb = rfb_5413; ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413); break; case AR5K_RF2317: rf_regs = rf_regs_2425; ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425); ini_rfb = rfb_2317; ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317); break; case AR5K_RF2425: rf_regs = rf_regs_2425; ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425); if (ah->ah_mac_srev < AR5K_SREV_AR2417) { ini_rfb = rfb_2425; ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425); } else { ini_rfb = rfb_2417; ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417); } break; default: return -EINVAL; } /* If it's the first time we set rf buffer, allocate * ah->ah_rf_banks based on ah->ah_rf_banks_size * we set above */ if (ah->ah_rf_banks == NULL) { ah->ah_rf_banks = malloc(sizeof(u32) * ah->ah_rf_banks_size); if (ah->ah_rf_banks == NULL) { return -ENOMEM; } } /* Copy values to modify them */ rfb = ah->ah_rf_banks; for (i = 0; i < ah->ah_rf_banks_size; i++) { if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) { DBG("ath5k: invalid RF register bank\n"); return -EINVAL; } /* Bank changed, write down the offset */ if (bank != ini_rfb[i].rfb_bank) { bank = ini_rfb[i].rfb_bank; ah->ah_offset[bank] = i; } rfb[i] = ini_rfb[i].rfb_mode_data[mode]; } /* Set Output and Driver bias current (OB/DB) */ if (channel->hw_value & CHANNEL_2GHZ) { if (channel->hw_value & CHANNEL_CCK) ee_mode = AR5K_EEPROM_MODE_11B; else ee_mode = AR5K_EEPROM_MODE_11G; /* For RF511X/RF211X combination we * use b_OB and b_DB parameters stored * in eeprom on ee->ee_ob[ee_mode][0] * * For all other chips we use OB/DB for 2Ghz * stored in the b/g modal section just like * 802.11a on ee->ee_ob[ee_mode][1] */ if ((ah->ah_radio == AR5K_RF5111) || (ah->ah_radio == AR5K_RF5112)) obdb = 0; else obdb = 1; ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb], AR5K_RF_OB_2GHZ, 1); ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb], AR5K_RF_DB_2GHZ, 1); /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */ } else if ((channel->hw_value & CHANNEL_5GHZ) || (ah->ah_radio == AR5K_RF5111)) { /* For 11a, Turbo and XR we need to choose * OB/DB based on frequency range */ ee_mode = AR5K_EEPROM_MODE_11A; obdb = channel->center_freq >= 5725 ? 3 : (channel->center_freq >= 5500 ? 2 : (channel->center_freq >= 5260 ? 1 : (channel->center_freq > 4000 ? 0 : -1))); if (obdb < 0) return -EINVAL; ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb], AR5K_RF_OB_5GHZ, 1); ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb], AR5K_RF_DB_5GHZ, 1); } g_step = &go->go_step[ah->ah_gain.g_step_idx]; /* Bank Modifications (chip-specific) */ if (ah->ah_radio == AR5K_RF5111) { /* Set gain_F settings according to current step */ if (channel->hw_value & CHANNEL_OFDM) { AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL, AR5K_PHY_FRAME_CTL_TX_CLIP, g_step->gos_param[0]); ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1], AR5K_RF_PWD_90, 1); ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2], AR5K_RF_PWD_84, 1); ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3], AR5K_RF_RFGAIN_SEL, 1); /* We programmed gain_F parameters, switch back * to active state */ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; } /* Bank 6/7 setup */ ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode], AR5K_RF_PWD_XPD, 1); ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode], AR5K_RF_XPD_GAIN, 1); ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode], AR5K_RF_GAIN_I, 1); ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode], AR5K_RF_PLO_SEL, 1); /* TODO: Half/quarter channel support */ } if (ah->ah_radio == AR5K_RF5112) { /* Set gain_F settings according to current step */ if (channel->hw_value & CHANNEL_OFDM) { ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0], AR5K_RF_MIXGAIN_OVR, 1); ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1], AR5K_RF_PWD_138, 1); ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2], AR5K_RF_PWD_137, 1); ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3], AR5K_RF_PWD_136, 1); ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4], AR5K_RF_PWD_132, 1); ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5], AR5K_RF_PWD_131, 1); ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6], AR5K_RF_PWD_130, 1); /* We programmed gain_F parameters, switch back * to active state */ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; } /* Bank 6/7 setup */ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode], AR5K_RF_XPD_SEL, 1); if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) { /* Rev. 1 supports only one xpd */ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode], AR5K_RF_XPD_GAIN, 1); } else { /* TODO: Set high and low gain bits */ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode], AR5K_RF_PD_GAIN_LO, 1); ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode], AR5K_RF_PD_GAIN_HI, 1); /* Lower synth voltage on Rev 2 */ ath5k_hw_rfb_op(ah, rf_regs, 2, AR5K_RF_HIGH_VC_CP, 1); ath5k_hw_rfb_op(ah, rf_regs, 2, AR5K_RF_MID_VC_CP, 1); ath5k_hw_rfb_op(ah, rf_regs, 2, AR5K_RF_LOW_VC_CP, 1); ath5k_hw_rfb_op(ah, rf_regs, 2, AR5K_RF_PUSH_UP, 1); /* Decrease power consumption on 5213+ BaseBand */ if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_PAD2GND, 1); ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_XB2_LVL, 1); ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_XB5_LVL, 1); ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_PWD_167, 1); ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_PWD_166, 1); } } ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode], AR5K_RF_GAIN_I, 1); /* TODO: Half/quarter channel support */ } if (ah->ah_radio == AR5K_RF5413 && channel->hw_value & CHANNEL_2GHZ) { ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE, 1); /* Set optimum value for early revisions (on pci-e chips) */ if (ah->ah_mac_srev >= AR5K_SREV_AR5424 && ah->ah_mac_srev < AR5K_SREV_AR5413) ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3), AR5K_RF_PWD_ICLOBUF_2G, 1); } /* Write RF banks on hw */ for (i = 0; i < ah->ah_rf_banks_size; i++) { AR5K_REG_WAIT(i); ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register); } return 0; } /**************************\ PHY/RF channel functions \**************************/ /* * Check if a channel is supported */ int ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags) { /* Check if the channel is in our supported range */ if (flags & CHANNEL_2GHZ) { if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) && (freq <= ah->ah_capabilities.cap_range.range_2ghz_max)) return 1; } else if (flags & CHANNEL_5GHZ) if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) && (freq <= ah->ah_capabilities.cap_range.range_5ghz_max)) return 1; return 0; } /* * Convertion needed for RF5110 */ static u32 ath5k_hw_rf5110_chan2athchan(struct net80211_channel *channel) { u32 athchan; /* * Convert IEEE channel/MHz to an internal channel value used * by the AR5210 chipset. This has not been verified with * newer chipsets like the AR5212A who have a completely * different RF/PHY part. */ athchan = (ath5k_hw_bitswap((ath5k_freq_to_channel(channel->center_freq) - 24) / 2, 5) << 1) | (1 << 6) | 0x1; return athchan; } /* * Set channel on RF5110 */ static int ath5k_hw_rf5110_channel(struct ath5k_hw *ah, struct net80211_channel *channel) { u32 data; /* * Set the channel and wait */ data = ath5k_hw_rf5110_chan2athchan(channel); ath5k_hw_reg_write(ah, data, AR5K_RF_BUFFER); ath5k_hw_reg_write(ah, 0, AR5K_RF_BUFFER_CONTROL_0); mdelay(1); return 0; } /* * Convertion needed for 5111 */ static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee, struct ath5k_athchan_2ghz *athchan) { int channel; /* Cast this value to catch negative channel numbers (>= -19) */ channel = (int)ieee; /* * Map 2GHz IEEE channel to 5GHz Atheros channel */ if (channel <= 13) { athchan->a2_athchan = 115 + channel; athchan->a2_flags = 0x46; } else if (channel == 14) { athchan->a2_athchan = 124; athchan->a2_flags = 0x44; } else if (channel >= 15 && channel <= 26) { athchan->a2_athchan = ((channel - 14) * 4) + 132; athchan->a2_flags = 0x46; } else return -EINVAL; return 0; } /* * Set channel on 5111 */ static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah, struct net80211_channel *channel) { struct ath5k_athchan_2ghz ath5k_channel_2ghz; unsigned int ath5k_channel = ath5k_freq_to_channel(channel->center_freq); u32 data0, data1, clock; int ret; /* * Set the channel on the RF5111 radio */ data0 = data1 = 0; if (channel->hw_value & CHANNEL_2GHZ) { /* Map 2GHz channel to 5GHz Atheros channel ID */ ret = ath5k_hw_rf5111_chan2athchan(ath5k_channel, &ath5k_channel_2ghz); if (ret) return ret; ath5k_channel = ath5k_channel_2ghz.a2_athchan; data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff) << 5) | (1 << 4); } if (ath5k_channel < 145 || !(ath5k_channel & 1)) { clock = 1; data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) | (clock << 1) | (1 << 10) | 1; } else { clock = 0; data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff) << 2) | (clock << 1) | (1 << 10) | 1; } ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8), AR5K_RF_BUFFER); ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00), AR5K_RF_BUFFER_CONTROL_3); return 0; } /* * Set channel on 5112 and newer */ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah, struct net80211_channel *channel) { u32 data, data0, data1, data2; u16 c; data = data0 = data1 = data2 = 0; c = channel->center_freq; if (c < 4800) { if (!((c - 2224) % 5)) { data0 = ((2 * (c - 704)) - 3040) / 10; data1 = 1; } else if (!((c - 2192) % 5)) { data0 = ((2 * (c - 672)) - 3040) / 10; data1 = 0; } else return -EINVAL; data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8); } else if ((c - (c % 5)) != 2 || c > 5435) { if (!(c % 20) && c >= 5120) { data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8); data2 = ath5k_hw_bitswap(3, 2); } else if (!(c % 10)) { data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8); data2 = ath5k_hw_bitswap(2, 2); } else if (!(c % 5)) { data0 = ath5k_hw_bitswap((c - 4800) / 5, 8); data2 = ath5k_hw_bitswap(1, 2); } else return -EINVAL; } else { data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8); data2 = ath5k_hw_bitswap(0, 2); } data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001; ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER); ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5); return 0; } /* * Set the channel on the RF2425 */ static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah, struct net80211_channel *channel) { u32 data, data0, data2; u16 c; data = data0 = data2 = 0; c = channel->center_freq; if (c < 4800) { data0 = ath5k_hw_bitswap((c - 2272), 8); data2 = 0; /* ? 5GHz ? */ } else if ((c - (c % 5)) != 2 || c > 5435) { if (!(c % 20) && c < 5120) data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8); else if (!(c % 10)) data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8); else if (!(c % 5)) data0 = ath5k_hw_bitswap((c - 4800) / 5, 8); else return -EINVAL; data2 = ath5k_hw_bitswap(1, 2); } else { data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8); data2 = ath5k_hw_bitswap(0, 2); } data = (data0 << 4) | data2 << 2 | 0x1001; ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER); ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5); return 0; } /* * Set a channel on the radio chip */ int ath5k_hw_channel(struct ath5k_hw *ah, struct net80211_channel *channel) { int ret; /* * Check bounds supported by the PHY (we don't care about regultory * restrictions at this point). Note: hw_value already has the band * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok() * of the band by that */ if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) { DBG("ath5k: channel frequency (%d MHz) out of supported " "range\n", channel->center_freq); return -EINVAL; } /* * Set the channel and wait */ switch (ah->ah_radio) { case AR5K_RF5110: ret = ath5k_hw_rf5110_channel(ah, channel); break; case AR5K_RF5111: ret = ath5k_hw_rf5111_channel(ah, channel); break; case AR5K_RF2425: ret = ath5k_hw_rf2425_channel(ah, channel); break; default: ret = ath5k_hw_rf5112_channel(ah, channel); break; } if (ret) { DBG("ath5k: setting channel failed: %s\n", strerror(ret)); return ret; } /* Set JAPAN setting for channel 14 */ if (channel->center_freq == 2484) { AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL, AR5K_PHY_CCKTXCTL_JAPAN); } else { AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL, AR5K_PHY_CCKTXCTL_WORLD); } ah->ah_current_channel = channel; ah->ah_turbo = (channel->hw_value == CHANNEL_T ? 1 : 0); return 0; } /*****************\ PHY calibration \*****************/ /** * ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration * * @ah: struct ath5k_hw pointer we are operating on * @freq: the channel frequency, just used for error logging * * This function performs a noise floor calibration of the PHY and waits for * it to complete. Then the noise floor value is compared to some maximum * noise floor we consider valid. * * Note that this is different from what the madwifi HAL does: it reads the * noise floor and afterwards initiates the calibration. Since the noise floor * calibration can take some time to finish, depending on the current channel * use, that avoids the occasional timeout warnings we are seeing now. * * See the following link for an Atheros patent on noise floor calibration: * http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \ * &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7 * * XXX: Since during noise floor calibration antennas are detached according to * the patent, we should stop tx queues here. */ int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq) { int ret; unsigned int i; s32 noise_floor; /* * Enable noise floor calibration */ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF); ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF, 0, 0); if (ret) { DBG("ath5k: noise floor calibration timeout (%d MHz)\n", freq); return -EAGAIN; } /* Wait until the noise floor is calibrated and read the value */ for (i = 20; i > 0; i--) { mdelay(1); noise_floor = ath5k_hw_reg_read(ah, AR5K_PHY_NF); noise_floor = AR5K_PHY_NF_RVAL(noise_floor); if (noise_floor & AR5K_PHY_NF_ACTIVE) { noise_floor = AR5K_PHY_NF_AVAL(noise_floor); if (noise_floor <= AR5K_TUNE_NOISE_FLOOR) break; } } DBG2("ath5k: noise floor %d\n", noise_floor); if (noise_floor > AR5K_TUNE_NOISE_FLOOR) { DBG("ath5k: noise floor calibration failed (%d MHz)\n", freq); return -EAGAIN; } ah->ah_noise_floor = noise_floor; return 0; } /* * Perform a PHY calibration on RF5110 * -Fix BPSK/QAM Constellation (I/Q correction) * -Calculate Noise Floor */ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, struct net80211_channel *channel) { u32 phy_sig, phy_agc, phy_sat, beacon; int ret; /* * Disable beacons and RX/TX queues, wait */ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210, AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210); beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210); ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210); mdelay(2); /* * Set the channel (with AGC turned off) */ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); udelay(10); ret = ath5k_hw_channel(ah, channel); /* * Activate PHY and wait */ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); mdelay(1); AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); if (ret) return ret; /* * Calibrate the radio chip */ /* Remember normal state */ phy_sig = ath5k_hw_reg_read(ah, AR5K_PHY_SIG); phy_agc = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCOARSE); phy_sat = ath5k_hw_reg_read(ah, AR5K_PHY_ADCSAT); /* Update radio registers */ ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) | AR5K_REG_SM(-1, AR5K_PHY_SIG_FIRPWR), AR5K_PHY_SIG); ath5k_hw_reg_write(ah, (phy_agc & ~(AR5K_PHY_AGCCOARSE_HI | AR5K_PHY_AGCCOARSE_LO)) | AR5K_REG_SM(-1, AR5K_PHY_AGCCOARSE_HI) | AR5K_REG_SM(-127, AR5K_PHY_AGCCOARSE_LO), AR5K_PHY_AGCCOARSE); ath5k_hw_reg_write(ah, (phy_sat & ~(AR5K_PHY_ADCSAT_ICNT | AR5K_PHY_ADCSAT_THR)) | AR5K_REG_SM(2, AR5K_PHY_ADCSAT_ICNT) | AR5K_REG_SM(12, AR5K_PHY_ADCSAT_THR), AR5K_PHY_ADCSAT); udelay(20); AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); udelay(10); ath5k_hw_reg_write(ah, AR5K_PHY_RFSTG_DISABLE, AR5K_PHY_RFSTG); AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); mdelay(1); /* * Enable calibration and wait until completion */ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL); ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL, 0, 0); /* Reset to normal state */ ath5k_hw_reg_write(ah, phy_sig, AR5K_PHY_SIG); ath5k_hw_reg_write(ah, phy_agc, AR5K_PHY_AGCCOARSE); ath5k_hw_reg_write(ah, phy_sat, AR5K_PHY_ADCSAT); if (ret) { DBG("ath5k: calibration timeout (%d MHz)\n", channel->center_freq); return ret; } ath5k_hw_noise_floor_calibration(ah, channel->center_freq); /* * Re-enable RX/TX and beacons */ AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210, AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210); ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210); return 0; } /* * Perform a PHY calibration on RF5111/5112 and newer chips */ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, struct net80211_channel *channel) { u32 i_pwr, q_pwr; s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd; int i; if (!ah->ah_calibration || ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) goto done; /* Calibration has finished, get the results and re-run */ for (i = 0; i <= 10; i++) { iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I); q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q); } i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; q_coffd = q_pwr >> 7; /* No correction */ if (i_coffd == 0 || q_coffd == 0) goto done; i_coff = ((-iq_corr) / i_coffd) & 0x3f; /* Boundary check */ if (i_coff > 31) i_coff = 31; if (i_coff < -32) i_coff = -32; q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f; /* Boundary check */ if (q_coff > 15) q_coff = 15; if (q_coff < -16) q_coff = -16; /* Commit new I/Q value */ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE | ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); /* Re-enable calibration -if we don't we'll commit * the same values again and again */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN); done: /* TODO: Separate noise floor calibration from I/Q calibration * since noise floor calibration interrupts rx path while I/Q * calibration doesn't. We don't need to run noise floor calibration * as often as I/Q calibration.*/ ath5k_hw_noise_floor_calibration(ah, channel->center_freq); /* Initiate a gain_F calibration */ ath5k_hw_request_rfgain_probe(ah); return 0; } /* * Perform a PHY calibration */ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct net80211_channel *channel) { int ret; if (ah->ah_radio == AR5K_RF5110) ret = ath5k_hw_rf5110_calibrate(ah, channel); else ret = ath5k_hw_rf511x_calibrate(ah, channel); return ret; } int ath5k_hw_phy_disable(struct ath5k_hw *ah) { ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); return 0; } /********************\ Misc PHY functions \********************/ /* * Get the PHY Chip revision */ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) { unsigned int i; u32 srev; u16 ret; /* * Set the radio chip access register */ switch (chan) { case CHANNEL_2GHZ: ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0)); break; case CHANNEL_5GHZ: ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); break; default: return 0; } mdelay(2); /* ...wait until PHY is ready and read the selected radio revision */ ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34)); for (i = 0; i < 8; i++) ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); if (ah->ah_version == AR5K_AR5210) { srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf; ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; } else { srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8); } /* Reset to the 5GHz mode */ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); return ret; } void /*TODO:Boundary check*/ ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant) { if (ah->ah_version != AR5K_AR5210) ath5k_hw_reg_write(ah, ant, AR5K_DEFAULT_ANTENNA); } unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah) { if (ah->ah_version != AR5K_AR5210) return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); return 0; /*XXX: What do we return for 5210 ?*/ } /****************\ * TX power setup * \****************/ /* * Helper functions */ /* * Do linear interpolation between two given (x, y) points */ static s16 ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right, s16 y_left, s16 y_right) { s16 ratio, result; /* Avoid divide by zero and skip interpolation * if we have the same point */ if ((x_left == x_right) || (y_left == y_right)) return y_left; /* * Since we use ints and not fps, we need to scale up in * order to get a sane ratio value (or else we 'll eg. get * always 1 instead of 1.25, 1.75 etc). We scale up by 100 * to have some accuracy both for 0.5 and 0.25 steps. */ ratio = ((100 * y_right - 100 * y_left)/(x_right - x_left)); /* Now scale down to be in range */ result = y_left + (ratio * (target - x_left) / 100); return result; } /* * Find vertical boundary (min pwr) for the linear PCDAC curve. * * Since we have the top of the curve and we draw the line below * until we reach 1 (1 pcdac step) we need to know which point * (x value) that is so that we don't go below y axis and have negative * pcdac values when creating the curve, or fill the table with zeroes. */ static s16 ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR, const s16 *pwrL, const s16 *pwrR) { s8 tmp; s16 min_pwrL, min_pwrR; s16 pwr_i; if (pwrL[0] == pwrL[1]) min_pwrL = pwrL[0]; else { pwr_i = pwrL[0]; do { pwr_i--; tmp = (s8) ath5k_get_interpolated_value(pwr_i, pwrL[0], pwrL[1], stepL[0], stepL[1]); } while (tmp > 1); min_pwrL = pwr_i; } if (pwrR[0] == pwrR[1]) min_pwrR = pwrR[0]; else { pwr_i = pwrR[0]; do { pwr_i--; tmp = (s8) ath5k_get_interpolated_value(pwr_i, pwrR[0], pwrR[1], stepR[0], stepR[1]); } while (tmp > 1); min_pwrR = pwr_i; } /* Keep the right boundary so that it works for both curves */ return max(min_pwrL, min_pwrR); } /* * Interpolate (pwr,vpd) points to create a Power to PDADC or a * Power to PCDAC curve. * * Each curve has power on x axis (in 0.5dB units) and PCDAC/PDADC * steps (offsets) on y axis. Power can go up to 31.5dB and max * PCDAC/PDADC step for each curve is 64 but we can write more than * one curves on hw so we can go up to 128 (which is the max step we * can write on the final table). * * We write y values (PCDAC/PDADC steps) on hw. */ static void ath5k_create_power_curve(s16 pmin, s16 pmax, const s16 *pwr, const u8 *vpd, u8 num_points, u8 *vpd_table, u8 type) { u8 idx[2] = { 0, 1 }; s16 pwr_i = 2*pmin; int i; if (num_points < 2) return; /* We want the whole line, so adjust boundaries * to cover the entire power range. Note that * power values are already 0.25dB so no need * to multiply pwr_i by 2 */ if (type == AR5K_PWRTABLE_LINEAR_PCDAC) { pwr_i = pmin; pmin = 0; pmax = 63; } /* Find surrounding turning points (TPs) * and interpolate between them */ for (i = 0; (i <= (u16) (pmax - pmin)) && (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) { /* We passed the right TP, move to the next set of TPs * if we pass the last TP, extrapolate above using the last * two TPs for ratio */ if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) { idx[0]++; idx[1]++; } vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i, pwr[idx[0]], pwr[idx[1]], vpd[idx[0]], vpd[idx[1]]); /* Increase by 0.5dB * (0.25 dB units) */ pwr_i += 2; } } /* * Get the surrounding per-channel power calibration piers * for a given frequency so that we can interpolate between * them and come up with an apropriate dataset for our current * channel. */ static void ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah, struct net80211_channel *channel, struct ath5k_chan_pcal_info **pcinfo_l, struct ath5k_chan_pcal_info **pcinfo_r) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info *pcinfo; u8 idx_l, idx_r; u8 mode, max, i; u32 target = channel->center_freq; idx_l = 0; idx_r = 0; if (!(channel->hw_value & CHANNEL_OFDM)) { pcinfo = ee->ee_pwr_cal_b; mode = AR5K_EEPROM_MODE_11B; } else if (channel->hw_value & CHANNEL_2GHZ) { pcinfo = ee->ee_pwr_cal_g; mode = AR5K_EEPROM_MODE_11G; } else { pcinfo = ee->ee_pwr_cal_a; mode = AR5K_EEPROM_MODE_11A; } max = ee->ee_n_piers[mode] - 1; /* Frequency is below our calibrated * range. Use the lowest power curve * we have */ if (target < pcinfo[0].freq) { idx_l = idx_r = 0; goto done; } /* Frequency is above our calibrated * range. Use the highest power curve * we have */ if (target > pcinfo[max].freq) { idx_l = idx_r = max; goto done; } /* Frequency is inside our calibrated * channel range. Pick the surrounding * calibration piers so that we can * interpolate */ for (i = 0; i <= max; i++) { /* Frequency matches one of our calibration * piers, no need to interpolate, just use * that calibration pier */ if (pcinfo[i].freq == target) { idx_l = idx_r = i; goto done; } /* We found a calibration pier that's above * frequency, use this pier and the previous * one to interpolate */ if (target < pcinfo[i].freq) { idx_r = i; idx_l = idx_r - 1; goto done; } } done: *pcinfo_l = &pcinfo[idx_l]; *pcinfo_r = &pcinfo[idx_r]; return; } /* * Get the surrounding per-rate power calibration data * for a given frequency and interpolate between power * values to set max target power supported by hw for * each rate. */ static void ath5k_get_rate_pcal_data(struct ath5k_hw *ah, struct net80211_channel *channel, struct ath5k_rate_pcal_info *rates) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_rate_pcal_info *rpinfo; u8 idx_l, idx_r; u8 mode, max, i; u32 target = channel->center_freq; idx_l = 0; idx_r = 0; if (!(channel->hw_value & CHANNEL_OFDM)) { rpinfo = ee->ee_rate_tpwr_b; mode = AR5K_EEPROM_MODE_11B; } else if (channel->hw_value & CHANNEL_2GHZ) { rpinfo = ee->ee_rate_tpwr_g; mode = AR5K_EEPROM_MODE_11G; } else { rpinfo = ee->ee_rate_tpwr_a; mode = AR5K_EEPROM_MODE_11A; } max = ee->ee_rate_target_pwr_num[mode] - 1; /* Get the surrounding calibration * piers - same as above */ if (target < rpinfo[0].freq) { idx_l = idx_r = 0; goto done; } if (target > rpinfo[max].freq) { idx_l = idx_r = max; goto done; } for (i = 0; i <= max; i++) { if (rpinfo[i].freq == target) { idx_l = idx_r = i; goto done; } if (target < rpinfo[i].freq) { idx_r = i; idx_l = idx_r - 1; goto done; } } done: /* Now interpolate power value, based on the frequency */ rates->freq = target; rates->target_power_6to24 = ath5k_get_interpolated_value(target, rpinfo[idx_l].freq, rpinfo[idx_r].freq, rpinfo[idx_l].target_power_6to24, rpinfo[idx_r].target_power_6to24); rates->target_power_36 = ath5k_get_interpolated_value(target, rpinfo[idx_l].freq, rpinfo[idx_r].freq, rpinfo[idx_l].target_power_36, rpinfo[idx_r].target_power_36); rates->target_power_48 = ath5k_get_interpolated_value(target, rpinfo[idx_l].freq, rpinfo[idx_r].freq, rpinfo[idx_l].target_power_48, rpinfo[idx_r].target_power_48); rates->target_power_54 = ath5k_get_interpolated_value(target, rpinfo[idx_l].freq, rpinfo[idx_r].freq, rpinfo[idx_l].target_power_54, rpinfo[idx_r].target_power_54); } /* * Get the max edge power for this channel if * we have such data from EEPROM's Conformance Test * Limits (CTL), and limit max power if needed. * * FIXME: Only works for world regulatory domains */ static void ath5k_get_max_ctl_power(struct ath5k_hw *ah, struct net80211_channel *channel) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_edge_power *rep = ee->ee_ctl_pwr; u8 *ctl_val = ee->ee_ctl; s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4; s16 edge_pwr = 0; u8 rep_idx; u8 i, ctl_mode; u8 ctl_idx = 0xFF; u32 target = channel->center_freq; /* Find out a CTL for our mode that's not mapped * on a specific reg domain. * * TODO: Map our current reg domain to one of the 3 available * reg domain ids so that we can support more CTLs. */ switch (channel->hw_value & CHANNEL_MODES) { case CHANNEL_A: ctl_mode = AR5K_CTL_11A | AR5K_CTL_NO_REGDOMAIN; break; case CHANNEL_G: ctl_mode = AR5K_CTL_11G | AR5K_CTL_NO_REGDOMAIN; break; case CHANNEL_B: ctl_mode = AR5K_CTL_11B | AR5K_CTL_NO_REGDOMAIN; break; case CHANNEL_T: ctl_mode = AR5K_CTL_TURBO | AR5K_CTL_NO_REGDOMAIN; break; case CHANNEL_TG: ctl_mode = AR5K_CTL_TURBOG | AR5K_CTL_NO_REGDOMAIN; break; case CHANNEL_XR: /* Fall through */ default: return; } for (i = 0; i < ee->ee_ctls; i++) { if (ctl_val[i] == ctl_mode) { ctl_idx = i; break; } } /* If we have a CTL dataset available grab it and find the * edge power for our frequency */ if (ctl_idx == 0xFF) return; /* Edge powers are sorted by frequency from lower * to higher. Each CTL corresponds to 8 edge power * measurements. */ rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES; /* Don't do boundaries check because we * might have more that one bands defined * for this mode */ /* Get the edge power that's closer to our * frequency */ for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) { rep_idx += i; if (target <= rep[rep_idx].freq) edge_pwr = (s16) rep[rep_idx].edge; } if (edge_pwr) { ah->ah_txpower.txp_max_pwr = 4*min(edge_pwr, max_chan_pwr); } } /* * Power to PCDAC table functions */ /* * Fill Power to PCDAC table on RF5111 * * No further processing is needed for RF5111, the only thing we have to * do is fill the values below and above calibration range since eeprom data * may not cover the entire PCDAC table. */ static void ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min, s16 *table_max) { u8 *pcdac_out = ah->ah_txpower.txp_pd_table; u8 *pcdac_tmp = ah->ah_txpower.tmpL[0]; u8 pcdac_0, pcdac_n, pcdac_i, pwr_idx, i; s16 min_pwr, max_pwr; /* Get table boundaries */ min_pwr = table_min[0]; pcdac_0 = pcdac_tmp[0]; max_pwr = table_max[0]; pcdac_n = pcdac_tmp[table_max[0] - table_min[0]]; /* Extrapolate below minimum using pcdac_0 */ pcdac_i = 0; for (i = 0; i < min_pwr; i++) pcdac_out[pcdac_i++] = pcdac_0; /* Copy values from pcdac_tmp */ pwr_idx = min_pwr; for (i = 0 ; pwr_idx <= max_pwr && pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) { pcdac_out[pcdac_i++] = pcdac_tmp[i]; pwr_idx++; } /* Extrapolate above maximum */ while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE) pcdac_out[pcdac_i++] = pcdac_n; } /* * Combine available XPD Curves and fill Linear Power to PCDAC table * on RF5112 * * RFX112 can have up to 2 curves (one for low txpower range and one for * higher txpower range). We need to put them both on pcdac_out and place * them in the correct location. In case we only have one curve available * just fit it on pcdac_out (it's supposed to cover the entire range of * available pwr levels since it's always the higher power curve). Extrapolate * below and above final table if needed. */ static void ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, s16 *table_max, u8 pdcurves) { u8 *pcdac_out = ah->ah_txpower.txp_pd_table; u8 *pcdac_low_pwr; u8 *pcdac_high_pwr; u8 *pcdac_tmp; u8 pwr; s16 max_pwr_idx; s16 min_pwr_idx; s16 mid_pwr_idx = 0; /* Edge flag turs on the 7nth bit on the PCDAC * to delcare the higher power curve (force values * to be greater than 64). If we only have one curve * we don't need to set this, if we have 2 curves and * fill the table backwards this can also be used to * switch from higher power curve to lower power curve */ u8 edge_flag; int i; /* When we have only one curve available * that's the higher power curve. If we have * two curves the first is the high power curve * and the next is the low power curve. */ if (pdcurves > 1) { pcdac_low_pwr = ah->ah_txpower.tmpL[1]; pcdac_high_pwr = ah->ah_txpower.tmpL[0]; mid_pwr_idx = table_max[1] - table_min[1] - 1; max_pwr_idx = (table_max[0] - table_min[0]) / 2; /* If table size goes beyond 31.5dB, keep the * upper 31.5dB range when setting tx power. * Note: 126 = 31.5 dB in quarter dB steps */ if (table_max[0] - table_min[1] > 126) min_pwr_idx = table_max[0] - 126; else min_pwr_idx = table_min[1]; /* Since we fill table backwards * start from high power curve */ pcdac_tmp = pcdac_high_pwr; edge_flag = 0x40; } else { pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */ pcdac_high_pwr = ah->ah_txpower.tmpL[0]; min_pwr_idx = table_min[0]; max_pwr_idx = (table_max[0] - table_min[0]) / 2; pcdac_tmp = pcdac_high_pwr; edge_flag = 0; } /* This is used when setting tx power*/ ah->ah_txpower.txp_min_idx = min_pwr_idx/2; /* Fill Power to PCDAC table backwards */ pwr = max_pwr_idx; for (i = 63; i >= 0; i--) { /* Entering lower power range, reset * edge flag and set pcdac_tmp to lower * power curve.*/ if (edge_flag == 0x40 && (2*pwr <= (table_max[1] - table_min[0]) || pwr == 0)) { edge_flag = 0x00; pcdac_tmp = pcdac_low_pwr; pwr = mid_pwr_idx/2; } /* Don't go below 1, extrapolate below if we have * already swithced to the lower power curve -or * we only have one curve and edge_flag is zero * anyway */ if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) { while (i >= 0) { pcdac_out[i] = pcdac_out[i + 1]; i--; } break; } pcdac_out[i] = pcdac_tmp[pwr] | edge_flag; /* Extrapolate above if pcdac is greater than * 126 -this can happen because we OR pcdac_out * value with edge_flag on high power curve */ if (pcdac_out[i] > 126) pcdac_out[i] = 126; /* Decrease by a 0.5dB step */ pwr--; } } /* Write PCDAC values on hw */ static void ath5k_setup_pcdac_table(struct ath5k_hw *ah) { u8 *pcdac_out = ah->ah_txpower.txp_pd_table; int i; /* * Write TX power values */ for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) { ath5k_hw_reg_write(ah, (((pcdac_out[2*i + 0] << 8 | 0xff) & 0xffff) << 0) | (((pcdac_out[2*i + 1] << 8 | 0xff) & 0xffff) << 16), AR5K_PHY_PCDAC_TXPOWER(i)); } } /* * Power to PDADC table functions */ /* * Set the gain boundaries and create final Power to PDADC table * * We can have up to 4 pd curves, we need to do a simmilar process * as we do for RF5112. This time we don't have an edge_flag but we * set the gain boundaries on a separate register. */ static void ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah, s16 *pwr_min, s16 *pwr_max, u8 pdcurves) { u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS]; u8 *pdadc_out = ah->ah_txpower.txp_pd_table; u8 *pdadc_tmp; s16 pdadc_0; u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size; u8 pd_gain_overlap; /* Note: Register value is initialized on initvals * there is no feedback from hw. * XXX: What about pd_gain_overlap from EEPROM ? */ pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) & AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP; /* Create final PDADC table */ for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) { pdadc_tmp = ah->ah_txpower.tmpL[pdg]; if (pdg == pdcurves - 1) /* 2 dB boundary stretch for last * (higher power) curve */ gain_boundaries[pdg] = pwr_max[pdg] + 4; else /* Set gain boundary in the middle * between this curve and the next one */ gain_boundaries[pdg] = (pwr_max[pdg] + pwr_min[pdg + 1]) / 2; /* Sanity check in case our 2 db stretch got out of * range. */ if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER) gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER; /* For the first curve (lower power) * start from 0 dB */ if (pdg == 0) pdadc_0 = 0; else /* For the other curves use the gain overlap */ pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) - pd_gain_overlap; /* Force each power step to be at least 0.5 dB */ if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1) pwr_step = pdadc_tmp[1] - pdadc_tmp[0]; else pwr_step = 1; /* If pdadc_0 is negative, we need to extrapolate * below this pdgain by a number of pwr_steps */ while ((pdadc_0 < 0) && (pdadc_i < 128)) { s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step; pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp; pdadc_0++; } /* Set last pwr level, using gain boundaries */ pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg]; /* Limit it to be inside pwr range */ table_size = pwr_max[pdg] - pwr_min[pdg]; max_idx = (pdadc_n < table_size) ? pdadc_n : table_size; /* Fill pdadc_out table */ while (pdadc_0 < max_idx) pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++]; /* Need to extrapolate above this pdgain? */ if (pdadc_n <= max_idx) continue; /* Force each power step to be at least 0.5 dB */ if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1) pwr_step = pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]; else pwr_step = 1; /* Extrapolate above */ while ((pdadc_0 < (s16) pdadc_n) && (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) { s16 tmp = pdadc_tmp[table_size - 1] + (pdadc_0 - max_idx) * pwr_step; pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp; pdadc_0++; } } while (pdg < AR5K_EEPROM_N_PD_GAINS) { gain_boundaries[pdg] = gain_boundaries[pdg - 1]; pdg++; } while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) { pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1]; pdadc_i++; } /* Set gain boundaries */ ath5k_hw_reg_write(ah, AR5K_REG_SM(pd_gain_overlap, AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) | AR5K_REG_SM(gain_boundaries[0], AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) | AR5K_REG_SM(gain_boundaries[1], AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) | AR5K_REG_SM(gain_boundaries[2], AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) | AR5K_REG_SM(gain_boundaries[3], AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4), AR5K_PHY_TPC_RG5); /* Used for setting rate power table */ ah->ah_txpower.txp_min_idx = pwr_min[0]; } /* Write PDADC values on hw */ static void ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 pdcurves, u8 *pdg_to_idx) { u8 *pdadc_out = ah->ah_txpower.txp_pd_table; u32 reg; u8 i; /* Select the right pdgain curves */ /* Clear current settings */ reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1); reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 | AR5K_PHY_TPC_RG1_PDGAIN_2 | AR5K_PHY_TPC_RG1_PDGAIN_3 | AR5K_PHY_TPC_RG1_NUM_PD_GAIN); /* * Use pd_gains curve from eeprom * * This overrides the default setting from initvals * in case some vendors (e.g. Zcomax) don't use the default * curves. If we don't honor their settings we 'll get a * 5dB (1 * gain overlap ?) drop. */ reg |= AR5K_REG_SM(pdcurves, AR5K_PHY_TPC_RG1_NUM_PD_GAIN); switch (pdcurves) { case 3: reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3); /* Fall through */ case 2: reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2); /* Fall through */ case 1: reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1); break; } ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1); /* * Write TX power values */ for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) { ath5k_hw_reg_write(ah, ((pdadc_out[4*i + 0] & 0xff) << 0) | ((pdadc_out[4*i + 1] & 0xff) << 8) | ((pdadc_out[4*i + 2] & 0xff) << 16) | ((pdadc_out[4*i + 3] & 0xff) << 24), AR5K_PHY_PDADC_TXPOWER(i)); } } /* * Common code for PCDAC/PDADC tables */ /* * This is the main function that uses all of the above * to set PCDAC/PDADC table on hw for the current channel. * This table is used for tx power calibration on the basband, * without it we get weird tx power levels and in some cases * distorted spectral mask */ static int ath5k_setup_channel_powertable(struct ath5k_hw *ah, struct net80211_channel *channel, u8 ee_mode, u8 type) { struct ath5k_pdgain_info *pdg_L, *pdg_R; struct ath5k_chan_pcal_info *pcinfo_L; struct ath5k_chan_pcal_info *pcinfo_R; struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode]; s16 table_min[AR5K_EEPROM_N_PD_GAINS]; s16 table_max[AR5K_EEPROM_N_PD_GAINS]; u8 *tmpL; u8 *tmpR; u32 target = channel->center_freq; int pdg, i; /* Get surounding freq piers for this channel */ ath5k_get_chan_pcal_surrounding_piers(ah, channel, &pcinfo_L, &pcinfo_R); /* Loop over pd gain curves on * surounding freq piers by index */ for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) { /* Fill curves in reverse order * from lower power (max gain) * to higher power. Use curve -> idx * backmaping we did on eeprom init */ u8 idx = pdg_curve_to_idx[pdg]; /* Grab the needed curves by index */ pdg_L = &pcinfo_L->pd_curves[idx]; pdg_R = &pcinfo_R->pd_curves[idx]; /* Initialize the temp tables */ tmpL = ah->ah_txpower.tmpL[pdg]; tmpR = ah->ah_txpower.tmpR[pdg]; /* Set curve's x boundaries and create * curves so that they cover the same * range (if we don't do that one table * will have values on some range and the * other one won't have any so interpolation * will fail) */ table_min[pdg] = min(pdg_L->pd_pwr[0], pdg_R->pd_pwr[0]) / 2; table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1], pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2; /* Now create the curves on surrounding channels * and interpolate if needed to get the final * curve for this gain on this channel */ switch (type) { case AR5K_PWRTABLE_LINEAR_PCDAC: /* Override min/max so that we don't loose * accuracy (don't divide by 2) */ table_min[pdg] = min(pdg_L->pd_pwr[0], pdg_R->pd_pwr[0]); table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1], pdg_R->pd_pwr[pdg_R->pd_points - 1]); /* Override minimum so that we don't get * out of bounds while extrapolating * below. Don't do this when we have 2 * curves and we are on the high power curve * because table_min is ok in this case */ if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) { table_min[pdg] = ath5k_get_linear_pcdac_min(pdg_L->pd_step, pdg_R->pd_step, pdg_L->pd_pwr, pdg_R->pd_pwr); /* Don't go too low because we will * miss the upper part of the curve. * Note: 126 = 31.5dB (max power supported) * in 0.25dB units */ if (table_max[pdg] - table_min[pdg] > 126) table_min[pdg] = table_max[pdg] - 126; } /* Fall through */ case AR5K_PWRTABLE_PWR_TO_PCDAC: case AR5K_PWRTABLE_PWR_TO_PDADC: ath5k_create_power_curve(table_min[pdg], table_max[pdg], pdg_L->pd_pwr, pdg_L->pd_step, pdg_L->pd_points, tmpL, type); /* We are in a calibration * pier, no need to interpolate * between freq piers */ if (pcinfo_L == pcinfo_R) continue; ath5k_create_power_curve(table_min[pdg], table_max[pdg], pdg_R->pd_pwr, pdg_R->pd_step, pdg_R->pd_points, tmpR, type); break; default: return -EINVAL; } /* Interpolate between curves * of surounding freq piers to * get the final curve for this * pd gain. Re-use tmpL for interpolation * output */ for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) && (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) { tmpL[i] = (u8) ath5k_get_interpolated_value(target, (s16) pcinfo_L->freq, (s16) pcinfo_R->freq, (s16) tmpL[i], (s16) tmpR[i]); } } /* Now we have a set of curves for this * channel on tmpL (x range is table_max - table_min * and y values are tmpL[pdg][]) sorted in the same * order as EEPROM (because we've used the backmaping). * So for RF5112 it's from higher power to lower power * and for RF2413 it's from lower power to higher power. * For RF5111 we only have one curve. */ /* Fill min and max power levels for this * channel by interpolating the values on * surounding channels to complete the dataset */ ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target, (s16) pcinfo_L->freq, (s16) pcinfo_R->freq, pcinfo_L->min_pwr, pcinfo_R->min_pwr); ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target, (s16) pcinfo_L->freq, (s16) pcinfo_R->freq, pcinfo_L->max_pwr, pcinfo_R->max_pwr); /* We are ready to go, fill PCDAC/PDADC * table and write settings on hardware */ switch (type) { case AR5K_PWRTABLE_LINEAR_PCDAC: /* For RF5112 we can have one or two curves * and each curve covers a certain power lvl * range so we need to do some more processing */ ath5k_combine_linear_pcdac_curves(ah, table_min, table_max, ee->ee_pd_gains[ee_mode]); /* Set txp.offset so that we can * match max power value with max * table index */ ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2); /* Write settings on hw */ ath5k_setup_pcdac_table(ah); break; case AR5K_PWRTABLE_PWR_TO_PCDAC: /* We are done for RF5111 since it has only * one curve, just fit the curve on the table */ ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max); /* No rate powertable adjustment for RF5111 */ ah->ah_txpower.txp_min_idx = 0; ah->ah_txpower.txp_offset = 0; /* Write settings on hw */ ath5k_setup_pcdac_table(ah); break; case AR5K_PWRTABLE_PWR_TO_PDADC: /* Set PDADC boundaries and fill * final PDADC table */ ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max, ee->ee_pd_gains[ee_mode]); /* Write settings on hw */ ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx); /* Set txp.offset, note that table_min * can be negative */ ah->ah_txpower.txp_offset = table_min[0]; break; default: return -EINVAL; } return 0; } /* * Per-rate tx power setting * * This is the code that sets the desired tx power (below * maximum) on hw for each rate (we also have TPC that sets * power per packet). We do that by providing an index on the * PCDAC/PDADC table we set up. */ /* * Set rate power table * * For now we only limit txpower based on maximum tx power * supported by hw (what's inside rate_info). We need to limit * this even more, based on regulatory domain etc. * * Rate power table contains indices to PCDAC/PDADC table (0.5dB steps) * and is indexed as follows: * rates[0] - rates[7] -> OFDM rates * rates[8] - rates[14] -> CCK rates * rates[15] -> XR rates (they all have the same power) */ static void ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, struct ath5k_rate_pcal_info *rate_info, u8 ee_mode) { unsigned int i; u16 *rates; /* max_pwr is power level we got from driver/user in 0.5dB * units, switch to 0.25dB units so we can compare */ max_pwr *= 2; max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2; /* apply rate limits */ rates = ah->ah_txpower.txp_rates_power_table; /* OFDM rates 6 to 24Mb/s */ for (i = 0; i < 5; i++) rates[i] = min(max_pwr, rate_info->target_power_6to24); /* Rest OFDM rates */ rates[5] = min(rates[0], rate_info->target_power_36); rates[6] = min(rates[0], rate_info->target_power_48); rates[7] = min(rates[0], rate_info->target_power_54); /* CCK rates */ /* 1L */ rates[8] = min(rates[0], rate_info->target_power_6to24); /* 2L */ rates[9] = min(rates[0], rate_info->target_power_36); /* 2S */ rates[10] = min(rates[0], rate_info->target_power_36); /* 5L */ rates[11] = min(rates[0], rate_info->target_power_48); /* 5S */ rates[12] = min(rates[0], rate_info->target_power_48); /* 11L */ rates[13] = min(rates[0], rate_info->target_power_54); /* 11S */ rates[14] = min(rates[0], rate_info->target_power_54); /* XR rates */ rates[15] = min(rates[0], rate_info->target_power_6to24); /* CCK rates have different peak to average ratio * so we have to tweak their power so that gainf * correction works ok. For this we use OFDM to * CCK delta from eeprom */ if ((ee_mode == AR5K_EEPROM_MODE_11G) && (ah->ah_phy_revision < AR5K_SREV_PHY_5212A)) for (i = 8; i <= 15; i++) rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta; ah->ah_txpower.txp_min_pwr = rates[7]; ah->ah_txpower.txp_max_pwr = rates[0]; ah->ah_txpower.txp_ofdm = rates[7]; } /* * Set transmition power */ int ath5k_hw_txpower(struct ath5k_hw *ah, struct net80211_channel *channel, u8 ee_mode, u8 txpower) { struct ath5k_rate_pcal_info rate_info; u8 type; int ret; if (txpower > AR5K_TUNE_MAX_TXPOWER) { DBG("ath5k: invalid tx power %d\n", txpower); return -EINVAL; } if (txpower == 0) txpower = AR5K_TUNE_DEFAULT_TXPOWER; /* Reset TX power values */ memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; ah->ah_txpower.txp_min_pwr = 0; ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER; /* Initialize TX power table */ switch (ah->ah_radio) { case AR5K_RF5111: type = AR5K_PWRTABLE_PWR_TO_PCDAC; break; case AR5K_RF5112: type = AR5K_PWRTABLE_LINEAR_PCDAC; break; case AR5K_RF2413: case AR5K_RF5413: case AR5K_RF2316: case AR5K_RF2317: case AR5K_RF2425: type = AR5K_PWRTABLE_PWR_TO_PDADC; break; default: return -EINVAL; } /* FIXME: Only on channel/mode change */ ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type); if (ret) return ret; /* Limit max power if we have a CTL available */ ath5k_get_max_ctl_power(ah, channel); /* FIXME: Tx power limit for this regdomain * XXX: Mac80211/CRDA will do that anyway ? */ /* FIXME: Antenna reduction stuff */ /* FIXME: Limit power on turbo modes */ /* FIXME: TPC scale reduction */ /* Get surounding channels for per-rate power table * calibration */ ath5k_get_rate_pcal_data(ah, channel, &rate_info); /* Setup rate power table */ ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode); /* Write rate power table on hw */ ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) | AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) | AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1); ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(7, 24) | AR5K_TXPOWER_OFDM(6, 16) | AR5K_TXPOWER_OFDM(5, 8) | AR5K_TXPOWER_OFDM(4, 0), AR5K_PHY_TXPOWER_RATE2); ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(10, 24) | AR5K_TXPOWER_CCK(9, 16) | AR5K_TXPOWER_CCK(15, 8) | AR5K_TXPOWER_CCK(8, 0), AR5K_PHY_TXPOWER_RATE3); ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(14, 24) | AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) | AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4); /* FIXME: TPC support */ if (ah->ah_txpower.txp_tpc) { ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE | AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX); ath5k_hw_reg_write(ah, AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) | AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) | AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP), AR5K_TPC); } else { ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX | AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX); } return 0; } int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 mode, u8 txpower) { struct net80211_channel *channel = ah->ah_current_channel; DBG2("ath5k: changing txpower to %d\n", txpower); return ath5k_hw_txpower(ah, channel, mode, txpower); } #undef _ATH5K_PHY debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k_eeprom.c0000664000000000000000000013457012524662415022764 0ustar /* * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2006-2009 Nick Kossifidis * Copyright (c) 2008-2009 Felix Fietkau * * Lightly modified for gPXE, July 2009, by Joshua Oreman . * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ FILE_LICENCE ( MIT ); /*************************************\ * EEPROM access functions and helpers * \*************************************/ #include #include #include "ath5k.h" #include "reg.h" #include "base.h" /* * Read from eeprom */ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) { u32 status, timeout; /* * Initialize EEPROM access */ if (ah->ah_version == AR5K_AR5210) { AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE); (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset)); } else { ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE); AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD, AR5K_EEPROM_CMD_READ); } for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) { status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS); if (status & AR5K_EEPROM_STAT_RDDONE) { if (status & AR5K_EEPROM_STAT_RDERR) return -EIO; *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) & 0xffff); return 0; } udelay(15); } return -ETIMEDOUT; } /* * Translate binary channel representation in EEPROM to frequency */ static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, unsigned int mode) { u16 val; if (bin == AR5K_EEPROM_CHANNEL_DIS) return bin; if (mode == AR5K_EEPROM_MODE_11A) { if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) val = (5 * bin) + 4800; else val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 : (bin * 10) + 5100; } else { if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) val = bin + 2300; else val = bin + 2400; } return val; } /* * Initialize eeprom & capabilities structs */ static int ath5k_eeprom_init_header(struct ath5k_hw *ah) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; int ret; u16 val; /* * Read values from EEPROM and store them in the capability structure */ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic); AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect); AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain); AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version); AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header); /* Return if we have an old EEPROM */ if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) return 0; AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), ee_ant_gain); if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0); AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1); /* XXX: Don't know which versions include these two */ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2); if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3); if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) { AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4); AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5); AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6); } } if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) { AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val); ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7; ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7; AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val); ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7; ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7; } return 0; } /* * Read antenna infos from eeprom */ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, unsigned int mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; u32 o = *offset; u16 val; int ret, i = 0; AR5K_EEPROM_READ(o++, val); ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; ee->ee_atn_tx_rx[mode] = (val >> 2) & 0x3f; ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; AR5K_EEPROM_READ(o++, val); ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; ee->ee_ant_control[mode][i++] = val & 0x3f; AR5K_EEPROM_READ(o++, val); ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f; ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f; ee->ee_ant_control[mode][i] = (val << 2) & 0x3f; AR5K_EEPROM_READ(o++, val); ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3; ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f; ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f; ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; AR5K_EEPROM_READ(o++, val); ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; ee->ee_ant_control[mode][i++] = val & 0x3f; /* Get antenna modes */ ah->ah_antenna[mode][0] = (ee->ee_ant_control[mode][0] << 4); ah->ah_antenna[mode][AR5K_ANT_FIXED_A] = ee->ee_ant_control[mode][1] | (ee->ee_ant_control[mode][2] << 6) | (ee->ee_ant_control[mode][3] << 12) | (ee->ee_ant_control[mode][4] << 18) | (ee->ee_ant_control[mode][5] << 24); ah->ah_antenna[mode][AR5K_ANT_FIXED_B] = ee->ee_ant_control[mode][6] | (ee->ee_ant_control[mode][7] << 6) | (ee->ee_ant_control[mode][8] << 12) | (ee->ee_ant_control[mode][9] << 18) | (ee->ee_ant_control[mode][10] << 24); /* return new offset */ *offset = o; return 0; } /* * Read supported modes and some mode-specific calibration data * from eeprom */ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, unsigned int mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; u32 o = *offset; u16 val; int ret; ee->ee_n_piers[mode] = 0; AR5K_EEPROM_READ(o++, val); ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); switch(mode) { case AR5K_EEPROM_MODE_11A: ee->ee_ob[mode][3] = (val >> 5) & 0x7; ee->ee_db[mode][3] = (val >> 2) & 0x7; ee->ee_ob[mode][2] = (val << 1) & 0x7; AR5K_EEPROM_READ(o++, val); ee->ee_ob[mode][2] |= (val >> 15) & 0x1; ee->ee_db[mode][2] = (val >> 12) & 0x7; ee->ee_ob[mode][1] = (val >> 9) & 0x7; ee->ee_db[mode][1] = (val >> 6) & 0x7; ee->ee_ob[mode][0] = (val >> 3) & 0x7; ee->ee_db[mode][0] = val & 0x7; break; case AR5K_EEPROM_MODE_11G: case AR5K_EEPROM_MODE_11B: ee->ee_ob[mode][1] = (val >> 4) & 0x7; ee->ee_db[mode][1] = val & 0x7; break; } AR5K_EEPROM_READ(o++, val); ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff; ee->ee_thr_62[mode] = val & 0xff; if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28; AR5K_EEPROM_READ(o++, val); ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff; ee->ee_tx_frm2xpa_enable[mode] = val & 0xff; AR5K_EEPROM_READ(o++, val); ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff; if ((val & 0xff) & 0x80) ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1); else ee->ee_noise_floor_thr[mode] = val & 0xff; if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) ee->ee_noise_floor_thr[mode] = mode == AR5K_EEPROM_MODE_11A ? -54 : -1; AR5K_EEPROM_READ(o++, val); ee->ee_xlna_gain[mode] = (val >> 5) & 0xff; ee->ee_x_gain[mode] = (val >> 1) & 0xf; ee->ee_xpd[mode] = val & 0x1; if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { AR5K_EEPROM_READ(o++, val); ee->ee_false_detect[mode] = (val >> 6) & 0x7f; if (mode == AR5K_EEPROM_MODE_11A) ee->ee_xr_power[mode] = val & 0x3f; else { ee->ee_ob[mode][0] = val & 0x7; ee->ee_db[mode][0] = (val >> 3) & 0x7; } } if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) { ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN; ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA; } else { ee->ee_i_gain[mode] = (val >> 13) & 0x7; AR5K_EEPROM_READ(o++, val); ee->ee_i_gain[mode] |= (val << 3) & 0x38; if (mode == AR5K_EEPROM_MODE_11G) { ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff; if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6) ee->ee_scaled_cck_delta = (val >> 11) & 0x1f; } } if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && mode == AR5K_EEPROM_MODE_11A) { ee->ee_i_cal[mode] = (val >> 8) & 0x3f; ee->ee_q_cal[mode] = (val >> 3) & 0x1f; } if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0) goto done; /* Note: >= v5 have bg freq piers on another location * so these freq piers are ignored for >= v5 (should be 0xff * anyway) */ switch(mode) { case AR5K_EEPROM_MODE_11A: if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1) break; AR5K_EEPROM_READ(o++, val); ee->ee_margin_tx_rx[mode] = val & 0x3f; break; case AR5K_EEPROM_MODE_11B: AR5K_EEPROM_READ(o++, val); ee->ee_pwr_cal_b[0].freq = ath5k_eeprom_bin2freq(ee, val & 0xff, mode); if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS) ee->ee_n_piers[mode]++; ee->ee_pwr_cal_b[1].freq = ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode); if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS) ee->ee_n_piers[mode]++; AR5K_EEPROM_READ(o++, val); ee->ee_pwr_cal_b[2].freq = ath5k_eeprom_bin2freq(ee, val & 0xff, mode); if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS) ee->ee_n_piers[mode]++; if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; break; case AR5K_EEPROM_MODE_11G: AR5K_EEPROM_READ(o++, val); ee->ee_pwr_cal_g[0].freq = ath5k_eeprom_bin2freq(ee, val & 0xff, mode); if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS) ee->ee_n_piers[mode]++; ee->ee_pwr_cal_g[1].freq = ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode); if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS) ee->ee_n_piers[mode]++; AR5K_EEPROM_READ(o++, val); ee->ee_turbo_max_power[mode] = val & 0x7f; ee->ee_xr_power[mode] = (val >> 7) & 0x3f; AR5K_EEPROM_READ(o++, val); ee->ee_pwr_cal_g[2].freq = ath5k_eeprom_bin2freq(ee, val & 0xff, mode); if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS) ee->ee_n_piers[mode]++; if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; AR5K_EEPROM_READ(o++, val); ee->ee_i_cal[mode] = (val >> 8) & 0x3f; ee->ee_q_cal[mode] = (val >> 3) & 0x1f; if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { AR5K_EEPROM_READ(o++, val); ee->ee_cck_ofdm_gain_delta = val & 0xff; } break; } done: /* return new offset */ *offset = o; return 0; } /* * Read turbo mode information on newer EEPROM versions */ static int ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah, u32 *offset, unsigned int mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; u32 o = *offset; u16 val; int ret; if (ee->ee_version < AR5K_EEPROM_VERSION_5_0) return 0; switch (mode){ case AR5K_EEPROM_MODE_11A: ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f; ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7; AR5K_EEPROM_READ(o++, val); ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3; ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f; ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f; AR5K_EEPROM_READ(o++, val); ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7; ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff; if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2) ee->ee_pd_gain_overlap = (val >> 9) & 0xf; break; case AR5K_EEPROM_MODE_11G: ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f; ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7; AR5K_EEPROM_READ(o++, val); ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1; ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f; ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f; AR5K_EEPROM_READ(o++, val); ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5; ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff; break; } /* return new offset */ *offset = o; return 0; } /* Read mode-specific data (except power calibration data) */ static int ath5k_eeprom_init_modes(struct ath5k_hw *ah) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; u32 mode_offset[3]; unsigned int mode; u32 offset; int ret; /* * Get values for all modes */ mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version); mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version); mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version); ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header); for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) { offset = mode_offset[mode]; ret = ath5k_eeprom_read_ants(ah, &offset, mode); if (ret) return ret; ret = ath5k_eeprom_read_modes(ah, &offset, mode); if (ret) return ret; ret = ath5k_eeprom_read_turbo_modes(ah, &offset, mode); if (ret) return ret; } /* override for older eeprom versions for better performance */ if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) { ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15; ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28; ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28; } return 0; } /* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff * frequency mask) */ static inline int ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, struct ath5k_chan_pcal_info *pc, unsigned int mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; int o = *offset; int i = 0; u8 freq1, freq2; int ret; u16 val; ee->ee_n_piers[mode] = 0; while(i < max) { AR5K_EEPROM_READ(o++, val); freq1 = val & 0xff; if (!freq1) break; pc[i++].freq = ath5k_eeprom_bin2freq(ee, freq1, mode); ee->ee_n_piers[mode]++; freq2 = (val >> 8) & 0xff; if (!freq2) break; pc[i++].freq = ath5k_eeprom_bin2freq(ee, freq2, mode); ee->ee_n_piers[mode]++; } /* return new offset */ *offset = o; return 0; } /* Read frequency piers for 802.11a */ static int ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a; int i, ret; u16 val; u8 mask; if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) { ath5k_eeprom_read_freq_list(ah, &offset, AR5K_EEPROM_N_5GHZ_CHAN, pcal, AR5K_EEPROM_MODE_11A); } else { mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version); AR5K_EEPROM_READ(offset++, val); pcal[0].freq = (val >> 9) & mask; pcal[1].freq = (val >> 2) & mask; pcal[2].freq = (val << 5) & mask; AR5K_EEPROM_READ(offset++, val); pcal[2].freq |= (val >> 11) & 0x1f; pcal[3].freq = (val >> 4) & mask; pcal[4].freq = (val << 3) & mask; AR5K_EEPROM_READ(offset++, val); pcal[4].freq |= (val >> 13) & 0x7; pcal[5].freq = (val >> 6) & mask; pcal[6].freq = (val << 1) & mask; AR5K_EEPROM_READ(offset++, val); pcal[6].freq |= (val >> 15) & 0x1; pcal[7].freq = (val >> 8) & mask; pcal[8].freq = (val >> 1) & mask; pcal[9].freq = (val << 6) & mask; AR5K_EEPROM_READ(offset++, val); pcal[9].freq |= (val >> 10) & 0x3f; /* Fixed number of piers */ ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10; for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) { pcal[i].freq = ath5k_eeprom_bin2freq(ee, pcal[i].freq, AR5K_EEPROM_MODE_11A); } } return 0; } /* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */ static inline int ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info *pcal; switch(mode) { case AR5K_EEPROM_MODE_11B: pcal = ee->ee_pwr_cal_b; break; case AR5K_EEPROM_MODE_11G: pcal = ee->ee_pwr_cal_g; break; default: return -EINVAL; } ath5k_eeprom_read_freq_list(ah, &offset, AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal, mode); return 0; } /* * Read power calibration for RF5111 chips * * For RF5111 we have an XPD -eXternal Power Detector- curve * for each calibrated channel. Each curve has 0,5dB Power steps * on x axis and PCDAC steps (offsets) on y axis and looks like an * exponential function. To recreate the curve we read 11 points * here and interpolate later. */ /* Used to match PCDAC steps with power values on RF5111 chips * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC * steps that match with the power values we read from eeprom. On * older eeprom versions (< 3.2) these steps are equaly spaced at * 10% of the pcdac curve -until the curve reaches it's maximum- * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) * these 11 steps are spaced in a different way. This function returns * the pcdac steps based on eeprom version and curve min/max so that we * can have pcdac/pwr points. */ static inline void ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) { static const u16 intercepts3[] = { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 }; static const u16 intercepts3_2[] = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; const u16 *ip; unsigned i; if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2) ip = intercepts3_2; else ip = intercepts3; for (i = 0; i < ARRAY_SIZE(intercepts3); i++) vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; } /* Convert RF5111 specific data to generic raw data * used by interpolation code */ static int ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, struct ath5k_chan_pcal_info *chinfo) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info_rf5111 *pcinfo; struct ath5k_pdgain_info *pd; u8 pier, point, idx; u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; /* Fill raw data for each calibration pier */ for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { pcinfo = &chinfo[pier].rf5111_info; /* Allocate pd_curves for this cal pier */ chinfo[pier].pd_curves = calloc(AR5K_EEPROM_N_PD_CURVES, sizeof(struct ath5k_pdgain_info)); if (!chinfo[pier].pd_curves) return -ENOMEM; /* Only one curve for RF5111 * find out which one and place * in in pd_curves. * Note: ee_x_gain is reversed here */ for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) { if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) { pdgain_idx[0] = idx; break; } } ee->ee_pd_gains[mode] = 1; pd = &chinfo[pier].pd_curves[idx]; pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111; /* Allocate pd points for this curve */ pd->pd_step = calloc(AR5K_EEPROM_N_PWR_POINTS_5111, sizeof(u8)); if (!pd->pd_step) return -ENOMEM; pd->pd_pwr = calloc(AR5K_EEPROM_N_PWR_POINTS_5111, sizeof(s16)); if (!pd->pd_pwr) return -ENOMEM; /* Fill raw dataset * (convert power to 0.25dB units * for RF5112 combatibility) */ for (point = 0; point < pd->pd_points; point++) { /* Absolute values */ pd->pd_pwr[point] = 2 * pcinfo->pwr[point]; /* Already sorted */ pd->pd_step[point] = pcinfo->pcdac[point]; } /* Set min/max pwr */ chinfo[pier].min_pwr = pd->pd_pwr[0]; chinfo[pier].max_pwr = pd->pd_pwr[10]; } return 0; } /* Parse EEPROM data */ static int ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info *pcal; int offset, ret; int i; u16 val; offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); switch(mode) { case AR5K_EEPROM_MODE_11A: if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) return 0; ret = ath5k_eeprom_init_11a_pcal_freq(ah, offset + AR5K_EEPROM_GROUP1_OFFSET); if (ret < 0) return ret; offset += AR5K_EEPROM_GROUP2_OFFSET; pcal = ee->ee_pwr_cal_a; break; case AR5K_EEPROM_MODE_11B: if (!AR5K_EEPROM_HDR_11B(ee->ee_header) && !AR5K_EEPROM_HDR_11G(ee->ee_header)) return 0; pcal = ee->ee_pwr_cal_b; offset += AR5K_EEPROM_GROUP3_OFFSET; /* fixed piers */ pcal[0].freq = 2412; pcal[1].freq = 2447; pcal[2].freq = 2484; ee->ee_n_piers[mode] = 3; break; case AR5K_EEPROM_MODE_11G: if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) return 0; pcal = ee->ee_pwr_cal_g; offset += AR5K_EEPROM_GROUP4_OFFSET; /* fixed piers */ pcal[0].freq = 2312; pcal[1].freq = 2412; pcal[2].freq = 2484; ee->ee_n_piers[mode] = 3; break; default: return -EINVAL; } for (i = 0; i < ee->ee_n_piers[mode]; i++) { struct ath5k_chan_pcal_info_rf5111 *cdata = &pcal[i].rf5111_info; AR5K_EEPROM_READ(offset++, val); cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M); cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M); cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M); AR5K_EEPROM_READ(offset++, val); cdata->pwr[0] |= ((val >> 14) & 0x3); cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M); cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M); cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M); AR5K_EEPROM_READ(offset++, val); cdata->pwr[3] |= ((val >> 12) & 0xf); cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M); cdata->pwr[5] = (val & AR5K_EEPROM_POWER_M); AR5K_EEPROM_READ(offset++, val); cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M); cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M); cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M); AR5K_EEPROM_READ(offset++, val); cdata->pwr[8] |= ((val >> 14) & 0x3); cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M); cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M); ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min, cdata->pcdac_max, cdata->pcdac); } return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal); } /* * Read power calibration for RF5112 chips * * For RF5112 we have 4 XPD -eXternal Power Detector- curves * for each calibrated channel on 0, -6, -12 and -18dbm but we only * use the higher (3) and the lower (0) curves. Each curve has 0.5dB * power steps on x axis and PCDAC steps on y axis and looks like a * linear function. To recreate the curve and pass the power values * on hw, we read 4 points for xpd 0 (lower gain -> max power) * and 3 points for xpd 3 (higher gain -> lower power) here and * interpolate later. * * Note: Many vendors just use xpd 0 so xpd 3 is zeroed. */ /* Convert RF5112 specific data to generic raw data * used by interpolation code */ static int ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, struct ath5k_chan_pcal_info *chinfo) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info_rf5112 *pcinfo; u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; unsigned int pier, pdg, point; /* Fill raw data for each calibration pier */ for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { pcinfo = &chinfo[pier].rf5112_info; /* Allocate pd_curves for this cal pier */ chinfo[pier].pd_curves = calloc(AR5K_EEPROM_N_PD_CURVES, sizeof(struct ath5k_pdgain_info)); if (!chinfo[pier].pd_curves) return -ENOMEM; /* Fill pd_curves */ for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { u8 idx = pdgain_idx[pdg]; struct ath5k_pdgain_info *pd = &chinfo[pier].pd_curves[idx]; /* Lowest gain curve (max power) */ if (pdg == 0) { /* One more point for better accuracy */ pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS; /* Allocate pd points for this curve */ pd->pd_step = calloc(pd->pd_points, sizeof(u8)); if (!pd->pd_step) return -ENOMEM; pd->pd_pwr = calloc(pd->pd_points, sizeof(s16)); if (!pd->pd_pwr) return -ENOMEM; /* Fill raw dataset * (all power levels are in 0.25dB units) */ pd->pd_step[0] = pcinfo->pcdac_x0[0]; pd->pd_pwr[0] = pcinfo->pwr_x0[0]; for (point = 1; point < pd->pd_points; point++) { /* Absolute values */ pd->pd_pwr[point] = pcinfo->pwr_x0[point]; /* Deltas */ pd->pd_step[point] = pd->pd_step[point - 1] + pcinfo->pcdac_x0[point]; } /* Set min power for this frequency */ chinfo[pier].min_pwr = pd->pd_pwr[0]; /* Highest gain curve (min power) */ } else if (pdg == 1) { pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS; /* Allocate pd points for this curve */ pd->pd_step = calloc(pd->pd_points, sizeof(u8)); if (!pd->pd_step) return -ENOMEM; pd->pd_pwr = calloc(pd->pd_points, sizeof(s16)); if (!pd->pd_pwr) return -ENOMEM; /* Fill raw dataset * (all power levels are in 0.25dB units) */ for (point = 0; point < pd->pd_points; point++) { /* Absolute values */ pd->pd_pwr[point] = pcinfo->pwr_x3[point]; /* Fixed points */ pd->pd_step[point] = pcinfo->pcdac_x3[point]; } /* Since we have a higher gain curve * override min power */ chinfo[pier].min_pwr = pd->pd_pwr[0]; } } } return 0; } /* Parse EEPROM data */ static int ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info; struct ath5k_chan_pcal_info *gen_chan_info; u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; u32 offset; u8 i, c; u16 val; int ret; u8 pd_gains = 0; /* Count how many curves we have and * identify them (which one of the 4 * available curves we have on each count). * Curves are stored from lower (x0) to * higher (x3) gain */ for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) { /* ee_x_gain[mode] is x gain mask */ if ((ee->ee_x_gain[mode] >> i) & 0x1) pdgain_idx[pd_gains++] = i; } ee->ee_pd_gains[mode] = pd_gains; if (pd_gains == 0 || pd_gains > 2) return -EINVAL; switch (mode) { case AR5K_EEPROM_MODE_11A: /* * Read 5GHz EEPROM channels */ offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); ath5k_eeprom_init_11a_pcal_freq(ah, offset); offset += AR5K_EEPROM_GROUP2_OFFSET; gen_chan_info = ee->ee_pwr_cal_a; break; case AR5K_EEPROM_MODE_11B: offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); if (AR5K_EEPROM_HDR_11A(ee->ee_header)) offset += AR5K_EEPROM_GROUP3_OFFSET; /* NB: frequency piers parsed during mode init */ gen_chan_info = ee->ee_pwr_cal_b; break; case AR5K_EEPROM_MODE_11G: offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); if (AR5K_EEPROM_HDR_11A(ee->ee_header)) offset += AR5K_EEPROM_GROUP4_OFFSET; else if (AR5K_EEPROM_HDR_11B(ee->ee_header)) offset += AR5K_EEPROM_GROUP2_OFFSET; /* NB: frequency piers parsed during mode init */ gen_chan_info = ee->ee_pwr_cal_g; break; default: return -EINVAL; } for (i = 0; i < ee->ee_n_piers[mode]; i++) { chan_pcal_info = &gen_chan_info[i].rf5112_info; /* Power values in quarter dB * for the lower xpd gain curve * (0 dBm -> higher output power) */ for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) { AR5K_EEPROM_READ(offset++, val); chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff); chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff); } /* PCDAC steps * corresponding to the above power * measurements */ AR5K_EEPROM_READ(offset++, val); chan_pcal_info->pcdac_x0[1] = (val & 0x1f); chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f); chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f); /* Power values in quarter dB * for the higher xpd gain curve * (18 dBm -> lower output power) */ AR5K_EEPROM_READ(offset++, val); chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff); chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff); AR5K_EEPROM_READ(offset++, val); chan_pcal_info->pwr_x3[2] = (val & 0xff); /* PCDAC steps * corresponding to the above power * measurements (fixed) */ chan_pcal_info->pcdac_x3[0] = 20; chan_pcal_info->pcdac_x3[1] = 35; chan_pcal_info->pcdac_x3[2] = 63; if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) { chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f); /* Last xpd0 power level is also channel maximum */ gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3]; } else { chan_pcal_info->pcdac_x0[0] = 1; gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff); } } return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info); } /* * Read power calibration for RF2413 chips * * For RF2413 we have a Power to PDDAC table (Power Detector) * instead of a PCDAC and 4 pd gain curves for each calibrated channel. * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y * axis and looks like an exponential function like the RF5111 curve. * * To recreate the curves we read here the points and interpolate * later. Note that in most cases only 2 (higher and lower) curves are * used (like RF5112) but vendors have the oportunity to include all * 4 curves on eeprom. The final curve (higher power) has an extra * point for better accuracy like RF5112. */ /* For RF2413 power calibration data doesn't start on a fixed location and * if a mode is not supported, it's section is missing -not zeroed-. * So we need to calculate the starting offset for each section by using * these two functions */ /* Return the size of each section based on the mode and the number of pd * gains available (maximum 4). */ static inline unsigned int ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode) { static const unsigned int pdgains_size[] = { 4, 6, 9, 12 }; unsigned int sz; sz = pdgains_size[ee->ee_pd_gains[mode] - 1]; sz *= ee->ee_n_piers[mode]; return sz; } /* Return the starting offset for a section based on the modes supported * and each section's size. */ static unsigned int ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode) { u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4); switch(mode) { case AR5K_EEPROM_MODE_11G: if (AR5K_EEPROM_HDR_11B(ee->ee_header)) offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11B) + AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; /* fall through */ case AR5K_EEPROM_MODE_11B: if (AR5K_EEPROM_HDR_11A(ee->ee_header)) offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11A) + AR5K_EEPROM_N_5GHZ_CHAN / 2; /* fall through */ case AR5K_EEPROM_MODE_11A: break; default: break; } return offset; } /* Convert RF2413 specific data to generic raw data * used by interpolation code */ static int ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, struct ath5k_chan_pcal_info *chinfo) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info_rf2413 *pcinfo; u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; unsigned int pier, point; int pdg; /* Fill raw data for each calibration pier */ for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { pcinfo = &chinfo[pier].rf2413_info; /* Allocate pd_curves for this cal pier */ chinfo[pier].pd_curves = calloc(AR5K_EEPROM_N_PD_CURVES, sizeof(struct ath5k_pdgain_info)); if (!chinfo[pier].pd_curves) return -ENOMEM; /* Fill pd_curves */ for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { u8 idx = pdgain_idx[pdg]; struct ath5k_pdgain_info *pd = &chinfo[pier].pd_curves[idx]; /* One more point for the highest power * curve (lowest gain) */ if (pdg == ee->ee_pd_gains[mode] - 1) pd->pd_points = AR5K_EEPROM_N_PD_POINTS; else pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1; /* Allocate pd points for this curve */ pd->pd_step = calloc(pd->pd_points, sizeof(u8)); if (!pd->pd_step) return -ENOMEM; pd->pd_pwr = calloc(pd->pd_points, sizeof(s16)); if (!pd->pd_pwr) return -ENOMEM; /* Fill raw dataset * convert all pwr levels to * quarter dB for RF5112 combatibility */ pd->pd_step[0] = pcinfo->pddac_i[pdg]; pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg]; for (point = 1; point < pd->pd_points; point++) { pd->pd_pwr[point] = pd->pd_pwr[point - 1] + 2 * pcinfo->pwr[pdg][point - 1]; pd->pd_step[point] = pd->pd_step[point - 1] + pcinfo->pddac[pdg][point - 1]; } /* Highest gain curve -> min power */ if (pdg == 0) chinfo[pier].min_pwr = pd->pd_pwr[0]; /* Lowest gain curve -> max power */ if (pdg == ee->ee_pd_gains[mode] - 1) chinfo[pier].max_pwr = pd->pd_pwr[pd->pd_points - 1]; } } return 0; } /* Parse EEPROM data */ static int ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info_rf2413 *pcinfo; struct ath5k_chan_pcal_info *chinfo; u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; u32 offset; int idx, i, ret; u16 val; u8 pd_gains = 0; /* Count how many curves we have and * identify them (which one of the 4 * available curves we have on each count). * Curves are stored from higher to * lower gain so we go backwards */ for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) { /* ee_x_gain[mode] is x gain mask */ if ((ee->ee_x_gain[mode] >> idx) & 0x1) pdgain_idx[pd_gains++] = idx; } ee->ee_pd_gains[mode] = pd_gains; if (pd_gains == 0) return -EINVAL; offset = ath5k_cal_data_offset_2413(ee, mode); switch (mode) { case AR5K_EEPROM_MODE_11A: if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) return 0; ath5k_eeprom_init_11a_pcal_freq(ah, offset); offset += AR5K_EEPROM_N_5GHZ_CHAN / 2; chinfo = ee->ee_pwr_cal_a; break; case AR5K_EEPROM_MODE_11B: if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) return 0; ath5k_eeprom_init_11bg_2413(ah, mode, offset); offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; chinfo = ee->ee_pwr_cal_b; break; case AR5K_EEPROM_MODE_11G: if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) return 0; ath5k_eeprom_init_11bg_2413(ah, mode, offset); offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; chinfo = ee->ee_pwr_cal_g; break; default: return -EINVAL; } for (i = 0; i < ee->ee_n_piers[mode]; i++) { pcinfo = &chinfo[i].rf2413_info; /* * Read pwr_i, pddac_i and the first * 2 pd points (pwr, pddac) */ AR5K_EEPROM_READ(offset++, val); pcinfo->pwr_i[0] = val & 0x1f; pcinfo->pddac_i[0] = (val >> 5) & 0x7f; pcinfo->pwr[0][0] = (val >> 12) & 0xf; AR5K_EEPROM_READ(offset++, val); pcinfo->pddac[0][0] = val & 0x3f; pcinfo->pwr[0][1] = (val >> 6) & 0xf; pcinfo->pddac[0][1] = (val >> 10) & 0x3f; AR5K_EEPROM_READ(offset++, val); pcinfo->pwr[0][2] = val & 0xf; pcinfo->pddac[0][2] = (val >> 4) & 0x3f; pcinfo->pwr[0][3] = 0; pcinfo->pddac[0][3] = 0; if (pd_gains > 1) { /* * Pd gain 0 is not the last pd gain * so it only has 2 pd points. * Continue wih pd gain 1. */ pcinfo->pwr_i[1] = (val >> 10) & 0x1f; pcinfo->pddac_i[1] = (val >> 15) & 0x1; AR5K_EEPROM_READ(offset++, val); pcinfo->pddac_i[1] |= (val & 0x3F) << 1; pcinfo->pwr[1][0] = (val >> 6) & 0xf; pcinfo->pddac[1][0] = (val >> 10) & 0x3f; AR5K_EEPROM_READ(offset++, val); pcinfo->pwr[1][1] = val & 0xf; pcinfo->pddac[1][1] = (val >> 4) & 0x3f; pcinfo->pwr[1][2] = (val >> 10) & 0xf; pcinfo->pddac[1][2] = (val >> 14) & 0x3; AR5K_EEPROM_READ(offset++, val); pcinfo->pddac[1][2] |= (val & 0xF) << 2; pcinfo->pwr[1][3] = 0; pcinfo->pddac[1][3] = 0; } else if (pd_gains == 1) { /* * Pd gain 0 is the last one so * read the extra point. */ pcinfo->pwr[0][3] = (val >> 10) & 0xf; pcinfo->pddac[0][3] = (val >> 14) & 0x3; AR5K_EEPROM_READ(offset++, val); pcinfo->pddac[0][3] |= (val & 0xF) << 2; } /* * Proceed with the other pd_gains * as above. */ if (pd_gains > 2) { pcinfo->pwr_i[2] = (val >> 4) & 0x1f; pcinfo->pddac_i[2] = (val >> 9) & 0x7f; AR5K_EEPROM_READ(offset++, val); pcinfo->pwr[2][0] = (val >> 0) & 0xf; pcinfo->pddac[2][0] = (val >> 4) & 0x3f; pcinfo->pwr[2][1] = (val >> 10) & 0xf; pcinfo->pddac[2][1] = (val >> 14) & 0x3; AR5K_EEPROM_READ(offset++, val); pcinfo->pddac[2][1] |= (val & 0xF) << 2; pcinfo->pwr[2][2] = (val >> 4) & 0xf; pcinfo->pddac[2][2] = (val >> 8) & 0x3f; pcinfo->pwr[2][3] = 0; pcinfo->pddac[2][3] = 0; } else if (pd_gains == 2) { pcinfo->pwr[1][3] = (val >> 4) & 0xf; pcinfo->pddac[1][3] = (val >> 8) & 0x3f; } if (pd_gains > 3) { pcinfo->pwr_i[3] = (val >> 14) & 0x3; AR5K_EEPROM_READ(offset++, val); pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2; pcinfo->pddac_i[3] = (val >> 3) & 0x7f; pcinfo->pwr[3][0] = (val >> 10) & 0xf; pcinfo->pddac[3][0] = (val >> 14) & 0x3; AR5K_EEPROM_READ(offset++, val); pcinfo->pddac[3][0] |= (val & 0xF) << 2; pcinfo->pwr[3][1] = (val >> 4) & 0xf; pcinfo->pddac[3][1] = (val >> 8) & 0x3f; pcinfo->pwr[3][2] = (val >> 14) & 0x3; AR5K_EEPROM_READ(offset++, val); pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2; pcinfo->pddac[3][2] = (val >> 2) & 0x3f; pcinfo->pwr[3][3] = (val >> 8) & 0xf; pcinfo->pddac[3][3] = (val >> 12) & 0xF; AR5K_EEPROM_READ(offset++, val); pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4; } else if (pd_gains == 3) { pcinfo->pwr[2][3] = (val >> 14) & 0x3; AR5K_EEPROM_READ(offset++, val); pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2; pcinfo->pddac[2][3] = (val >> 2) & 0x3f; } } return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo); } /* * Read per rate target power (this is the maximum tx power * supported by the card). This info is used when setting * tx power, no matter the channel. * * This also works for v5 EEPROMs. */ static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_rate_pcal_info *rate_pcal_info; u8 *rate_target_pwr_num; u32 offset; u16 val; int ret, i; offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1); rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode]; switch (mode) { case AR5K_EEPROM_MODE_11A: offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version); rate_pcal_info = ee->ee_rate_tpwr_a; ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN; break; case AR5K_EEPROM_MODE_11B: offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); rate_pcal_info = ee->ee_rate_tpwr_b; ee->ee_rate_target_pwr_num[mode] = 2; /* 3rd is g mode's 1st */ break; case AR5K_EEPROM_MODE_11G: offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version); rate_pcal_info = ee->ee_rate_tpwr_g; ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN; break; default: return -EINVAL; } /* Different freq mask for older eeproms (<= v3.2) */ if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) { for (i = 0; i < (*rate_target_pwr_num); i++) { AR5K_EEPROM_READ(offset++, val); rate_pcal_info[i].freq = ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode); rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f); rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f; AR5K_EEPROM_READ(offset++, val); if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS || val == 0) { (*rate_target_pwr_num) = i; break; } rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7); rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f); rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f); } } else { for (i = 0; i < (*rate_target_pwr_num); i++) { AR5K_EEPROM_READ(offset++, val); rate_pcal_info[i].freq = ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode); rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f); rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f; AR5K_EEPROM_READ(offset++, val); if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS || val == 0) { (*rate_target_pwr_num) = i; break; } rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf; rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f); rate_pcal_info[i].target_power_54 = (val & 0x3f); } } return 0; } /* * Read per channel calibration info from EEPROM * * This info is used to calibrate the baseband power table. Imagine * that for each channel there is a power curve that's hw specific * (depends on amplifier etc) and we try to "correct" this curve using * offests we pass on to phy chip (baseband -> before amplifier) so that * it can use accurate power values when setting tx power (takes amplifier's * performance on each channel into account). * * EEPROM provides us with the offsets for some pre-calibrated channels * and we have to interpolate to create the full table for these channels and * also the table for any channel. */ static int ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; int (*read_pcal)(struct ath5k_hw *hw, int mode); int mode; int err; if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) && (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1)) read_pcal = ath5k_eeprom_read_pcal_info_5112; else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) && (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2)) read_pcal = ath5k_eeprom_read_pcal_info_2413; else read_pcal = ath5k_eeprom_read_pcal_info_5111; for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) { err = read_pcal(ah, mode); if (err) return err; err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode); if (err < 0) return err; } return 0; } static int ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info *chinfo; u8 pier, pdg; switch (mode) { case AR5K_EEPROM_MODE_11A: if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) return 0; chinfo = ee->ee_pwr_cal_a; break; case AR5K_EEPROM_MODE_11B: if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) return 0; chinfo = ee->ee_pwr_cal_b; break; case AR5K_EEPROM_MODE_11G: if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) return 0; chinfo = ee->ee_pwr_cal_g; break; default: return -EINVAL; } for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { if (!chinfo[pier].pd_curves) continue; for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { struct ath5k_pdgain_info *pd = &chinfo[pier].pd_curves[pdg]; if (pd != NULL) { free(pd->pd_step); free(pd->pd_pwr); } } free(chinfo[pier].pd_curves); } return 0; } void ath5k_eeprom_detach(struct ath5k_hw *ah) { u8 mode; for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) ath5k_eeprom_free_pcal_info(ah, mode); } /* Read conformance test limits used for regulatory control */ static int ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_edge_power *rep; unsigned int fmask, pmask; unsigned int ctl_mode; int ret, i, j; u32 offset; u16 val; pmask = AR5K_EEPROM_POWER_M; fmask = AR5K_EEPROM_FREQ_M(ee->ee_version); offset = AR5K_EEPROM_CTL(ee->ee_version); ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version); for (i = 0; i < ee->ee_ctls; i += 2) { AR5K_EEPROM_READ(offset++, val); ee->ee_ctl[i] = (val >> 8) & 0xff; ee->ee_ctl[i + 1] = val & 0xff; } offset = AR5K_EEPROM_GROUP8_OFFSET; if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) - AR5K_EEPROM_GROUP5_OFFSET; else offset += AR5K_EEPROM_GROUPS_START(ee->ee_version); rep = ee->ee_ctl_pwr; for(i = 0; i < ee->ee_ctls; i++) { switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) { case AR5K_CTL_11A: case AR5K_CTL_TURBO: ctl_mode = AR5K_EEPROM_MODE_11A; break; default: ctl_mode = AR5K_EEPROM_MODE_11G; break; } if (ee->ee_ctl[i] == 0) { if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) offset += 8; else offset += 7; rep += AR5K_EEPROM_N_EDGES; continue; } if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) { for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) { AR5K_EEPROM_READ(offset++, val); rep[j].freq = (val >> 8) & fmask; rep[j + 1].freq = val & fmask; } for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) { AR5K_EEPROM_READ(offset++, val); rep[j].edge = (val >> 8) & pmask; rep[j].flag = (val >> 14) & 1; rep[j + 1].edge = val & pmask; rep[j + 1].flag = (val >> 6) & 1; } } else { AR5K_EEPROM_READ(offset++, val); rep[0].freq = (val >> 9) & fmask; rep[1].freq = (val >> 2) & fmask; rep[2].freq = (val << 5) & fmask; AR5K_EEPROM_READ(offset++, val); rep[2].freq |= (val >> 11) & 0x1f; rep[3].freq = (val >> 4) & fmask; rep[4].freq = (val << 3) & fmask; AR5K_EEPROM_READ(offset++, val); rep[4].freq |= (val >> 13) & 0x7; rep[5].freq = (val >> 6) & fmask; rep[6].freq = (val << 1) & fmask; AR5K_EEPROM_READ(offset++, val); rep[6].freq |= (val >> 15) & 0x1; rep[7].freq = (val >> 8) & fmask; rep[0].edge = (val >> 2) & pmask; rep[1].edge = (val << 4) & pmask; AR5K_EEPROM_READ(offset++, val); rep[1].edge |= (val >> 12) & 0xf; rep[2].edge = (val >> 6) & pmask; rep[3].edge = val & pmask; AR5K_EEPROM_READ(offset++, val); rep[4].edge = (val >> 10) & pmask; rep[5].edge = (val >> 4) & pmask; rep[6].edge = (val << 2) & pmask; AR5K_EEPROM_READ(offset++, val); rep[6].edge |= (val >> 14) & 0x3; rep[7].edge = (val >> 8) & pmask; } for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) { rep[j].freq = ath5k_eeprom_bin2freq(ee, rep[j].freq, ctl_mode); } rep += AR5K_EEPROM_N_EDGES; } return 0; } /* * Initialize eeprom power tables */ int ath5k_eeprom_init(struct ath5k_hw *ah) { int err; err = ath5k_eeprom_init_header(ah); if (err < 0) return err; err = ath5k_eeprom_init_modes(ah); if (err < 0) return err; err = ath5k_eeprom_read_pcal_info(ah); if (err < 0) return err; err = ath5k_eeprom_read_ctl_info(ah); if (err < 0) return err; return 0; } /* * Read the MAC address from eeprom */ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) { u8 mac_d[ETH_ALEN] = {}; u32 total, offset; u16 data; int octet, ret; ret = ath5k_hw_eeprom_read(ah, 0x20, &data); if (ret) return ret; for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { ret = ath5k_hw_eeprom_read(ah, offset, &data); if (ret) return ret; total += data; mac_d[octet + 1] = data & 0xff; mac_d[octet] = data >> 8; octet += 2; } if (!total || total == 3 * 0xffff) return -EINVAL; memcpy(mac, mac_d, ETH_ALEN); return 0; } int ath5k_eeprom_is_hb63(struct ath5k_hw *ah) { u16 data; ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data); if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data) return 1; else return 0; } debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/base.h0000664000000000000000000001204012524662415021303 0ustar /*- * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting * All rights reserved. * * Modified for gPXE, July 2009, by Joshua Oreman * Original from Linux kernel 2.6.30. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * */ /* * Defintions for the Atheros Wireless LAN controller driver. */ #ifndef _DEV_ATH_ATHVAR_H #define _DEV_ATH_ATHVAR_H FILE_LICENCE ( BSD3 ); #include "ath5k.h" #include #define ATH_RXBUF 16 /* number of RX buffers */ #define ATH_TXBUF 16 /* number of TX buffers */ struct ath5k_buf { struct list_head list; unsigned int flags; /* rx descriptor flags */ struct ath5k_desc *desc; /* virtual addr of desc */ u32 daddr; /* physical addr of desc */ struct io_buffer *iob; /* I/O buffer for buf */ u32 iobaddr;/* physical addr of iob data */ }; /* * Data transmit queue state. One of these exists for each * hardware transmit queue. Packets sent to us from above * are assigned to queues based on their priority. Not all * devices support a complete set of hardware transmit queues. * For those devices the array sc_ac2q will map multiple * priorities to fewer hardware queues (typically all to one * hardware queue). */ struct ath5k_txq { unsigned int qnum; /* hardware q number */ u32 *link; /* link ptr in last TX desc */ struct list_head q; /* transmit queue */ int setup; }; #if CHAN_DEBUG #define ATH_CHAN_MAX (26+26+26+200+200) #else #define ATH_CHAN_MAX (14+14+14+252+20) #endif /* Software Carrier, keeps track of the driver state * associated with an instance of a device */ struct ath5k_softc { struct pci_device *pdev; /* for dma mapping */ void *iobase; /* address of the device */ struct net80211_device *dev; /* IEEE 802.11 common */ struct ath5k_hw *ah; /* Atheros HW */ struct net80211_hw_info *hwinfo; int curband; int irq_ena; /* interrupts enabled */ struct ath5k_buf *bufptr; /* allocated buffer ptr */ struct ath5k_desc *desc; /* TX/RX descriptors */ u32 desc_daddr; /* DMA (physical) address */ size_t desc_len; /* size of TX/RX descriptors */ u16 cachelsz; /* cache line size */ int status; #define ATH_STAT_INVALID 0x01 /* disable hardware accesses */ #define ATH_STAT_MRRETRY 0x02 /* multi-rate retry support */ #define ATH_STAT_PROMISC 0x04 #define ATH_STAT_LEDSOFT 0x08 /* enable LED gpio status */ #define ATH_STAT_STARTED 0x10 /* opened & irqs enabled */ unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ unsigned int curmode; /* current phy mode */ struct net80211_channel *curchan; /* current h/w channel */ enum ath5k_int imask; /* interrupt mask copy */ u8 bssidmask[ETH_ALEN]; unsigned int rxbufsize; /* rx size based on mtu */ struct list_head rxbuf; /* receive buffer */ u32 *rxlink; /* link ptr in last RX desc */ struct list_head txbuf; /* transmit buffer */ unsigned int txbuf_len; /* buf count in txbuf list */ struct ath5k_txq txq; /* tx queue */ int last_calib_ticks; int power_level; /* Requested tx power in dbm */ int assoc; /* assocate state */ int hw_rate; /* Hardware tx rate code */ int hw_rtscts_rate; /* Hardware rts/cts rate code */ }; #define ath5k_hw_hasbssidmask(_ah) \ (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0) #define ath5k_hw_hasveol(_ah) \ (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0) #endif debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/reg.h0000664000000000000000000027465612524662415021175 0ustar /* * Copyright (c) 2006-2008 Nick Kossifidis * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2007-2008 Michael Taylor * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ /* * Register values for Atheros 5210/5211/5212 cards from OpenBSD's ar5k * maintained by Reyk Floeter * * I tried to document those registers by looking at ar5k code, some * 802.11 (802.11e mostly) papers and by reading various public available * Atheros presentations and papers like these: * * 5210 - http://nova.stanford.edu/~bbaas/ps/isscc2002_slides.pdf * http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf * * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf * * This file also contains register values found on a memory dump of * Atheros's ART program (Atheros Radio Test), on ath9k, on legacy-hal * released by Atheros and on various debug messages found on the net. */ /*====MAC DMA REGISTERS====*/ /* * AR5210-Specific TXDP registers * 5210 has only 2 transmit queues so no DCU/QCU, just * 2 transmit descriptor pointers... */ #define AR5K_NOQCU_TXDP0 0x0000 /* Queue 0 - data */ #define AR5K_NOQCU_TXDP1 0x0004 /* Queue 1 - beacons */ /* * Mac Control Register */ #define AR5K_CR 0x0008 /* Register Address */ #define AR5K_CR_TXE0 0x00000001 /* TX Enable for queue 0 on 5210 */ #define AR5K_CR_TXE1 0x00000002 /* TX Enable for queue 1 on 5210 */ #define AR5K_CR_RXE 0x00000004 /* RX Enable */ #define AR5K_CR_TXD0 0x00000008 /* TX Disable for queue 0 on 5210 */ #define AR5K_CR_TXD1 0x00000010 /* TX Disable for queue 1 on 5210 */ #define AR5K_CR_RXD 0x00000020 /* RX Disable */ #define AR5K_CR_SWI 0x00000040 /* Software Interrupt */ /* * RX Descriptor Pointer register */ #define AR5K_RXDP 0x000c /* * Configuration and status register */ #define AR5K_CFG 0x0014 /* Register Address */ #define AR5K_CFG_SWTD 0x00000001 /* Byte-swap TX descriptor (for big endian archs) */ #define AR5K_CFG_SWTB 0x00000002 /* Byte-swap TX buffer */ #define AR5K_CFG_SWRD 0x00000004 /* Byte-swap RX descriptor */ #define AR5K_CFG_SWRB 0x00000008 /* Byte-swap RX buffer */ #define AR5K_CFG_SWRG 0x00000010 /* Byte-swap Register access */ #define AR5K_CFG_IBSS 0x00000020 /* 0-BSS, 1-IBSS [5211+] */ #define AR5K_CFG_PHY_OK 0x00000100 /* [5211+] */ #define AR5K_CFG_EEBS 0x00000200 /* EEPROM is busy */ #define AR5K_CFG_CLKGD 0x00000400 /* Clock gated (Disable dynamic clock) */ #define AR5K_CFG_TXCNT 0x00007800 /* Tx frame count (?) [5210] */ #define AR5K_CFG_TXCNT_S 11 #define AR5K_CFG_TXFSTAT 0x00008000 /* Tx frame status (?) [5210] */ #define AR5K_CFG_TXFSTRT 0x00010000 /* [5210] */ #define AR5K_CFG_PCI_THRES 0x00060000 /* PCI Master req q threshold [5211+] */ #define AR5K_CFG_PCI_THRES_S 17 /* * Interrupt enable register */ #define AR5K_IER 0x0024 /* Register Address */ #define AR5K_IER_DISABLE 0x00000000 /* Disable card interrupts */ #define AR5K_IER_ENABLE 0x00000001 /* Enable card interrupts */ /* * 0x0028 is Beacon Control Register on 5210 * and first RTS duration register on 5211 */ /* * Beacon control register [5210] */ #define AR5K_BCR 0x0028 /* Register Address */ #define AR5K_BCR_AP 0x00000000 /* AP mode */ #define AR5K_BCR_ADHOC 0x00000001 /* Ad-Hoc mode */ #define AR5K_BCR_BDMAE 0x00000002 /* DMA enable */ #define AR5K_BCR_TQ1FV 0x00000004 /* Use Queue1 for CAB traffic */ #define AR5K_BCR_TQ1V 0x00000008 /* Use Queue1 for Beacon traffic */ #define AR5K_BCR_BCGET 0x00000010 /* * First RTS duration register [5211] */ #define AR5K_RTSD0 0x0028 /* Register Address */ #define AR5K_RTSD0_6 0x000000ff /* 6Mb RTS duration mask (?) */ #define AR5K_RTSD0_6_S 0 /* 6Mb RTS duration shift (?) */ #define AR5K_RTSD0_9 0x0000ff00 /* 9Mb*/ #define AR5K_RTSD0_9_S 8 #define AR5K_RTSD0_12 0x00ff0000 /* 12Mb*/ #define AR5K_RTSD0_12_S 16 #define AR5K_RTSD0_18 0xff000000 /* 16Mb*/ #define AR5K_RTSD0_18_S 24 /* * 0x002c is Beacon Status Register on 5210 * and second RTS duration register on 5211 */ /* * Beacon status register [5210] * * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR). * So SNAPPEDBCRVALID sould also stand for "snapped BCR -values- valid", so i * renamed it to SNAPSHOTSVALID to make more sense. I realy have no idea what * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR. */ #define AR5K_BSR 0x002c /* Register Address */ #define AR5K_BSR_BDLYSW 0x00000001 /* SW Beacon delay (?) */ #define AR5K_BSR_BDLYDMA 0x00000002 /* DMA Beacon delay (?) */ #define AR5K_BSR_TXQ1F 0x00000004 /* Beacon queue (1) finished */ #define AR5K_BSR_ATIMDLY 0x00000008 /* ATIM delay (?) */ #define AR5K_BSR_SNPADHOC 0x00000100 /* Ad-hoc mode set (?) */ #define AR5K_BSR_SNPBDMAE 0x00000200 /* Beacon DMA enabled (?) */ #define AR5K_BSR_SNPTQ1FV 0x00000400 /* Queue1 is used for CAB traffic (?) */ #define AR5K_BSR_SNPTQ1V 0x00000800 /* Queue1 is used for Beacon traffic (?) */ #define AR5K_BSR_SNAPSHOTSVALID 0x00001000 /* BCR snapshots are valid (?) */ #define AR5K_BSR_SWBA_CNT 0x00ff0000 /* * Second RTS duration register [5211] */ #define AR5K_RTSD1 0x002c /* Register Address */ #define AR5K_RTSD1_24 0x000000ff /* 24Mb */ #define AR5K_RTSD1_24_S 0 #define AR5K_RTSD1_36 0x0000ff00 /* 36Mb */ #define AR5K_RTSD1_36_S 8 #define AR5K_RTSD1_48 0x00ff0000 /* 48Mb */ #define AR5K_RTSD1_48_S 16 #define AR5K_RTSD1_54 0xff000000 /* 54Mb */ #define AR5K_RTSD1_54_S 24 /* * Transmit configuration register */ #define AR5K_TXCFG 0x0030 /* Register Address */ #define AR5K_TXCFG_SDMAMR 0x00000007 /* DMA size (read) */ #define AR5K_TXCFG_SDMAMR_S 0 #define AR5K_TXCFG_B_MODE 0x00000008 /* Set b mode for 5111 (enable 2111) */ #define AR5K_TXCFG_TXFSTP 0x00000008 /* TX DMA full Stop [5210] */ #define AR5K_TXCFG_TXFULL 0x000003f0 /* TX Triger level mask */ #define AR5K_TXCFG_TXFULL_S 4 #define AR5K_TXCFG_TXFULL_0B 0x00000000 #define AR5K_TXCFG_TXFULL_64B 0x00000010 #define AR5K_TXCFG_TXFULL_128B 0x00000020 #define AR5K_TXCFG_TXFULL_192B 0x00000030 #define AR5K_TXCFG_TXFULL_256B 0x00000040 #define AR5K_TXCFG_TXCONT_EN 0x00000080 #define AR5K_TXCFG_DMASIZE 0x00000100 /* Flag for passing DMA size [5210] */ #define AR5K_TXCFG_JUMBO_DESC_EN 0x00000400 /* Enable jumbo tx descriptors [5211+] */ #define AR5K_TXCFG_ADHOC_BCN_ATIM 0x00000800 /* Adhoc Beacon ATIM Policy */ #define AR5K_TXCFG_ATIM_WINDOW_DEF_DIS 0x00001000 /* Disable ATIM window defer [5211+] */ #define AR5K_TXCFG_RTSRND 0x00001000 /* [5211+] */ #define AR5K_TXCFG_FRMPAD_DIS 0x00002000 /* [5211+] */ #define AR5K_TXCFG_RDY_CBR_DIS 0x00004000 /* Ready time CBR disable [5211+] */ #define AR5K_TXCFG_JUMBO_FRM_MODE 0x00008000 /* Jumbo frame mode [5211+] */ #define AR5K_TXCFG_DCU_DBL_BUF_DIS 0x00008000 /* Disable double buffering on DCU */ #define AR5K_TXCFG_DCU_CACHING_DIS 0x00010000 /* Disable DCU caching */ /* * Receive configuration register */ #define AR5K_RXCFG 0x0034 /* Register Address */ #define AR5K_RXCFG_SDMAMW 0x00000007 /* DMA size (write) */ #define AR5K_RXCFG_SDMAMW_S 0 #define AR5K_RXCFG_ZLFDMA 0x00000008 /* Enable Zero-length frame DMA */ #define AR5K_RXCFG_DEF_ANTENNA 0x00000010 /* Default antenna (?) */ #define AR5K_RXCFG_JUMBO_RXE 0x00000020 /* Enable jumbo rx descriptors [5211+] */ #define AR5K_RXCFG_JUMBO_WRAP 0x00000040 /* Wrap jumbo frames [5211+] */ #define AR5K_RXCFG_SLE_ENTRY 0x00000080 /* Sleep entry policy */ /* * Receive jumbo descriptor last address register * Only found in 5211 (?) */ #define AR5K_RXJLA 0x0038 /* * MIB control register */ #define AR5K_MIBC 0x0040 /* Register Address */ #define AR5K_MIBC_COW 0x00000001 /* Warn test indicator */ #define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */ #define AR5K_MIBC_CMC 0x00000004 /* Clean MIB Counters */ #define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe */ /* * Timeout prescale register */ #define AR5K_TOPS 0x0044 #define AR5K_TOPS_M 0x0000ffff /* * Receive timeout register (no frame received) */ #define AR5K_RXNOFRM 0x0048 #define AR5K_RXNOFRM_M 0x000003ff /* * Transmit timeout register (no frame sent) */ #define AR5K_TXNOFRM 0x004c #define AR5K_TXNOFRM_M 0x000003ff #define AR5K_TXNOFRM_QCU 0x000ffc00 #define AR5K_TXNOFRM_QCU_S 10 /* * Receive frame gap timeout register */ #define AR5K_RPGTO 0x0050 #define AR5K_RPGTO_M 0x000003ff /* * Receive frame count limit register */ #define AR5K_RFCNT 0x0054 #define AR5K_RFCNT_M 0x0000001f /* [5211+] (?) */ #define AR5K_RFCNT_RFCL 0x0000000f /* [5210] */ /* * Misc settings register * (reserved0-3) */ #define AR5K_MISC 0x0058 /* Register Address */ #define AR5K_MISC_DMA_OBS_M 0x000001e0 #define AR5K_MISC_DMA_OBS_S 5 #define AR5K_MISC_MISC_OBS_M 0x00000e00 #define AR5K_MISC_MISC_OBS_S 9 #define AR5K_MISC_MAC_OBS_LSB_M 0x00007000 #define AR5K_MISC_MAC_OBS_LSB_S 12 #define AR5K_MISC_MAC_OBS_MSB_M 0x00038000 #define AR5K_MISC_MAC_OBS_MSB_S 15 #define AR5K_MISC_LED_DECAY 0x001c0000 /* [5210] */ #define AR5K_MISC_LED_BLINK 0x00e00000 /* [5210] */ /* * QCU/DCU clock gating register (5311) * (reserved4-5) */ #define AR5K_QCUDCU_CLKGT 0x005c /* Register Address (?) */ #define AR5K_QCUDCU_CLKGT_QCU 0x0000ffff /* Mask for QCU clock */ #define AR5K_QCUDCU_CLKGT_DCU 0x07ff0000 /* Mask for DCU clock */ /* * Interrupt Status Registers * * For 5210 there is only one status register but for * 5211/5212 we have one primary and 4 secondary registers. * So we have AR5K_ISR for 5210 and AR5K_PISR /SISRx for 5211/5212. * Most of these bits are common for all chipsets. */ #define AR5K_ISR 0x001c /* Register Address [5210] */ #define AR5K_PISR 0x0080 /* Register Address [5211+] */ #define AR5K_ISR_RXOK 0x00000001 /* Frame successfuly recieved */ #define AR5K_ISR_RXDESC 0x00000002 /* RX descriptor request */ #define AR5K_ISR_RXERR 0x00000004 /* Receive error */ #define AR5K_ISR_RXNOFRM 0x00000008 /* No frame received (receive timeout) */ #define AR5K_ISR_RXEOL 0x00000010 /* Empty RX descriptor */ #define AR5K_ISR_RXORN 0x00000020 /* Receive FIFO overrun */ #define AR5K_ISR_TXOK 0x00000040 /* Frame successfuly transmited */ #define AR5K_ISR_TXDESC 0x00000080 /* TX descriptor request */ #define AR5K_ISR_TXERR 0x00000100 /* Transmit error */ #define AR5K_ISR_TXNOFRM 0x00000200 /* No frame transmited (transmit timeout) */ #define AR5K_ISR_TXEOL 0x00000400 /* Empty TX descriptor */ #define AR5K_ISR_TXURN 0x00000800 /* Transmit FIFO underrun */ #define AR5K_ISR_MIB 0x00001000 /* Update MIB counters */ #define AR5K_ISR_SWI 0x00002000 /* Software interrupt */ #define AR5K_ISR_RXPHY 0x00004000 /* PHY error */ #define AR5K_ISR_RXKCM 0x00008000 /* RX Key cache miss */ #define AR5K_ISR_SWBA 0x00010000 /* Software beacon alert */ #define AR5K_ISR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ #define AR5K_ISR_BMISS 0x00040000 /* Beacon missed */ #define AR5K_ISR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ #define AR5K_ISR_BNR 0x00100000 /* Beacon not ready [5211+] */ #define AR5K_ISR_MCABT 0x00100000 /* Master Cycle Abort [5210] */ #define AR5K_ISR_RXCHIRP 0x00200000 /* CHIRP Received [5212+] */ #define AR5K_ISR_SSERR 0x00200000 /* Signaled System Error [5210] */ #define AR5K_ISR_DPERR 0x00400000 /* Det par Error (?) [5210] */ #define AR5K_ISR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */ #define AR5K_ISR_TIM 0x00800000 /* [5211+] */ #define AR5K_ISR_BCNMISC 0x00800000 /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT, CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */ #define AR5K_ISR_GPIO 0x01000000 /* GPIO (rf kill) */ #define AR5K_ISR_QCBRORN 0x02000000 /* QCU CBR overrun [5211+] */ #define AR5K_ISR_QCBRURN 0x04000000 /* QCU CBR underrun [5211+] */ #define AR5K_ISR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */ /* * Secondary status registers [5211+] (0 - 4) * * These give the status for each QCU, only QCUs 0-9 are * represented. */ #define AR5K_SISR0 0x0084 /* Register Address [5211+] */ #define AR5K_SISR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */ #define AR5K_SISR0_QCU_TXOK_S 0 #define AR5K_SISR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */ #define AR5K_SISR0_QCU_TXDESC_S 16 #define AR5K_SISR1 0x0088 /* Register Address [5211+] */ #define AR5K_SISR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */ #define AR5K_SISR1_QCU_TXERR_S 0 #define AR5K_SISR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */ #define AR5K_SISR1_QCU_TXEOL_S 16 #define AR5K_SISR2 0x008c /* Register Address [5211+] */ #define AR5K_SISR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */ #define AR5K_SISR2_QCU_TXURN_S 0 #define AR5K_SISR2_MCABT 0x00100000 /* Master Cycle Abort */ #define AR5K_SISR2_SSERR 0x00200000 /* Signaled System Error */ #define AR5K_SISR2_DPERR 0x00400000 /* Bus parity error */ #define AR5K_SISR2_TIM 0x01000000 /* [5212+] */ #define AR5K_SISR2_CAB_END 0x02000000 /* [5212+] */ #define AR5K_SISR2_DTIM_SYNC 0x04000000 /* DTIM sync lost [5212+] */ #define AR5K_SISR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ #define AR5K_SISR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ #define AR5K_SISR2_DTIM 0x20000000 /* [5212+] */ #define AR5K_SISR2_TSFOOR 0x80000000 /* TSF OOR (?) */ #define AR5K_SISR3 0x0090 /* Register Address [5211+] */ #define AR5K_SISR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ #define AR5K_SISR3_QCBRORN_S 0 #define AR5K_SISR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */ #define AR5K_SISR3_QCBRURN_S 16 #define AR5K_SISR4 0x0094 /* Register Address [5211+] */ #define AR5K_SISR4_QTRIG 0x000003ff /* Mask for QTRIG */ #define AR5K_SISR4_QTRIG_S 0 /* * Shadow read-and-clear interrupt status registers [5211+] */ #define AR5K_RAC_PISR 0x00c0 /* Read and clear PISR */ #define AR5K_RAC_SISR0 0x00c4 /* Read and clear SISR0 */ #define AR5K_RAC_SISR1 0x00c8 /* Read and clear SISR1 */ #define AR5K_RAC_SISR2 0x00cc /* Read and clear SISR2 */ #define AR5K_RAC_SISR3 0x00d0 /* Read and clear SISR3 */ #define AR5K_RAC_SISR4 0x00d4 /* Read and clear SISR4 */ /* * Interrupt Mask Registers * * As whith ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match. */ #define AR5K_IMR 0x0020 /* Register Address [5210] */ #define AR5K_PIMR 0x00a0 /* Register Address [5211+] */ #define AR5K_IMR_RXOK 0x00000001 /* Frame successfuly recieved*/ #define AR5K_IMR_RXDESC 0x00000002 /* RX descriptor request*/ #define AR5K_IMR_RXERR 0x00000004 /* Receive error*/ #define AR5K_IMR_RXNOFRM 0x00000008 /* No frame received (receive timeout)*/ #define AR5K_IMR_RXEOL 0x00000010 /* Empty RX descriptor*/ #define AR5K_IMR_RXORN 0x00000020 /* Receive FIFO overrun*/ #define AR5K_IMR_TXOK 0x00000040 /* Frame successfuly transmited*/ #define AR5K_IMR_TXDESC 0x00000080 /* TX descriptor request*/ #define AR5K_IMR_TXERR 0x00000100 /* Transmit error*/ #define AR5K_IMR_TXNOFRM 0x00000200 /* No frame transmited (transmit timeout)*/ #define AR5K_IMR_TXEOL 0x00000400 /* Empty TX descriptor*/ #define AR5K_IMR_TXURN 0x00000800 /* Transmit FIFO underrun*/ #define AR5K_IMR_MIB 0x00001000 /* Update MIB counters*/ #define AR5K_IMR_SWI 0x00002000 /* Software interrupt */ #define AR5K_IMR_RXPHY 0x00004000 /* PHY error*/ #define AR5K_IMR_RXKCM 0x00008000 /* RX Key cache miss */ #define AR5K_IMR_SWBA 0x00010000 /* Software beacon alert*/ #define AR5K_IMR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ #define AR5K_IMR_BMISS 0x00040000 /* Beacon missed*/ #define AR5K_IMR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ #define AR5K_IMR_BNR 0x00100000 /* Beacon not ready [5211+] */ #define AR5K_IMR_MCABT 0x00100000 /* Master Cycle Abort [5210] */ #define AR5K_IMR_RXCHIRP 0x00200000 /* CHIRP Received [5212+]*/ #define AR5K_IMR_SSERR 0x00200000 /* Signaled System Error [5210] */ #define AR5K_IMR_DPERR 0x00400000 /* Det par Error (?) [5210] */ #define AR5K_IMR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */ #define AR5K_IMR_TIM 0x00800000 /* [5211+] */ #define AR5K_IMR_BCNMISC 0x00800000 /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT, CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */ #define AR5K_IMR_GPIO 0x01000000 /* GPIO (rf kill)*/ #define AR5K_IMR_QCBRORN 0x02000000 /* QCU CBR overrun (?) [5211+] */ #define AR5K_IMR_QCBRURN 0x04000000 /* QCU CBR underrun (?) [5211+] */ #define AR5K_IMR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */ /* * Secondary interrupt mask registers [5211+] (0 - 4) */ #define AR5K_SIMR0 0x00a4 /* Register Address [5211+] */ #define AR5K_SIMR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */ #define AR5K_SIMR0_QCU_TXOK_S 0 #define AR5K_SIMR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */ #define AR5K_SIMR0_QCU_TXDESC_S 16 #define AR5K_SIMR1 0x00a8 /* Register Address [5211+] */ #define AR5K_SIMR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */ #define AR5K_SIMR1_QCU_TXERR_S 0 #define AR5K_SIMR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */ #define AR5K_SIMR1_QCU_TXEOL_S 16 #define AR5K_SIMR2 0x00ac /* Register Address [5211+] */ #define AR5K_SIMR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */ #define AR5K_SIMR2_QCU_TXURN_S 0 #define AR5K_SIMR2_MCABT 0x00100000 /* Master Cycle Abort */ #define AR5K_SIMR2_SSERR 0x00200000 /* Signaled System Error */ #define AR5K_SIMR2_DPERR 0x00400000 /* Bus parity error */ #define AR5K_SIMR2_TIM 0x01000000 /* [5212+] */ #define AR5K_SIMR2_CAB_END 0x02000000 /* [5212+] */ #define AR5K_SIMR2_DTIM_SYNC 0x04000000 /* DTIM Sync lost [5212+] */ #define AR5K_SIMR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ #define AR5K_SIMR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ #define AR5K_SIMR2_DTIM 0x20000000 /* [5212+] */ #define AR5K_SIMR2_TSFOOR 0x80000000 /* TSF OOR (?) */ #define AR5K_SIMR3 0x00b0 /* Register Address [5211+] */ #define AR5K_SIMR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ #define AR5K_SIMR3_QCBRORN_S 0 #define AR5K_SIMR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */ #define AR5K_SIMR3_QCBRURN_S 16 #define AR5K_SIMR4 0x00b4 /* Register Address [5211+] */ #define AR5K_SIMR4_QTRIG 0x000003ff /* Mask for QTRIG */ #define AR5K_SIMR4_QTRIG_S 0 /* * DMA Debug registers 0-7 * 0xe0 - 0xfc */ /* * Decompression mask registers [5212+] */ #define AR5K_DCM_ADDR 0x0400 /*Decompression mask address (index) */ #define AR5K_DCM_DATA 0x0404 /*Decompression mask data */ /* * Wake On Wireless pattern control register [5212+] */ #define AR5K_WOW_PCFG 0x0410 /* Register Address */ #define AR5K_WOW_PCFG_PAT_MATCH_EN 0x00000001 /* Pattern match enable */ #define AR5K_WOW_PCFG_LONG_FRAME_POL 0x00000002 /* Long frame policy */ #define AR5K_WOW_PCFG_WOBMISS 0x00000004 /* Wake on bea(con) miss (?) */ #define AR5K_WOW_PCFG_PAT_0_EN 0x00000100 /* Enable pattern 0 */ #define AR5K_WOW_PCFG_PAT_1_EN 0x00000200 /* Enable pattern 1 */ #define AR5K_WOW_PCFG_PAT_2_EN 0x00000400 /* Enable pattern 2 */ #define AR5K_WOW_PCFG_PAT_3_EN 0x00000800 /* Enable pattern 3 */ #define AR5K_WOW_PCFG_PAT_4_EN 0x00001000 /* Enable pattern 4 */ #define AR5K_WOW_PCFG_PAT_5_EN 0x00002000 /* Enable pattern 5 */ /* * Wake On Wireless pattern index register (?) [5212+] */ #define AR5K_WOW_PAT_IDX 0x0414 /* * Wake On Wireless pattern data register [5212+] */ #define AR5K_WOW_PAT_DATA 0x0418 /* Register Address */ #define AR5K_WOW_PAT_DATA_0_3_V 0x00000001 /* Pattern 0, 3 value */ #define AR5K_WOW_PAT_DATA_1_4_V 0x00000100 /* Pattern 1, 4 value */ #define AR5K_WOW_PAT_DATA_2_5_V 0x00010000 /* Pattern 2, 5 value */ #define AR5K_WOW_PAT_DATA_0_3_M 0x01000000 /* Pattern 0, 3 mask */ #define AR5K_WOW_PAT_DATA_1_4_M 0x04000000 /* Pattern 1, 4 mask */ #define AR5K_WOW_PAT_DATA_2_5_M 0x10000000 /* Pattern 2, 5 mask */ /* * Decompression configuration registers [5212+] */ #define AR5K_DCCFG 0x0420 /* Register Address */ #define AR5K_DCCFG_GLOBAL_EN 0x00000001 /* Enable decompression on all queues */ #define AR5K_DCCFG_BYPASS_EN 0x00000002 /* Bypass decompression */ #define AR5K_DCCFG_BCAST_EN 0x00000004 /* Enable decompression for bcast frames */ #define AR5K_DCCFG_MCAST_EN 0x00000008 /* Enable decompression for mcast frames */ /* * Compression configuration registers [5212+] */ #define AR5K_CCFG 0x0600 /* Register Address */ #define AR5K_CCFG_WINDOW_SIZE 0x00000007 /* Compression window size */ #define AR5K_CCFG_CPC_EN 0x00000008 /* Enable performance counters */ #define AR5K_CCFG_CCU 0x0604 /* Register Address */ #define AR5K_CCFG_CCU_CUP_EN 0x00000001 /* CCU Catchup enable */ #define AR5K_CCFG_CCU_CREDIT 0x00000002 /* CCU Credit (field) */ #define AR5K_CCFG_CCU_CD_THRES 0x00000080 /* CCU Cyc(lic?) debt threshold (field) */ #define AR5K_CCFG_CCU_CUP_LCNT 0x00010000 /* CCU Catchup lit(?) count */ #define AR5K_CCFG_CCU_INIT 0x00100200 /* Initial value during reset */ /* * Compression performance counter registers [5212+] */ #define AR5K_CPC0 0x0610 /* Compression performance counter 0 */ #define AR5K_CPC1 0x0614 /* Compression performance counter 1*/ #define AR5K_CPC2 0x0618 /* Compression performance counter 2 */ #define AR5K_CPC3 0x061c /* Compression performance counter 3 */ #define AR5K_CPCOVF 0x0620 /* Compression performance overflow */ /* * Queue control unit (QCU) registers [5211+] * * Card has 12 TX Queues but i see that only 0-9 are used (?) * both in binary HAL (see ah.h) and ar5k. Each queue has it's own * TXDP at addresses 0x0800 - 0x082c, a CBR (Constant Bit Rate) * configuration register (0x08c0 - 0x08ec), a ready time configuration * register (0x0900 - 0x092c), a misc configuration register (0x09c0 - * 0x09ec) and a status register (0x0a00 - 0x0a2c). We also have some * global registers, QCU transmit enable/disable and "one shot arm (?)" * set/clear, which contain status for all queues (we shift by 1 for each * queue). To access these registers easily we define some macros here * that are used inside HAL. For more infos check out *_tx_queue functs. */ /* * Generic QCU Register access macros */ #define AR5K_QUEUE_REG(_r, _q) (((_q) << 2) + _r) #define AR5K_QCU_GLOBAL_READ(_r, _q) (AR5K_REG_READ(_r) & (1 << _q)) #define AR5K_QCU_GLOBAL_WRITE(_r, _q) AR5K_REG_WRITE(_r, (1 << _q)) /* * QCU Transmit descriptor pointer registers */ #define AR5K_QCU_TXDP_BASE 0x0800 /* Register Address - Queue0 TXDP */ #define AR5K_QUEUE_TXDP(_q) AR5K_QUEUE_REG(AR5K_QCU_TXDP_BASE, _q) /* * QCU Transmit enable register */ #define AR5K_QCU_TXE 0x0840 #define AR5K_ENABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXE, _q) #define AR5K_QUEUE_ENABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXE, _q) /* * QCU Transmit disable register */ #define AR5K_QCU_TXD 0x0880 #define AR5K_DISABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXD, _q) #define AR5K_QUEUE_DISABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXD, _q) /* * QCU Constant Bit Rate configuration registers */ #define AR5K_QCU_CBRCFG_BASE 0x08c0 /* Register Address - Queue0 CBRCFG */ #define AR5K_QCU_CBRCFG_INTVAL 0x00ffffff /* CBR Interval mask */ #define AR5K_QCU_CBRCFG_INTVAL_S 0 #define AR5K_QCU_CBRCFG_ORN_THRES 0xff000000 /* CBR overrun threshold mask */ #define AR5K_QCU_CBRCFG_ORN_THRES_S 24 #define AR5K_QUEUE_CBRCFG(_q) AR5K_QUEUE_REG(AR5K_QCU_CBRCFG_BASE, _q) /* * QCU Ready time configuration registers */ #define AR5K_QCU_RDYTIMECFG_BASE 0x0900 /* Register Address - Queue0 RDYTIMECFG */ #define AR5K_QCU_RDYTIMECFG_INTVAL 0x00ffffff /* Ready time interval mask */ #define AR5K_QCU_RDYTIMECFG_INTVAL_S 0 #define AR5K_QCU_RDYTIMECFG_ENABLE 0x01000000 /* Ready time enable mask */ #define AR5K_QUEUE_RDYTIMECFG(_q) AR5K_QUEUE_REG(AR5K_QCU_RDYTIMECFG_BASE, _q) /* * QCU one shot arm set registers */ #define AR5K_QCU_ONESHOTARM_SET 0x0940 /* Register Address -QCU "one shot arm set (?)" */ #define AR5K_QCU_ONESHOTARM_SET_M 0x0000ffff /* * QCU one shot arm clear registers */ #define AR5K_QCU_ONESHOTARM_CLEAR 0x0980 /* Register Address -QCU "one shot arm clear (?)" */ #define AR5K_QCU_ONESHOTARM_CLEAR_M 0x0000ffff /* * QCU misc registers */ #define AR5K_QCU_MISC_BASE 0x09c0 /* Register Address -Queue0 MISC */ #define AR5K_QCU_MISC_FRSHED_M 0x0000000f /* Frame sheduling mask */ #define AR5K_QCU_MISC_FRSHED_ASAP 0 /* ASAP */ #define AR5K_QCU_MISC_FRSHED_CBR 1 /* Constant Bit Rate */ #define AR5K_QCU_MISC_FRSHED_DBA_GT 2 /* DMA Beacon alert gated */ #define AR5K_QCU_MISC_FRSHED_TIM_GT 3 /* TIMT gated */ #define AR5K_QCU_MISC_FRSHED_BCN_SENT_GT 4 /* Beacon sent gated */ #define AR5K_QCU_MISC_ONESHOT_ENABLE 0x00000010 /* Oneshot enable */ #define AR5K_QCU_MISC_CBREXP_DIS 0x00000020 /* Disable CBR expired counter (normal queue) */ #define AR5K_QCU_MISC_CBREXP_BCN_DIS 0x00000040 /* Disable CBR expired counter (beacon queue) */ #define AR5K_QCU_MISC_BCN_ENABLE 0x00000080 /* Enable Beacon use */ #define AR5K_QCU_MISC_CBR_THRES_ENABLE 0x00000100 /* CBR expired threshold enabled */ #define AR5K_QCU_MISC_RDY_VEOL_POLICY 0x00000200 /* TXE reset when RDYTIME expired or VEOL */ #define AR5K_QCU_MISC_CBR_RESET_CNT 0x00000400 /* CBR threshold (counter) reset */ #define AR5K_QCU_MISC_DCU_EARLY 0x00000800 /* DCU early termination */ #define AR5K_QCU_MISC_DCU_CMP_EN 0x00001000 /* Enable frame compression */ #define AR5K_QUEUE_MISC(_q) AR5K_QUEUE_REG(AR5K_QCU_MISC_BASE, _q) /* * QCU status registers */ #define AR5K_QCU_STS_BASE 0x0a00 /* Register Address - Queue0 STS */ #define AR5K_QCU_STS_FRMPENDCNT 0x00000003 /* Frames pending counter */ #define AR5K_QCU_STS_CBREXPCNT 0x0000ff00 /* CBR expired counter */ #define AR5K_QUEUE_STATUS(_q) AR5K_QUEUE_REG(AR5K_QCU_STS_BASE, _q) /* * QCU ready time shutdown register */ #define AR5K_QCU_RDYTIMESHDN 0x0a40 #define AR5K_QCU_RDYTIMESHDN_M 0x000003ff /* * QCU compression buffer base registers [5212+] */ #define AR5K_QCU_CBB_SELECT 0x0b00 #define AR5K_QCU_CBB_ADDR 0x0b04 #define AR5K_QCU_CBB_ADDR_S 9 /* * QCU compression buffer configuration register [5212+] * (buffer size) */ #define AR5K_QCU_CBCFG 0x0b08 /* * Distributed Coordination Function (DCF) control unit (DCU) * registers [5211+] * * These registers control the various characteristics of each queue * for 802.11e (WME) combatibility so they go together with * QCU registers in pairs. For each queue we have a QCU mask register, * (0x1000 - 0x102c), a local-IFS settings register (0x1040 - 0x106c), * a retry limit register (0x1080 - 0x10ac), a channel time register * (0x10c0 - 0x10ec), a misc-settings register (0x1100 - 0x112c) and * a sequence number register (0x1140 - 0x116c). It seems that "global" * registers here afect all queues (see use of DCU_GBL_IFS_SLOT in ar5k). * We use the same macros here for easier register access. * */ /* * DCU QCU mask registers */ #define AR5K_DCU_QCUMASK_BASE 0x1000 /* Register Address -Queue0 DCU_QCUMASK */ #define AR5K_DCU_QCUMASK_M 0x000003ff #define AR5K_QUEUE_QCUMASK(_q) AR5K_QUEUE_REG(AR5K_DCU_QCUMASK_BASE, _q) /* * DCU local Inter Frame Space settings register */ #define AR5K_DCU_LCL_IFS_BASE 0x1040 /* Register Address -Queue0 DCU_LCL_IFS */ #define AR5K_DCU_LCL_IFS_CW_MIN 0x000003ff /* Minimum Contention Window */ #define AR5K_DCU_LCL_IFS_CW_MIN_S 0 #define AR5K_DCU_LCL_IFS_CW_MAX 0x000ffc00 /* Maximum Contention Window */ #define AR5K_DCU_LCL_IFS_CW_MAX_S 10 #define AR5K_DCU_LCL_IFS_AIFS 0x0ff00000 /* Arbitrated Interframe Space */ #define AR5K_DCU_LCL_IFS_AIFS_S 20 #define AR5K_DCU_LCL_IFS_AIFS_MAX 0xfc /* Anything above that can cause DCU to hang */ #define AR5K_QUEUE_DFS_LOCAL_IFS(_q) AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q) /* * DCU retry limit registers */ #define AR5K_DCU_RETRY_LMT_BASE 0x1080 /* Register Address -Queue0 DCU_RETRY_LMT */ #define AR5K_DCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */ #define AR5K_DCU_RETRY_LMT_SH_RETRY_S 0 #define AR5K_DCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry limit mask */ #define AR5K_DCU_RETRY_LMT_LG_RETRY_S 4 #define AR5K_DCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask (?) */ #define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8 #define AR5K_DCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask (?) */ #define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14 #define AR5K_QUEUE_DFS_RETRY_LIMIT(_q) AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q) /* * DCU channel time registers */ #define AR5K_DCU_CHAN_TIME_BASE 0x10c0 /* Register Address -Queue0 DCU_CHAN_TIME */ #define AR5K_DCU_CHAN_TIME_DUR 0x000fffff /* Channel time duration */ #define AR5K_DCU_CHAN_TIME_DUR_S 0 #define AR5K_DCU_CHAN_TIME_ENABLE 0x00100000 /* Enable channel time */ #define AR5K_QUEUE_DFS_CHANNEL_TIME(_q) AR5K_QUEUE_REG(AR5K_DCU_CHAN_TIME_BASE, _q) /* * DCU misc registers [5211+] * * Note: Arbiter lockout control controls the * behaviour on low priority queues when we have multiple queues * with pending frames. Intra-frame lockout means we wait until * the queue's current frame transmits (with post frame backoff and bursting) * before we transmit anything else and global lockout means we * wait for the whole queue to finish before higher priority queues * can transmit (this is used on beacon and CAB queues). * No lockout means there is no special handling. */ #define AR5K_DCU_MISC_BASE 0x1100 /* Register Address -Queue0 DCU_MISC */ #define AR5K_DCU_MISC_BACKOFF 0x0000003f /* Mask for backoff threshold */ #define AR5K_DCU_MISC_ETS_RTS_POL 0x00000040 /* End of transmission series station RTS/data failure count reset policy (?) */ #define AR5K_DCU_MISC_ETS_CW_POL 0x00000080 /* End of transmission series CW reset policy */ #define AR5K_DCU_MISC_FRAG_WAIT 0x00000100 /* Wait for next fragment */ #define AR5K_DCU_MISC_BACKOFF_FRAG 0x00000200 /* Enable backoff while bursting */ #define AR5K_DCU_MISC_HCFPOLL_ENABLE 0x00000800 /* CF - Poll enable */ #define AR5K_DCU_MISC_BACKOFF_PERSIST 0x00001000 /* Persistent backoff */ #define AR5K_DCU_MISC_FRMPRFTCH_ENABLE 0x00002000 /* Enable frame pre-fetch */ #define AR5K_DCU_MISC_VIRTCOL 0x0000c000 /* Mask for Virtual Collision (?) */ #define AR5K_DCU_MISC_VIRTCOL_NORMAL 0 #define AR5K_DCU_MISC_VIRTCOL_IGNORE 1 #define AR5K_DCU_MISC_BCN_ENABLE 0x00010000 /* Enable Beacon use */ #define AR5K_DCU_MISC_ARBLOCK_CTL 0x00060000 /* Arbiter lockout control mask */ #define AR5K_DCU_MISC_ARBLOCK_CTL_S 17 #define AR5K_DCU_MISC_ARBLOCK_CTL_NONE 0 /* No arbiter lockout */ #define AR5K_DCU_MISC_ARBLOCK_CTL_INTFRM 1 /* Intra-frame lockout */ #define AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL 2 /* Global lockout */ #define AR5K_DCU_MISC_ARBLOCK_IGNORE 0x00080000 /* Ignore Arbiter lockout */ #define AR5K_DCU_MISC_SEQ_NUM_INCR_DIS 0x00100000 /* Disable sequence number increment */ #define AR5K_DCU_MISC_POST_FR_BKOFF_DIS 0x00200000 /* Disable post-frame backoff */ #define AR5K_DCU_MISC_VIRT_COLL_POLICY 0x00400000 /* Virtual Collision cw policy */ #define AR5K_DCU_MISC_BLOWN_IFS_POLICY 0x00800000 /* Blown IFS policy (?) */ #define AR5K_DCU_MISC_SEQNUM_CTL 0x01000000 /* Sequence number control (?) */ #define AR5K_QUEUE_DFS_MISC(_q) AR5K_QUEUE_REG(AR5K_DCU_MISC_BASE, _q) /* * DCU frame sequence number registers */ #define AR5K_DCU_SEQNUM_BASE 0x1140 #define AR5K_DCU_SEQNUM_M 0x00000fff #define AR5K_QUEUE_DCU_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q) /* * DCU global IFS SIFS register */ #define AR5K_DCU_GBL_IFS_SIFS 0x1030 #define AR5K_DCU_GBL_IFS_SIFS_M 0x0000ffff /* * DCU global IFS slot interval register */ #define AR5K_DCU_GBL_IFS_SLOT 0x1070 #define AR5K_DCU_GBL_IFS_SLOT_M 0x0000ffff /* * DCU global IFS EIFS register */ #define AR5K_DCU_GBL_IFS_EIFS 0x10b0 #define AR5K_DCU_GBL_IFS_EIFS_M 0x0000ffff /* * DCU global IFS misc register * * LFSR stands for Linear Feedback Shift Register * and it's used for generating pseudo-random * number sequences. * * (If i understand corectly, random numbers are * used for idle sensing -multiplied with cwmin/max etc-) */ #define AR5K_DCU_GBL_IFS_MISC 0x10f0 /* Register Address */ #define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */ #define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */ #define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */ #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */ #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10 #define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */ #define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST 0x00400000 /* SIFS cnt reset policy (?) */ #define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST 0x00800000 /* AIFS cnt reset policy (?) */ #define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS 0x01000000 /* Disable random LFSR slice */ /* * DCU frame prefetch control register */ #define AR5K_DCU_FP 0x1230 /* Register Address */ #define AR5K_DCU_FP_NOBURST_DCU_EN 0x00000001 /* Enable non-burst prefetch on DCU (?) */ #define AR5K_DCU_FP_NOBURST_EN 0x00000010 /* Enable non-burst prefetch (?) */ #define AR5K_DCU_FP_BURST_DCU_EN 0x00000020 /* Enable burst prefetch on DCU (?) */ /* * DCU transmit pause control/status register */ #define AR5K_DCU_TXP 0x1270 /* Register Address */ #define AR5K_DCU_TXP_M 0x000003ff /* Tx pause mask */ #define AR5K_DCU_TXP_STATUS 0x00010000 /* Tx pause status */ /* * DCU transmit filter table 0 (32 entries) * each entry contains a 32bit slice of the * 128bit tx filter for each DCU (4 slices per DCU) */ #define AR5K_DCU_TX_FILTER_0_BASE 0x1038 #define AR5K_DCU_TX_FILTER_0(_n) (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64)) /* * DCU transmit filter table 1 (16 entries) */ #define AR5K_DCU_TX_FILTER_1_BASE 0x103c #define AR5K_DCU_TX_FILTER_1(_n) (AR5K_DCU_TX_FILTER_1_BASE + (_n * 64)) /* * DCU clear transmit filter register */ #define AR5K_DCU_TX_FILTER_CLR 0x143c /* * DCU set transmit filter register */ #define AR5K_DCU_TX_FILTER_SET 0x147c /* * Reset control register */ #define AR5K_RESET_CTL 0x4000 /* Register Address */ #define AR5K_RESET_CTL_PCU 0x00000001 /* Protocol Control Unit reset */ #define AR5K_RESET_CTL_DMA 0x00000002 /* DMA (Rx/Tx) reset [5210] */ #define AR5K_RESET_CTL_BASEBAND 0x00000002 /* Baseband reset [5211+] */ #define AR5K_RESET_CTL_MAC 0x00000004 /* MAC reset (PCU+Baseband ?) [5210] */ #define AR5K_RESET_CTL_PHY 0x00000008 /* PHY reset [5210] */ #define AR5K_RESET_CTL_PCI 0x00000010 /* PCI Core reset (interrupts etc) */ /* * Sleep control register */ #define AR5K_SLEEP_CTL 0x4004 /* Register Address */ #define AR5K_SLEEP_CTL_SLDUR 0x0000ffff /* Sleep duration mask */ #define AR5K_SLEEP_CTL_SLDUR_S 0 #define AR5K_SLEEP_CTL_SLE 0x00030000 /* Sleep enable mask */ #define AR5K_SLEEP_CTL_SLE_S 16 #define AR5K_SLEEP_CTL_SLE_WAKE 0x00000000 /* Force chip awake */ #define AR5K_SLEEP_CTL_SLE_SLP 0x00010000 /* Force chip sleep */ #define AR5K_SLEEP_CTL_SLE_ALLOW 0x00020000 /* Normal sleep policy */ #define AR5K_SLEEP_CTL_SLE_UNITS 0x00000008 /* [5211+] */ #define AR5K_SLEEP_CTL_DUR_TIM_POL 0x00040000 /* Sleep duration timing policy */ #define AR5K_SLEEP_CTL_DUR_WRITE_POL 0x00080000 /* Sleep duration write policy */ #define AR5K_SLEEP_CTL_SLE_POL 0x00100000 /* Sleep policy mode */ /* * Interrupt pending register */ #define AR5K_INTPEND 0x4008 #define AR5K_INTPEND_M 0x00000001 /* * Sleep force register */ #define AR5K_SFR 0x400c #define AR5K_SFR_EN 0x00000001 /* * PCI configuration register * TODO: Fix LED stuff */ #define AR5K_PCICFG 0x4010 /* Register Address */ #define AR5K_PCICFG_EEAE 0x00000001 /* Eeprom access enable [5210] */ #define AR5K_PCICFG_SLEEP_CLOCK_EN 0x00000002 /* Enable sleep clock */ #define AR5K_PCICFG_CLKRUNEN 0x00000004 /* CLKRUN enable [5211+] */ #define AR5K_PCICFG_EESIZE 0x00000018 /* Mask for EEPROM size [5211+] */ #define AR5K_PCICFG_EESIZE_S 3 #define AR5K_PCICFG_EESIZE_4K 0 /* 4K */ #define AR5K_PCICFG_EESIZE_8K 1 /* 8K */ #define AR5K_PCICFG_EESIZE_16K 2 /* 16K */ #define AR5K_PCICFG_EESIZE_FAIL 3 /* Failed to get size [5211+] */ #define AR5K_PCICFG_LED 0x00000060 /* Led status [5211+] */ #define AR5K_PCICFG_LED_NONE 0x00000000 /* Default [5211+] */ #define AR5K_PCICFG_LED_PEND 0x00000020 /* Scan / Auth pending */ #define AR5K_PCICFG_LED_ASSOC 0x00000040 /* Associated */ #define AR5K_PCICFG_BUS_SEL 0x00000380 /* Mask for "bus select" [5211+] (?) */ #define AR5K_PCICFG_CBEFIX_DIS 0x00000400 /* Disable CBE fix */ #define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep */ #define AR5K_PCICFG_LED_BCTL 0x00001000 /* Led blink (?) [5210] */ #define AR5K_PCICFG_RETRY_FIX 0x00001000 /* Enable pci core retry fix */ #define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even whith pending interrupts*/ #define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status */ #define AR5K_PCICFG_LEDMODE 0x000e0000 /* Ledmode [5211+] */ #define AR5K_PCICFG_LEDMODE_PROP 0x00000000 /* Blink on standard traffic [5211+] */ #define AR5K_PCICFG_LEDMODE_PROM 0x00020000 /* Default mode (blink on any traffic) [5211+] */ #define AR5K_PCICFG_LEDMODE_PWR 0x00040000 /* Some other blinking mode (?) [5211+] */ #define AR5K_PCICFG_LEDMODE_RAND 0x00060000 /* Random blinking (?) [5211+] */ #define AR5K_PCICFG_LEDBLINK 0x00700000 /* Led blink rate */ #define AR5K_PCICFG_LEDBLINK_S 20 #define AR5K_PCICFG_LEDSLOW 0x00800000 /* Slowest led blink rate [5211+] */ #define AR5K_PCICFG_LEDSTATE \ (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE | \ AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW) #define AR5K_PCICFG_SLEEP_CLOCK_RATE 0x03000000 /* Sleep clock rate */ #define AR5K_PCICFG_SLEEP_CLOCK_RATE_S 24 /* * "General Purpose Input/Output" (GPIO) control register * * I'm not sure about this but after looking at the code * for all chipsets here is what i got. * * We have 6 GPIOs (pins), each GPIO has 4 modes (2 bits) * Mode 0 -> always input * Mode 1 -> output when GPIODO for this GPIO is set to 0 * Mode 2 -> output when GPIODO for this GPIO is set to 1 * Mode 3 -> always output * * For more infos check out get_gpio/set_gpio and * set_gpio_input/set_gpio_output functs. * For more infos on gpio interrupt check out set_gpio_intr. */ #define AR5K_NUM_GPIO 6 #define AR5K_GPIOCR 0x4014 /* Register Address */ #define AR5K_GPIOCR_INT_ENA 0x00008000 /* Enable GPIO interrupt */ #define AR5K_GPIOCR_INT_SELL 0x00000000 /* Generate interrupt when pin is low */ #define AR5K_GPIOCR_INT_SELH 0x00010000 /* Generate interrupt when pin is high */ #define AR5K_GPIOCR_IN(n) (0 << ((n) * 2)) /* Mode 0 for pin n */ #define AR5K_GPIOCR_OUT0(n) (1 << ((n) * 2)) /* Mode 1 for pin n */ #define AR5K_GPIOCR_OUT1(n) (2 << ((n) * 2)) /* Mode 2 for pin n */ #define AR5K_GPIOCR_OUT(n) (3 << ((n) * 2)) /* Mode 3 for pin n */ #define AR5K_GPIOCR_INT_SEL(n) ((n) << 12) /* Interrupt for GPIO pin n */ /* * "General Purpose Input/Output" (GPIO) data output register */ #define AR5K_GPIODO 0x4018 /* * "General Purpose Input/Output" (GPIO) data input register */ #define AR5K_GPIODI 0x401c #define AR5K_GPIODI_M 0x0000002f /* * Silicon revision register */ #define AR5K_SREV 0x4020 /* Register Address */ #define AR5K_SREV_REV 0x0000000f /* Mask for revision */ #define AR5K_SREV_REV_S 0 #define AR5K_SREV_VER 0x000000ff /* Mask for version */ #define AR5K_SREV_VER_S 4 /* * TXE write posting register */ #define AR5K_TXEPOST 0x4028 /* * QCU sleep mask */ #define AR5K_QCU_SLEEP_MASK 0x402c /* 0x4068 is compression buffer configuration * register on 5414 and pm configuration register * on 5424 and newer pci-e chips. */ /* * Compression buffer configuration * register (enable/disable) [5414] */ #define AR5K_5414_CBCFG 0x4068 #define AR5K_5414_CBCFG_BUF_DIS 0x10 /* Disable buffer */ /* * PCI-E Power managment configuration * and status register [5424+] */ #define AR5K_PCIE_PM_CTL 0x4068 /* Register address */ /* Only 5424 */ #define AR5K_PCIE_PM_CTL_L1_WHEN_D2 0x00000001 /* enable PCIe core enter L1 when d2_sleep_en is asserted */ #define AR5K_PCIE_PM_CTL_L0_L0S_CLEAR 0x00000002 /* Clear L0 and L0S counters */ #define AR5K_PCIE_PM_CTL_L0_L0S_EN 0x00000004 /* Start L0 nd L0S counters */ #define AR5K_PCIE_PM_CTL_LDRESET_EN 0x00000008 /* Enable reset when link goes down */ /* Wake On Wireless */ #define AR5K_PCIE_PM_CTL_PME_EN 0x00000010 /* PME Enable */ #define AR5K_PCIE_PM_CTL_AUX_PWR_DET 0x00000020 /* Aux power detect */ #define AR5K_PCIE_PM_CTL_PME_CLEAR 0x00000040 /* Clear PME */ #define AR5K_PCIE_PM_CTL_PSM_D0 0x00000080 #define AR5K_PCIE_PM_CTL_PSM_D1 0x00000100 #define AR5K_PCIE_PM_CTL_PSM_D2 0x00000200 #define AR5K_PCIE_PM_CTL_PSM_D3 0x00000400 /* * PCI-E Workaround enable register */ #define AR5K_PCIE_WAEN 0x407c /* * PCI-E Serializer/Desirializer * registers */ #define AR5K_PCIE_SERDES 0x4080 #define AR5K_PCIE_SERDES_RESET 0x4084 /*====EEPROM REGISTERS====*/ /* * EEPROM access registers * * Here we got a difference between 5210/5211-12 * read data register for 5210 is at 0x6800 and * status register is at 0x6c00. There is also * no eeprom command register on 5210 and the * offsets are different. * * To read eeprom data for a specific offset: * 5210 - enable eeprom access (AR5K_PCICFG_EEAE) * read AR5K_EEPROM_BASE +(4 * offset) * check the eeprom status register * and read eeprom data register. * * 5211 - write offset to AR5K_EEPROM_BASE * 5212 write AR5K_EEPROM_CMD_READ on AR5K_EEPROM_CMD * check the eeprom status register * and read eeprom data register. * * To write eeprom data for a specific offset: * 5210 - enable eeprom access (AR5K_PCICFG_EEAE) * write data to AR5K_EEPROM_BASE +(4 * offset) * check the eeprom status register * 5211 - write AR5K_EEPROM_CMD_RESET on AR5K_EEPROM_CMD * 5212 write offset to AR5K_EEPROM_BASE * write data to data register * write AR5K_EEPROM_CMD_WRITE on AR5K_EEPROM_CMD * check the eeprom status register * * For more infos check eeprom_* functs and the ar5k.c * file posted in madwifi-devel mailing list. * http://sourceforge.net/mailarchive/message.php?msg_id=8966525 * */ #define AR5K_EEPROM_BASE 0x6000 /* * EEPROM data register */ #define AR5K_EEPROM_DATA_5211 0x6004 #define AR5K_EEPROM_DATA_5210 0x6800 #define AR5K_EEPROM_DATA (ah->ah_version == AR5K_AR5210 ? \ AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211) /* * EEPROM command register */ #define AR5K_EEPROM_CMD 0x6008 /* Register Addres */ #define AR5K_EEPROM_CMD_READ 0x00000001 /* EEPROM read */ #define AR5K_EEPROM_CMD_WRITE 0x00000002 /* EEPROM write */ #define AR5K_EEPROM_CMD_RESET 0x00000004 /* EEPROM reset */ /* * EEPROM status register */ #define AR5K_EEPROM_STAT_5210 0x6c00 /* Register Address [5210] */ #define AR5K_EEPROM_STAT_5211 0x600c /* Register Address [5211+] */ #define AR5K_EEPROM_STATUS (ah->ah_version == AR5K_AR5210 ? \ AR5K_EEPROM_STAT_5210 : AR5K_EEPROM_STAT_5211) #define AR5K_EEPROM_STAT_RDERR 0x00000001 /* EEPROM read failed */ #define AR5K_EEPROM_STAT_RDDONE 0x00000002 /* EEPROM read successful */ #define AR5K_EEPROM_STAT_WRERR 0x00000004 /* EEPROM write failed */ #define AR5K_EEPROM_STAT_WRDONE 0x00000008 /* EEPROM write successful */ /* * EEPROM config register */ #define AR5K_EEPROM_CFG 0x6010 /* Register Addres */ #define AR5K_EEPROM_CFG_SIZE 0x00000003 /* Size determination override */ #define AR5K_EEPROM_CFG_SIZE_AUTO 0 #define AR5K_EEPROM_CFG_SIZE_4KBIT 1 #define AR5K_EEPROM_CFG_SIZE_8KBIT 2 #define AR5K_EEPROM_CFG_SIZE_16KBIT 3 #define AR5K_EEPROM_CFG_WR_WAIT_DIS 0x00000004 /* Disable write wait */ #define AR5K_EEPROM_CFG_CLK_RATE 0x00000018 /* Clock rate */ #define AR5K_EEPROM_CFG_CLK_RATE_S 3 #define AR5K_EEPROM_CFG_CLK_RATE_156KHZ 0 #define AR5K_EEPROM_CFG_CLK_RATE_312KHZ 1 #define AR5K_EEPROM_CFG_CLK_RATE_625KHZ 2 #define AR5K_EEPROM_CFG_PROT_KEY 0x00ffff00 /* Protection key */ #define AR5K_EEPROM_CFG_PROT_KEY_S 8 #define AR5K_EEPROM_CFG_LIND_EN 0x01000000 /* Enable length indicator (?) */ /* * TODO: Wake On Wireless registers * Range 0x7000 - 0x7ce0 */ /* * Protocol Control Unit (PCU) registers */ /* * Used for checking initial register writes * during channel reset (see reset func) */ #define AR5K_PCU_MIN 0x8000 #define AR5K_PCU_MAX 0x8fff /* * First station id register (Lower 32 bits of MAC address) */ #define AR5K_STA_ID0 0x8000 #define AR5K_STA_ID0_ARRD_L32 0xffffffff /* * Second station id register (Upper 16 bits of MAC address + PCU settings) */ #define AR5K_STA_ID1 0x8004 /* Register Address */ #define AR5K_STA_ID1_ADDR_U16 0x0000ffff /* Upper 16 bits of MAC addres */ #define AR5K_STA_ID1_AP 0x00010000 /* Set AP mode */ #define AR5K_STA_ID1_ADHOC 0x00020000 /* Set Ad-Hoc mode */ #define AR5K_STA_ID1_PWR_SV 0x00040000 /* Power save reporting */ #define AR5K_STA_ID1_NO_KEYSRCH 0x00080000 /* No key search */ #define AR5K_STA_ID1_NO_PSPOLL 0x00100000 /* No power save polling [5210] */ #define AR5K_STA_ID1_PCF_5211 0x00100000 /* Enable PCF on [5211+] */ #define AR5K_STA_ID1_PCF_5210 0x00200000 /* Enable PCF on [5210]*/ #define AR5K_STA_ID1_PCF (ah->ah_version == AR5K_AR5210 ? \ AR5K_STA_ID1_PCF_5210 : AR5K_STA_ID1_PCF_5211) #define AR5K_STA_ID1_DEFAULT_ANTENNA 0x00200000 /* Use default antenna */ #define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */ #define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS */ #define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Use 6Mbit/s for ACK/CTS */ #define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* Use 11b base rate for ACK/CTS [5211+] */ #define AR5K_STA_ID1_SELFGEN_DEF_ANT 0x04000000 /* Use def. antenna for self generated frames */ #define AR5K_STA_ID1_CRYPT_MIC_EN 0x08000000 /* Enable MIC */ #define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Look up key when key id != 0 */ #define AR5K_STA_ID1_PRESERVE_SEQ_NUM 0x20000000 /* Preserve sequence number */ #define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */ #define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */ /* * First BSSID register (MAC address, lower 32bits) */ #define AR5K_BSS_ID0 0x8008 /* * Second BSSID register (MAC address in upper 16 bits) * * AID: Association ID */ #define AR5K_BSS_ID1 0x800c #define AR5K_BSS_ID1_AID 0xffff0000 #define AR5K_BSS_ID1_AID_S 16 /* * Backoff slot time register */ #define AR5K_SLOT_TIME 0x8010 /* * ACK/CTS timeout register */ #define AR5K_TIME_OUT 0x8014 /* Register Address */ #define AR5K_TIME_OUT_ACK 0x00001fff /* ACK timeout mask */ #define AR5K_TIME_OUT_ACK_S 0 #define AR5K_TIME_OUT_CTS 0x1fff0000 /* CTS timeout mask */ #define AR5K_TIME_OUT_CTS_S 16 /* * RSSI threshold register */ #define AR5K_RSSI_THR 0x8018 /* Register Address */ #define AR5K_RSSI_THR_M 0x000000ff /* Mask for RSSI threshold [5211+] */ #define AR5K_RSSI_THR_BMISS_5210 0x00000700 /* Mask for Beacon Missed threshold [5210] */ #define AR5K_RSSI_THR_BMISS_5210_S 8 #define AR5K_RSSI_THR_BMISS_5211 0x0000ff00 /* Mask for Beacon Missed threshold [5211+] */ #define AR5K_RSSI_THR_BMISS_5211_S 8 #define AR5K_RSSI_THR_BMISS (ah->ah_version == AR5K_AR5210 ? \ AR5K_RSSI_THR_BMISS_5210 : AR5K_RSSI_THR_BMISS_5211) #define AR5K_RSSI_THR_BMISS_S 8 /* * 5210 has more PCU registers because there is no QCU/DCU * so queue parameters are set here, this way a lot common * registers have different address for 5210. To make things * easier we define a macro based on ah->ah_version for common * registers with different addresses and common flags. */ /* * Retry limit register * * Retry limit register for 5210 (no QCU/DCU so it's done in PCU) */ #define AR5K_NODCU_RETRY_LMT 0x801c /* Register Address */ #define AR5K_NODCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */ #define AR5K_NODCU_RETRY_LMT_SH_RETRY_S 0 #define AR5K_NODCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry mask */ #define AR5K_NODCU_RETRY_LMT_LG_RETRY_S 4 #define AR5K_NODCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask */ #define AR5K_NODCU_RETRY_LMT_SSH_RETRY_S 8 #define AR5K_NODCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask */ #define AR5K_NODCU_RETRY_LMT_SLG_RETRY_S 14 #define AR5K_NODCU_RETRY_LMT_CW_MIN 0x3ff00000 /* Minimum contention window mask */ #define AR5K_NODCU_RETRY_LMT_CW_MIN_S 20 /* * Transmit latency register */ #define AR5K_USEC_5210 0x8020 /* Register Address [5210] */ #define AR5K_USEC_5211 0x801c /* Register Address [5211+] */ #define AR5K_USEC (ah->ah_version == AR5K_AR5210 ? \ AR5K_USEC_5210 : AR5K_USEC_5211) #define AR5K_USEC_1 0x0000007f /* clock cycles for 1us */ #define AR5K_USEC_1_S 0 #define AR5K_USEC_32 0x00003f80 /* clock cycles for 1us while on 32Mhz clock */ #define AR5K_USEC_32_S 7 #define AR5K_USEC_TX_LATENCY_5211 0x007fc000 #define AR5K_USEC_TX_LATENCY_5211_S 14 #define AR5K_USEC_RX_LATENCY_5211 0x1f800000 #define AR5K_USEC_RX_LATENCY_5211_S 23 #define AR5K_USEC_TX_LATENCY_5210 0x000fc000 /* also for 5311 */ #define AR5K_USEC_TX_LATENCY_5210_S 14 #define AR5K_USEC_RX_LATENCY_5210 0x03f00000 /* also for 5311 */ #define AR5K_USEC_RX_LATENCY_5210_S 20 /* * PCU beacon control register */ #define AR5K_BEACON_5210 0x8024 /*Register Address [5210] */ #define AR5K_BEACON_5211 0x8020 /*Register Address [5211+] */ #define AR5K_BEACON (ah->ah_version == AR5K_AR5210 ? \ AR5K_BEACON_5210 : AR5K_BEACON_5211) #define AR5K_BEACON_PERIOD 0x0000ffff /* Mask for beacon period */ #define AR5K_BEACON_PERIOD_S 0 #define AR5K_BEACON_TIM 0x007f0000 /* Mask for TIM offset */ #define AR5K_BEACON_TIM_S 16 #define AR5K_BEACON_ENABLE 0x00800000 /* Enable beacons */ #define AR5K_BEACON_RESET_TSF 0x01000000 /* Force TSF reset */ /* * CFP period register */ #define AR5K_CFP_PERIOD_5210 0x8028 #define AR5K_CFP_PERIOD_5211 0x8024 #define AR5K_CFP_PERIOD (ah->ah_version == AR5K_AR5210 ? \ AR5K_CFP_PERIOD_5210 : AR5K_CFP_PERIOD_5211) /* * Next beacon time register */ #define AR5K_TIMER0_5210 0x802c #define AR5K_TIMER0_5211 0x8028 #define AR5K_TIMER0 (ah->ah_version == AR5K_AR5210 ? \ AR5K_TIMER0_5210 : AR5K_TIMER0_5211) /* * Next DMA beacon alert register */ #define AR5K_TIMER1_5210 0x8030 #define AR5K_TIMER1_5211 0x802c #define AR5K_TIMER1 (ah->ah_version == AR5K_AR5210 ? \ AR5K_TIMER1_5210 : AR5K_TIMER1_5211) /* * Next software beacon alert register */ #define AR5K_TIMER2_5210 0x8034 #define AR5K_TIMER2_5211 0x8030 #define AR5K_TIMER2 (ah->ah_version == AR5K_AR5210 ? \ AR5K_TIMER2_5210 : AR5K_TIMER2_5211) /* * Next ATIM window time register */ #define AR5K_TIMER3_5210 0x8038 #define AR5K_TIMER3_5211 0x8034 #define AR5K_TIMER3 (ah->ah_version == AR5K_AR5210 ? \ AR5K_TIMER3_5210 : AR5K_TIMER3_5211) /* * 5210 First inter frame spacing register (IFS) */ #define AR5K_IFS0 0x8040 #define AR5K_IFS0_SIFS 0x000007ff #define AR5K_IFS0_SIFS_S 0 #define AR5K_IFS0_DIFS 0x007ff800 #define AR5K_IFS0_DIFS_S 11 /* * 5210 Second inter frame spacing register (IFS) */ #define AR5K_IFS1 0x8044 #define AR5K_IFS1_PIFS 0x00000fff #define AR5K_IFS1_PIFS_S 0 #define AR5K_IFS1_EIFS 0x03fff000 #define AR5K_IFS1_EIFS_S 12 #define AR5K_IFS1_CS_EN 0x04000000 /* * CFP duration register */ #define AR5K_CFP_DUR_5210 0x8048 #define AR5K_CFP_DUR_5211 0x8038 #define AR5K_CFP_DUR (ah->ah_version == AR5K_AR5210 ? \ AR5K_CFP_DUR_5210 : AR5K_CFP_DUR_5211) /* * Receive filter register */ #define AR5K_RX_FILTER_5210 0x804c /* Register Address [5210] */ #define AR5K_RX_FILTER_5211 0x803c /* Register Address [5211+] */ #define AR5K_RX_FILTER (ah->ah_version == AR5K_AR5210 ? \ AR5K_RX_FILTER_5210 : AR5K_RX_FILTER_5211) #define AR5K_RX_FILTER_UCAST 0x00000001 /* Don't filter unicast frames */ #define AR5K_RX_FILTER_MCAST 0x00000002 /* Don't filter multicast frames */ #define AR5K_RX_FILTER_BCAST 0x00000004 /* Don't filter broadcast frames */ #define AR5K_RX_FILTER_CONTROL 0x00000008 /* Don't filter control frames */ #define AR5K_RX_FILTER_BEACON 0x00000010 /* Don't filter beacon frames */ #define AR5K_RX_FILTER_PROM 0x00000020 /* Set promiscuous mode */ #define AR5K_RX_FILTER_XRPOLL 0x00000040 /* Don't filter XR poll frame [5212+] */ #define AR5K_RX_FILTER_PROBEREQ 0x00000080 /* Don't filter probe requests [5212+] */ #define AR5K_RX_FILTER_PHYERR_5212 0x00000100 /* Don't filter phy errors [5212+] */ #define AR5K_RX_FILTER_RADARERR_5212 0x00000200 /* Don't filter phy radar errors [5212+] */ #define AR5K_RX_FILTER_PHYERR_5211 0x00000040 /* [5211] */ #define AR5K_RX_FILTER_RADARERR_5211 0x00000080 /* [5211] */ #define AR5K_RX_FILTER_PHYERR \ ((ah->ah_version == AR5K_AR5211 ? \ AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212)) #define AR5K_RX_FILTER_RADARERR \ ((ah->ah_version == AR5K_AR5211 ? \ AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212)) /* * Multicast filter register (lower 32 bits) */ #define AR5K_MCAST_FILTER0_5210 0x8050 #define AR5K_MCAST_FILTER0_5211 0x8040 #define AR5K_MCAST_FILTER0 (ah->ah_version == AR5K_AR5210 ? \ AR5K_MCAST_FILTER0_5210 : AR5K_MCAST_FILTER0_5211) /* * Multicast filter register (higher 16 bits) */ #define AR5K_MCAST_FILTER1_5210 0x8054 #define AR5K_MCAST_FILTER1_5211 0x8044 #define AR5K_MCAST_FILTER1 (ah->ah_version == AR5K_AR5210 ? \ AR5K_MCAST_FILTER1_5210 : AR5K_MCAST_FILTER1_5211) /* * Transmit mask register (lower 32 bits) [5210] */ #define AR5K_TX_MASK0 0x8058 /* * Transmit mask register (higher 16 bits) [5210] */ #define AR5K_TX_MASK1 0x805c /* * Clear transmit mask [5210] */ #define AR5K_CLR_TMASK 0x8060 /* * Trigger level register (before transmission) [5210] */ #define AR5K_TRIG_LVL 0x8064 /* * PCU control register * * Only DIS_RX is used in the code, the rest i guess are * for tweaking/diagnostics. */ #define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */ #define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */ #define AR5K_DIAG_SW (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_5210 : AR5K_DIAG_SW_5211) #define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001 /* Disable ACKs if WEP key is invalid */ #define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs */ #define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs */ #define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable encryption */ #define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable decryption */ #define AR5K_DIAG_SW_DIS_TX 0x00000020 /* Disable transmit [5210] */ #define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable recieve */ #define AR5K_DIAG_SW_DIS_RX_5211 0x00000020 #define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211) #define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* Loopback (i guess it goes with DIS_TX) [5210] */ #define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040 #define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211) #define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Corrupted FCS */ #define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080 #define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211) #define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Dump channel info */ #define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100 #define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211) #define AR5K_DIAG_SW_EN_SCRAM_SEED_5210 0x00000400 /* Enable fixed scrambler seed */ #define AR5K_DIAG_SW_EN_SCRAM_SEED_5211 0x00000200 #define AR5K_DIAG_SW_EN_SCRAM_SEED (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211) #define AR5K_DIAG_SW_ECO_ENABLE 0x00000400 /* [5211+] */ #define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */ #define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask */ #define AR5K_DIAG_SW_SCRAM_SEED_S 10 #define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */ #define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000 #define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */ #define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211) #define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */ #define AR5K_DIAG_SW_OBSPT_S 18 #define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x0010000 /* Force RX Clear high */ #define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000 /* Ignore virtual carrier sense */ #define AR5K_DIAG_SW_CHANEL_IDLE_HIGH 0x0040000 /* Force channel idle high */ #define AR5K_DIAG_SW_PHEAR_ME 0x0080000 /* ??? */ /* * TSF (clock) register (lower 32 bits) */ #define AR5K_TSF_L32_5210 0x806c #define AR5K_TSF_L32_5211 0x804c #define AR5K_TSF_L32 (ah->ah_version == AR5K_AR5210 ? \ AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211) /* * TSF (clock) register (higher 32 bits) */ #define AR5K_TSF_U32_5210 0x8070 #define AR5K_TSF_U32_5211 0x8050 #define AR5K_TSF_U32 (ah->ah_version == AR5K_AR5210 ? \ AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211) /* * Last beacon timestamp register (Read Only) */ #define AR5K_LAST_TSTP 0x8080 /* * ADDAC test register [5211+] */ #define AR5K_ADDAC_TEST 0x8054 /* Register Address */ #define AR5K_ADDAC_TEST_TXCONT 0x00000001 /* Test continuous tx */ #define AR5K_ADDAC_TEST_TST_MODE 0x00000002 /* Test mode */ #define AR5K_ADDAC_TEST_LOOP_EN 0x00000004 /* Enable loop */ #define AR5K_ADDAC_TEST_LOOP_LEN 0x00000008 /* Loop length (field) */ #define AR5K_ADDAC_TEST_USE_U8 0x00004000 /* Use upper 8 bits */ #define AR5K_ADDAC_TEST_MSB 0x00008000 /* State of MSB */ #define AR5K_ADDAC_TEST_TRIG_SEL 0x00010000 /* Trigger select */ #define AR5K_ADDAC_TEST_TRIG_PTY 0x00020000 /* Trigger polarity */ #define AR5K_ADDAC_TEST_RXCONT 0x00040000 /* Continuous capture */ #define AR5K_ADDAC_TEST_CAPTURE 0x00080000 /* Begin capture */ #define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* ARM rx buffer for capture */ /* * Default antenna register [5211+] */ #define AR5K_DEFAULT_ANTENNA 0x8058 /* * Frame control QoS mask register (?) [5211+] * (FC_QOS_MASK) */ #define AR5K_FRAME_CTL_QOSM 0x805c /* * Seq mask register (?) [5211+] */ #define AR5K_SEQ_MASK 0x8060 /* * Retry count register [5210] */ #define AR5K_RETRY_CNT 0x8084 /* Register Address [5210] */ #define AR5K_RETRY_CNT_SSH 0x0000003f /* Station short retry count (?) */ #define AR5K_RETRY_CNT_SLG 0x00000fc0 /* Station long retry count (?) */ /* * Back-off status register [5210] */ #define AR5K_BACKOFF 0x8088 /* Register Address [5210] */ #define AR5K_BACKOFF_CW 0x000003ff /* Backoff Contention Window (?) */ #define AR5K_BACKOFF_CNT 0x03ff0000 /* Backoff count (?) */ /* * NAV register (current) */ #define AR5K_NAV_5210 0x808c #define AR5K_NAV_5211 0x8084 #define AR5K_NAV (ah->ah_version == AR5K_AR5210 ? \ AR5K_NAV_5210 : AR5K_NAV_5211) /* * RTS success register */ #define AR5K_RTS_OK_5210 0x8090 #define AR5K_RTS_OK_5211 0x8088 #define AR5K_RTS_OK (ah->ah_version == AR5K_AR5210 ? \ AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211) /* * RTS failure register */ #define AR5K_RTS_FAIL_5210 0x8094 #define AR5K_RTS_FAIL_5211 0x808c #define AR5K_RTS_FAIL (ah->ah_version == AR5K_AR5210 ? \ AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211) /* * ACK failure register */ #define AR5K_ACK_FAIL_5210 0x8098 #define AR5K_ACK_FAIL_5211 0x8090 #define AR5K_ACK_FAIL (ah->ah_version == AR5K_AR5210 ? \ AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211) /* * FCS failure register */ #define AR5K_FCS_FAIL_5210 0x809c #define AR5K_FCS_FAIL_5211 0x8094 #define AR5K_FCS_FAIL (ah->ah_version == AR5K_AR5210 ? \ AR5K_FCS_FAIL_5210 : AR5K_FCS_FAIL_5211) /* * Beacon count register */ #define AR5K_BEACON_CNT_5210 0x80a0 #define AR5K_BEACON_CNT_5211 0x8098 #define AR5K_BEACON_CNT (ah->ah_version == AR5K_AR5210 ? \ AR5K_BEACON_CNT_5210 : AR5K_BEACON_CNT_5211) /*===5212 Specific PCU registers===*/ /* * Transmit power control register */ #define AR5K_TPC 0x80e8 #define AR5K_TPC_ACK 0x0000003f /* ack frames */ #define AR5K_TPC_ACK_S 0 #define AR5K_TPC_CTS 0x00003f00 /* cts frames */ #define AR5K_TPC_CTS_S 8 #define AR5K_TPC_CHIRP 0x003f0000 /* chirp frames */ #define AR5K_TPC_CHIRP_S 16 #define AR5K_TPC_DOPPLER 0x0f000000 /* doppler chirp span */ #define AR5K_TPC_DOPPLER_S 24 /* * XR (eXtended Range) mode register */ #define AR5K_XRMODE 0x80c0 /* Register Address */ #define AR5K_XRMODE_POLL_TYPE_M 0x0000003f /* Mask for Poll type (?) */ #define AR5K_XRMODE_POLL_TYPE_S 0 #define AR5K_XRMODE_POLL_SUBTYPE_M 0x0000003c /* Mask for Poll subtype (?) */ #define AR5K_XRMODE_POLL_SUBTYPE_S 2 #define AR5K_XRMODE_POLL_WAIT_ALL 0x00000080 /* Wait for poll */ #define AR5K_XRMODE_SIFS_DELAY 0x000fff00 /* Mask for SIFS delay */ #define AR5K_XRMODE_FRAME_HOLD_M 0xfff00000 /* Mask for frame hold (?) */ #define AR5K_XRMODE_FRAME_HOLD_S 20 /* * XR delay register */ #define AR5K_XRDELAY 0x80c4 /* Register Address */ #define AR5K_XRDELAY_SLOT_DELAY_M 0x0000ffff /* Mask for slot delay */ #define AR5K_XRDELAY_SLOT_DELAY_S 0 #define AR5K_XRDELAY_CHIRP_DELAY_M 0xffff0000 /* Mask for CHIRP data delay */ #define AR5K_XRDELAY_CHIRP_DELAY_S 16 /* * XR timeout register */ #define AR5K_XRTIMEOUT 0x80c8 /* Register Address */ #define AR5K_XRTIMEOUT_CHIRP_M 0x0000ffff /* Mask for CHIRP timeout */ #define AR5K_XRTIMEOUT_CHIRP_S 0 #define AR5K_XRTIMEOUT_POLL_M 0xffff0000 /* Mask for Poll timeout */ #define AR5K_XRTIMEOUT_POLL_S 16 /* * XR chirp register */ #define AR5K_XRCHIRP 0x80cc /* Register Address */ #define AR5K_XRCHIRP_SEND 0x00000001 /* Send CHIRP */ #define AR5K_XRCHIRP_GAP 0xffff0000 /* Mask for CHIRP gap (?) */ /* * XR stomp register */ #define AR5K_XRSTOMP 0x80d0 /* Register Address */ #define AR5K_XRSTOMP_TX 0x00000001 /* Stomp Tx (?) */ #define AR5K_XRSTOMP_RX 0x00000002 /* Stomp Rx (?) */ #define AR5K_XRSTOMP_TX_RSSI 0x00000004 /* Stomp Tx RSSI (?) */ #define AR5K_XRSTOMP_TX_BSSID 0x00000008 /* Stomp Tx BSSID (?) */ #define AR5K_XRSTOMP_DATA 0x00000010 /* Stomp data (?)*/ #define AR5K_XRSTOMP_RSSI_THRES 0x0000ff00 /* Mask for XR RSSI threshold */ /* * First enhanced sleep register */ #define AR5K_SLEEP0 0x80d4 /* Register Address */ #define AR5K_SLEEP0_NEXT_DTIM 0x0007ffff /* Mask for next DTIM (?) */ #define AR5K_SLEEP0_NEXT_DTIM_S 0 #define AR5K_SLEEP0_ASSUME_DTIM 0x00080000 /* Assume DTIM */ #define AR5K_SLEEP0_ENH_SLEEP_EN 0x00100000 /* Enable enchanced sleep control */ #define AR5K_SLEEP0_CABTO 0xff000000 /* Mask for CAB Time Out */ #define AR5K_SLEEP0_CABTO_S 24 /* * Second enhanced sleep register */ #define AR5K_SLEEP1 0x80d8 /* Register Address */ #define AR5K_SLEEP1_NEXT_TIM 0x0007ffff /* Mask for next TIM (?) */ #define AR5K_SLEEP1_NEXT_TIM_S 0 #define AR5K_SLEEP1_BEACON_TO 0xff000000 /* Mask for Beacon Time Out */ #define AR5K_SLEEP1_BEACON_TO_S 24 /* * Third enhanced sleep register */ #define AR5K_SLEEP2 0x80dc /* Register Address */ #define AR5K_SLEEP2_TIM_PER 0x0000ffff /* Mask for TIM period (?) */ #define AR5K_SLEEP2_TIM_PER_S 0 #define AR5K_SLEEP2_DTIM_PER 0xffff0000 /* Mask for DTIM period (?) */ #define AR5K_SLEEP2_DTIM_PER_S 16 /* * BSSID mask registers */ #define AR5K_BSS_IDM0 0x80e0 /* Upper bits */ #define AR5K_BSS_IDM1 0x80e4 /* Lower bits */ /* * TX power control (TPC) register * * XXX: PCDAC steps (0.5dbm) or DBM ? * */ #define AR5K_TXPC 0x80e8 /* Register Address */ #define AR5K_TXPC_ACK_M 0x0000003f /* ACK tx power */ #define AR5K_TXPC_ACK_S 0 #define AR5K_TXPC_CTS_M 0x00003f00 /* CTS tx power */ #define AR5K_TXPC_CTS_S 8 #define AR5K_TXPC_CHIRP_M 0x003f0000 /* CHIRP tx power */ #define AR5K_TXPC_CHIRP_S 16 #define AR5K_TXPC_DOPPLER 0x0f000000 /* Doppler chirp span (?) */ #define AR5K_TXPC_DOPPLER_S 24 /* * Profile count registers */ #define AR5K_PROFCNT_TX 0x80ec /* Tx count */ #define AR5K_PROFCNT_RX 0x80f0 /* Rx count */ #define AR5K_PROFCNT_RXCLR 0x80f4 /* Clear Rx count */ #define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle count (?) */ /* * Quiet period control registers */ #define AR5K_QUIET_CTL1 0x80fc /* Register Address */ #define AR5K_QUIET_CTL1_NEXT_QT_TSF 0x0000ffff /* Next quiet period TSF (TU) */ #define AR5K_QUIET_CTL1_NEXT_QT_TSF_S 0 #define AR5K_QUIET_CTL1_QT_EN 0x00010000 /* Enable quiet period */ #define AR5K_QUIET_CTL1_ACK_CTS_EN 0x00020000 /* Send ACK/CTS during quiet period */ #define AR5K_QUIET_CTL2 0x8100 /* Register Address */ #define AR5K_QUIET_CTL2_QT_PER 0x0000ffff /* Mask for quiet period periodicity */ #define AR5K_QUIET_CTL2_QT_PER_S 0 #define AR5K_QUIET_CTL2_QT_DUR 0xffff0000 /* Mask for quiet period duration */ #define AR5K_QUIET_CTL2_QT_DUR_S 16 /* * TSF parameter register */ #define AR5K_TSF_PARM 0x8104 /* Register Address */ #define AR5K_TSF_PARM_INC 0x000000ff /* Mask for TSF increment */ #define AR5K_TSF_PARM_INC_S 0 /* * QoS NOACK policy */ #define AR5K_QOS_NOACK 0x8108 /* Register Address */ #define AR5K_QOS_NOACK_2BIT_VALUES 0x0000000f /* ??? */ #define AR5K_QOS_NOACK_2BIT_VALUES_S 0 #define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */ #define AR5K_QOS_NOACK_BIT_OFFSET_S 4 #define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */ #define AR5K_QOS_NOACK_BYTE_OFFSET_S 7 /* * PHY error filter register */ #define AR5K_PHY_ERR_FIL 0x810c #define AR5K_PHY_ERR_FIL_RADAR 0x00000020 /* Radar signal */ #define AR5K_PHY_ERR_FIL_OFDM 0x00020000 /* OFDM false detect (ANI) */ #define AR5K_PHY_ERR_FIL_CCK 0x02000000 /* CCK false detect (ANI) */ /* * XR latency register */ #define AR5K_XRLAT_TX 0x8110 /* * ACK SIFS register */ #define AR5K_ACKSIFS 0x8114 /* Register Address */ #define AR5K_ACKSIFS_INC 0x00000000 /* ACK SIFS Increment (field) */ /* * MIC QoS control register (?) */ #define AR5K_MIC_QOS_CTL 0x8118 /* Register Address */ #define AR5K_MIC_QOS_CTL_OFF(_n) (1 << (_n * 2)) #define AR5K_MIC_QOS_CTL_MQ_EN 0x00010000 /* Enable MIC QoS */ /* * MIC QoS select register (?) */ #define AR5K_MIC_QOS_SEL 0x811c #define AR5K_MIC_QOS_SEL_OFF(_n) (1 << (_n * 4)) /* * Misc mode control register (?) */ #define AR5K_MISC_MODE 0x8120 /* Register Address */ #define AR5K_MISC_MODE_FBSSID_MATCH 0x00000001 /* Force BSSID match */ #define AR5K_MISC_MODE_ACKSIFS_MEM 0x00000002 /* ACK SIFS memory (?) */ #define AR5K_MISC_MODE_COMBINED_MIC 0x00000004 /* use rx/tx MIC key */ /* more bits */ /* * OFDM Filter counter */ #define AR5K_OFDM_FIL_CNT 0x8124 /* * CCK Filter counter */ #define AR5K_CCK_FIL_CNT 0x8128 /* * PHY Error Counters (?) */ #define AR5K_PHYERR_CNT1 0x812c #define AR5K_PHYERR_CNT1_MASK 0x8130 #define AR5K_PHYERR_CNT2 0x8134 #define AR5K_PHYERR_CNT2_MASK 0x8138 /* * TSF Threshold register (?) */ #define AR5K_TSF_THRES 0x813c /* * TODO: Wake On Wireless registers * Range: 0x8147 - 0x818c */ /* * Rate -> ACK SIFS mapping table (32 entries) */ #define AR5K_RATE_ACKSIFS_BASE 0x8680 /* Register Address */ #define AR5K_RATE_ACKSIFS(_n) (AR5K_RATE_ACKSIFS_BSE + ((_n) << 2)) #define AR5K_RATE_ACKSIFS_NORMAL 0x00000001 /* Normal SIFS (field) */ #define AR5K_RATE_ACKSIFS_TURBO 0x00000400 /* Turbo SIFS (field) */ /* * Rate -> duration mapping table (32 entries) */ #define AR5K_RATE_DUR_BASE 0x8700 #define AR5K_RATE_DUR(_n) (AR5K_RATE_DUR_BASE + ((_n) << 2)) /* * Rate -> db mapping table * (8 entries, each one has 4 8bit fields) */ #define AR5K_RATE2DB_BASE 0x87c0 #define AR5K_RATE2DB(_n) (AR5K_RATE2DB_BASE + ((_n) << 2)) /* * db -> Rate mapping table * (8 entries, each one has 4 8bit fields) */ #define AR5K_DB2RATE_BASE 0x87e0 #define AR5K_DB2RATE(_n) (AR5K_DB2RATE_BASE + ((_n) << 2)) /*===5212 end===*/ /* * Key table (WEP) register */ #define AR5K_KEYTABLE_0_5210 0x9000 #define AR5K_KEYTABLE_0_5211 0x8800 #define AR5K_KEYTABLE_5210(_n) (AR5K_KEYTABLE_0_5210 + ((_n) << 5)) #define AR5K_KEYTABLE_5211(_n) (AR5K_KEYTABLE_0_5211 + ((_n) << 5)) #define AR5K_KEYTABLE(_n) (ah->ah_version == AR5K_AR5210 ? \ AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n)) #define AR5K_KEYTABLE_OFF(_n, x) (AR5K_KEYTABLE(_n) + (x << 2)) #define AR5K_KEYTABLE_TYPE(_n) AR5K_KEYTABLE_OFF(_n, 5) #define AR5K_KEYTABLE_TYPE_40 0x00000000 #define AR5K_KEYTABLE_TYPE_104 0x00000001 #define AR5K_KEYTABLE_TYPE_128 0x00000003 #define AR5K_KEYTABLE_TYPE_TKIP 0x00000004 /* [5212+] */ #define AR5K_KEYTABLE_TYPE_AES 0x00000005 /* [5211+] */ #define AR5K_KEYTABLE_TYPE_CCM 0x00000006 /* [5212+] */ #define AR5K_KEYTABLE_TYPE_NULL 0x00000007 /* [5211+] */ #define AR5K_KEYTABLE_ANTENNA 0x00000008 /* [5212+] */ #define AR5K_KEYTABLE_MAC0(_n) AR5K_KEYTABLE_OFF(_n, 6) #define AR5K_KEYTABLE_MAC1(_n) AR5K_KEYTABLE_OFF(_n, 7) #define AR5K_KEYTABLE_VALID 0x00008000 /* If key type is TKIP and MIC is enabled * MIC key goes in offset entry + 64 */ #define AR5K_KEYTABLE_MIC_OFFSET 64 /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit * * Some vendors have introduced bigger WEP keys to address * security vulnerabilities in WEP. This includes: * * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit * * We can expand this if we find ar5k Atheros cards with a larger * key table size. */ #define AR5K_KEYTABLE_SIZE_5210 64 #define AR5K_KEYTABLE_SIZE_5211 128 #define AR5K_KEYTABLE_SIZE (ah->ah_version == AR5K_AR5210 ? \ AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211) /*===PHY REGISTERS===*/ /* * PHY registers start */ #define AR5K_PHY_BASE 0x9800 #define AR5K_PHY(_n) (AR5K_PHY_BASE + ((_n) << 2)) /* * TST_2 (Misc config parameters) */ #define AR5K_PHY_TST2 0x9800 /* Register Address */ #define AR5K_PHY_TST2_TRIG_SEL 0x00000007 /* Trigger select (?)*/ #define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) */ #define AR5K_PHY_TST2_CBUS_MODE 0x00000060 /* Cardbus mode (?) */ #define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32Khz external) */ #define AR5K_PHY_TST2_CHANCOR_DUMP_EN 0x00000800 /* Enable Chancor dump (?) */ #define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP 0x00001000 /* Even Chancor dump (?) */ #define AR5K_PHY_TST2_RFSILENT_EN 0x00002000 /* Enable RFSILENT */ #define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch ?) */ #define AR5K_PHY_TST2_MINI_OBS_EN 0x00008000 /* Enable mini OBS (?) */ #define AR5K_PHY_TST2_RX2_IS_RX5_INV 0x00010000 /* 2GHz rx path is the 5GHz path inverted (?) */ #define AR5K_PHY_TST2_SLOW_CLK160 0x00020000 /* Slow CLK160 (?) */ #define AR5K_PHY_TST2_AGC_OBS_SEL_3 0x00040000 /* AGC OBS Select 3 (?) */ #define AR5K_PHY_TST2_BBB_OBS_SEL 0x00080000 /* BB OBS Select (field ?) */ #define AR5K_PHY_TST2_ADC_OBS_SEL 0x00800000 /* ADC OBS Select (field ?) */ #define AR5K_PHY_TST2_RX_CLR_SEL 0x08000000 /* RX Clear Select (?) */ #define AR5K_PHY_TST2_FORCE_AGC_CLR 0x10000000 /* Force AGC clear (?) */ #define AR5K_PHY_SHIFT_2GHZ 0x00004007 /* Used to access 2GHz radios */ #define AR5K_PHY_SHIFT_5GHZ 0x00000007 /* Used to access 5GHz radios (default) */ /* * PHY frame control register [5110] /turbo mode register [5111+] * * There is another frame control register for [5111+] * at address 0x9944 (see below) but the 2 first flags * are common here between 5110 frame control register * and [5111+] turbo mode register, so this also works as * a "turbo mode register" for 5110. We treat this one as * a frame control register for 5110 below. */ #define AR5K_PHY_TURBO 0x9804 /* Register Address */ #define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */ #define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */ #define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo mimo */ /* * PHY agility command register * (aka TST_1) */ #define AR5K_PHY_AGC 0x9808 /* Register Address */ #define AR5K_PHY_TST1 0x9808 #define AR5K_PHY_AGC_DISABLE 0x08000000 /* Disable AGC to A2 (?)*/ #define AR5K_PHY_TST1_TXHOLD 0x00003800 /* Set tx hold (?) */ #define AR5K_PHY_TST1_TXSRC_SRC 0x00000002 /* Used with bit 7 (?) */ #define AR5K_PHY_TST1_TXSRC_SRC_S 1 #define AR5K_PHY_TST1_TXSRC_ALT 0x00000080 /* Set input to tsdac (?) */ #define AR5K_PHY_TST1_TXSRC_ALT_S 7 /* * PHY timing register 3 [5112+] */ #define AR5K_PHY_TIMING_3 0x9814 #define AR5K_PHY_TIMING_3_DSC_MAN 0xfffe0000 #define AR5K_PHY_TIMING_3_DSC_MAN_S 17 #define AR5K_PHY_TIMING_3_DSC_EXP 0x0001e000 #define AR5K_PHY_TIMING_3_DSC_EXP_S 13 /* * PHY chip revision register */ #define AR5K_PHY_CHIP_ID 0x9818 /* * PHY activation register */ #define AR5K_PHY_ACT 0x981c /* Register Address */ #define AR5K_PHY_ACT_ENABLE 0x00000001 /* Activate PHY */ #define AR5K_PHY_ACT_DISABLE 0x00000002 /* Deactivate PHY */ /* * PHY RF control registers */ #define AR5K_PHY_RF_CTL2 0x9824 /* Register Address */ #define AR5K_PHY_RF_CTL2_TXF2TXD_START 0x0000000f /* TX frame to TX data start */ #define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0 #define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */ #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000ff00 /* TX end to XLNA on */ #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 8 #define AR5K_PHY_ADC_CTL 0x982c #define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003 #define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF_S 0 #define AR5K_PHY_ADC_CTL_PWD_DAC_OFF 0x00002000 #define AR5K_PHY_ADC_CTL_PWD_BAND_GAP_OFF 0x00004000 #define AR5K_PHY_ADC_CTL_PWD_ADC_OFF 0x00008000 #define AR5K_PHY_ADC_CTL_INBUFGAIN_ON 0x00030000 #define AR5K_PHY_ADC_CTL_INBUFGAIN_ON_S 16 #define AR5K_PHY_RF_CTL4 0x9834 /* Register Address */ #define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON 0x00000001 /* TX frame to XPA A on (field) */ #define AR5K_PHY_RF_CTL4_TXF2XPA_B_ON 0x00000100 /* TX frame to XPA B on (field) */ #define AR5K_PHY_RF_CTL4_TXE2XPA_A_OFF 0x00010000 /* TX end to XPA A off (field) */ #define AR5K_PHY_RF_CTL4_TXE2XPA_B_OFF 0x01000000 /* TX end to XPA B off (field) */ /* * Pre-Amplifier control register * (XPA -> external pre-amplifier) */ #define AR5K_PHY_PA_CTL 0x9838 /* Register Address */ #define AR5K_PHY_PA_CTL_XPA_A_HI 0x00000001 /* XPA A high (?) */ #define AR5K_PHY_PA_CTL_XPA_B_HI 0x00000002 /* XPA B high (?) */ #define AR5K_PHY_PA_CTL_XPA_A_EN 0x00000004 /* Enable XPA A */ #define AR5K_PHY_PA_CTL_XPA_B_EN 0x00000008 /* Enable XPA B */ /* * PHY settling register */ #define AR5K_PHY_SETTLING 0x9844 /* Register Address */ #define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ #define AR5K_PHY_SETTLING_AGC_S 0 #define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ #define AR5K_PHY_SETTLING_SWITCH_S 7 /* * PHY Gain registers */ #define AR5K_PHY_GAIN 0x9848 /* Register Address */ #define AR5K_PHY_GAIN_TXRX_ATTEN 0x0003f000 /* TX-RX Attenuation */ #define AR5K_PHY_GAIN_TXRX_ATTEN_S 12 #define AR5K_PHY_GAIN_TXRX_RF_MAX 0x007c0000 #define AR5K_PHY_GAIN_TXRX_RF_MAX_S 18 #define AR5K_PHY_GAIN_OFFSET 0x984c /* Register Address */ #define AR5K_PHY_GAIN_OFFSET_RXTX_FLAG 0x00020000 /* RX-TX flag (?) */ /* * Desired ADC/PGA size register * (for more infos read ANI patent) */ #define AR5K_PHY_DESIRED_SIZE 0x9850 /* Register Address */ #define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* ADC desired size */ #define AR5K_PHY_DESIRED_SIZE_ADC_S 0 #define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* PGA desired size */ #define AR5K_PHY_DESIRED_SIZE_PGA_S 8 #define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Total desired size */ #define AR5K_PHY_DESIRED_SIZE_TOT_S 20 /* * PHY signal register * (for more infos read ANI patent) */ #define AR5K_PHY_SIG 0x9858 /* Register Address */ #define AR5K_PHY_SIG_FIRSTEP 0x0003f000 /* FIRSTEP */ #define AR5K_PHY_SIG_FIRSTEP_S 12 #define AR5K_PHY_SIG_FIRPWR 0x03fc0000 /* FIPWR */ #define AR5K_PHY_SIG_FIRPWR_S 18 /* * PHY coarse agility control register * (for more infos read ANI patent) */ #define AR5K_PHY_AGCCOARSE 0x985c /* Register Address */ #define AR5K_PHY_AGCCOARSE_LO 0x00007f80 /* AGC Coarse low */ #define AR5K_PHY_AGCCOARSE_LO_S 7 #define AR5K_PHY_AGCCOARSE_HI 0x003f8000 /* AGC Coarse high */ #define AR5K_PHY_AGCCOARSE_HI_S 15 /* * PHY agility control register */ #define AR5K_PHY_AGCCTL 0x9860 /* Register address */ #define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */ #define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */ #define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */ #define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */ /* * PHY noise floor status register */ #define AR5K_PHY_NF 0x9864 /* Register address */ #define AR5K_PHY_NF_M 0x000001ff /* Noise floor mask */ #define AR5K_PHY_NF_ACTIVE 0x00000100 /* Noise floor calibration still active */ #define AR5K_PHY_NF_RVAL(_n) (((_n) >> 19) & AR5K_PHY_NF_M) #define AR5K_PHY_NF_AVAL(_n) (-((_n) ^ AR5K_PHY_NF_M) + 1) #define AR5K_PHY_NF_SVAL(_n) (((_n) & AR5K_PHY_NF_M) | (1 << 9)) #define AR5K_PHY_NF_THRESH62 0x0007f000 /* Thresh62 -check ANI patent- (field) */ #define AR5K_PHY_NF_THRESH62_S 12 #define AR5K_PHY_NF_MINCCA_PWR 0x0ff80000 /* ??? */ #define AR5K_PHY_NF_MINCCA_PWR_S 19 /* * PHY ADC saturation register [5110] */ #define AR5K_PHY_ADCSAT 0x9868 #define AR5K_PHY_ADCSAT_ICNT 0x0001f800 #define AR5K_PHY_ADCSAT_ICNT_S 11 #define AR5K_PHY_ADCSAT_THR 0x000007e0 #define AR5K_PHY_ADCSAT_THR_S 5 /* * PHY Weak ofdm signal detection threshold registers (ANI) [5212+] */ /* High thresholds */ #define AR5K_PHY_WEAK_OFDM_HIGH_THR 0x9868 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT 0x0000001f #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT_S 0 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1 0x00fe0000 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1_S 17 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2 0x7f000000 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_S 24 /* Low thresholds */ #define AR5K_PHY_WEAK_OFDM_LOW_THR 0x986c #define AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN 0x00000001 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT 0x00003f00 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT_S 8 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M1 0x001fc000 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M1_S 14 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2 0x0fe00000 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_S 21 /* * PHY sleep registers [5112+] */ #define AR5K_PHY_SCR 0x9870 #define AR5K_PHY_SLMT 0x9874 #define AR5K_PHY_SLMT_32MHZ 0x0000007f #define AR5K_PHY_SCAL 0x9878 #define AR5K_PHY_SCAL_32MHZ 0x0000000e #define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a #define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032 /* * PHY PLL (Phase Locked Loop) control register */ #define AR5K_PHY_PLL 0x987c #define AR5K_PHY_PLL_20MHZ 0x00000013 /* For half rate (?) */ /* 40MHz -> 5GHz band */ #define AR5K_PHY_PLL_40MHZ_5211 0x00000018 #define AR5K_PHY_PLL_40MHZ_5212 0x000000aa #define AR5K_PHY_PLL_40MHZ_5413 0x00000004 #define AR5K_PHY_PLL_40MHZ (ah->ah_version == AR5K_AR5211 ? \ AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212) /* 44MHz -> 2.4GHz band */ #define AR5K_PHY_PLL_44MHZ_5211 0x00000019 #define AR5K_PHY_PLL_44MHZ_5212 0x000000ab #define AR5K_PHY_PLL_44MHZ (ah->ah_version == AR5K_AR5211 ? \ AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212) #define AR5K_PHY_PLL_RF5111 0x00000000 #define AR5K_PHY_PLL_RF5112 0x00000040 #define AR5K_PHY_PLL_HALF_RATE 0x00000100 #define AR5K_PHY_PLL_QUARTER_RATE 0x00000200 /* * RF Buffer register * * It's obvious from the code that 0x989c is the buffer register but * for the other special registers that we write to after sending each * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers * for now. It's interesting that they are also used for some other operations. */ #define AR5K_RF_BUFFER 0x989c #define AR5K_RF_BUFFER_CONTROL_0 0x98c0 /* Channel on 5110 */ #define AR5K_RF_BUFFER_CONTROL_1 0x98c4 /* Bank 7 on 5112 */ #define AR5K_RF_BUFFER_CONTROL_2 0x98cc /* Bank 7 on 5111 */ #define AR5K_RF_BUFFER_CONTROL_3 0x98d0 /* Bank 2 on 5112 */ /* Channel set on 5111 */ /* Used to read radio revision*/ #define AR5K_RF_BUFFER_CONTROL_4 0x98d4 /* RF Stage register on 5110 */ /* Bank 0,1,2,6 on 5111 */ /* Bank 1 on 5112 */ /* Used during activation on 5111 */ #define AR5K_RF_BUFFER_CONTROL_5 0x98d8 /* Bank 3 on 5111 */ /* Used during activation on 5111 */ /* Channel on 5112 */ /* Bank 6 on 5112 */ #define AR5K_RF_BUFFER_CONTROL_6 0x98dc /* Bank 3 on 5112 */ /* * PHY RF stage register [5210] */ #define AR5K_PHY_RFSTG 0x98d4 #define AR5K_PHY_RFSTG_DISABLE 0x00000021 /* * BIN masks (?) */ #define AR5K_PHY_BIN_MASK_1 0x9900 #define AR5K_PHY_BIN_MASK_2 0x9904 #define AR5K_PHY_BIN_MASK_3 0x9908 #define AR5K_PHY_BIN_MASK_CTL 0x990c #define AR5K_PHY_BIN_MASK_CTL_MASK_4 0x00003fff #define AR5K_PHY_BIN_MASK_CTL_MASK_4_S 0 #define AR5K_PHY_BIN_MASK_CTL_RATE 0xff000000 #define AR5K_PHY_BIN_MASK_CTL_RATE_S 24 /* * PHY Antenna control register */ #define AR5K_PHY_ANT_CTL 0x9910 /* Register Address */ #define AR5K_PHY_ANT_CTL_TXRX_EN 0x00000001 /* Enable TX/RX (?) */ #define AR5K_PHY_ANT_CTL_SECTORED_ANT 0x00000004 /* Sectored Antenna */ #define AR5K_PHY_ANT_CTL_HITUNE5 0x00000008 /* Hitune5 (?) */ #define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x000003f0 /* Switch table idle (?) */ #define AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4 /* * PHY receiver delay register [5111+] */ #define AR5K_PHY_RX_DELAY 0x9914 /* Register Address */ #define AR5K_PHY_RX_DELAY_M 0x00003fff /* Mask for RX activate to receive delay (/100ns) */ /* * PHY max rx length register (?) [5111] */ #define AR5K_PHY_MAX_RX_LEN 0x991c /* * PHY timing register 4 * I(nphase)/Q(adrature) calibration register [5111+] */ #define AR5K_PHY_IQ 0x9920 /* Register Address */ #define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */ #define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */ #define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5 #define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */ #define AR5K_PHY_IQ_CAL_NUM_LOG_MAX 0x0000f000 /* Mask for max number of samples in log scale */ #define AR5K_PHY_IQ_CAL_NUM_LOG_MAX_S 12 #define AR5K_PHY_IQ_RUN 0x00010000 /* Run i/q calibration */ #define AR5K_PHY_IQ_USE_PT_DF 0x00020000 /* Use pilot track df (?) */ #define AR5K_PHY_IQ_EARLY_TRIG_THR 0x00200000 /* Early trigger threshold (?) (field) */ #define AR5K_PHY_IQ_PILOT_MASK_EN 0x10000000 /* Enable pilot mask (?) */ #define AR5K_PHY_IQ_CHAN_MASK_EN 0x20000000 /* Enable channel mask (?) */ #define AR5K_PHY_IQ_SPUR_FILT_EN 0x40000000 /* Enable spur filter */ #define AR5K_PHY_IQ_SPUR_RSSI_EN 0x80000000 /* Enable spur rssi */ /* * PHY timing register 5 * OFDM Self-correlator Cyclic RSSI threshold params * (Check out bb_cycpwr_thr1 on ANI patent) */ #define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */ #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */ #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */ #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 1 #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */ #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */ #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */ #define AR5K_PHY_OFDM_SELFCORR_LSCTHR_HIRSSI 0x00800000 /* Long sc threshold hi rssi (?) */ /* * PHY-only warm reset register */ #define AR5K_PHY_WARM_RESET 0x9928 /* * PHY-only control register */ #define AR5K_PHY_CTL 0x992c /* Register Address */ #define AR5K_PHY_CTL_RX_DRAIN_RATE 0x00000001 /* RX drain rate (?) */ #define AR5K_PHY_CTL_LATE_TX_SIG_SYM 0x00000002 /* Late tx signal symbol (?) */ #define AR5K_PHY_CTL_GEN_SCRAMBLER 0x00000004 /* Generate scrambler */ #define AR5K_PHY_CTL_TX_ANT_SEL 0x00000008 /* TX antenna select */ #define AR5K_PHY_CTL_TX_ANT_STATIC 0x00000010 /* Static TX antenna */ #define AR5K_PHY_CTL_RX_ANT_SEL 0x00000020 /* RX antenna select */ #define AR5K_PHY_CTL_RX_ANT_STATIC 0x00000040 /* Static RX antenna */ #define AR5K_PHY_CTL_LOW_FREQ_SLE_EN 0x00000080 /* Enable low freq sleep */ /* * PHY PAPD probe register [5111+] */ #define AR5K_PHY_PAPD_PROBE 0x9930 #define AR5K_PHY_PAPD_PROBE_SH_HI_PAR 0x00000001 #define AR5K_PHY_PAPD_PROBE_PCDAC_BIAS 0x00000002 #define AR5K_PHY_PAPD_PROBE_COMP_GAIN 0x00000040 #define AR5K_PHY_PAPD_PROBE_TXPOWER 0x00007e00 #define AR5K_PHY_PAPD_PROBE_TXPOWER_S 9 #define AR5K_PHY_PAPD_PROBE_TX_NEXT 0x00008000 #define AR5K_PHY_PAPD_PROBE_PREDIST_EN 0x00010000 #define AR5K_PHY_PAPD_PROBE_TYPE 0x01800000 /* [5112+] */ #define AR5K_PHY_PAPD_PROBE_TYPE_S 23 #define AR5K_PHY_PAPD_PROBE_TYPE_OFDM 0 #define AR5K_PHY_PAPD_PROBE_TYPE_XR 1 #define AR5K_PHY_PAPD_PROBE_TYPE_CCK 2 #define AR5K_PHY_PAPD_PROBE_GAINF 0xfe000000 #define AR5K_PHY_PAPD_PROBE_GAINF_S 25 #define AR5K_PHY_PAPD_PROBE_INI_5111 0x00004883 /* [5212+] */ #define AR5K_PHY_PAPD_PROBE_INI_5112 0x00004882 /* [5212+] */ /* * PHY TX rate power registers [5112+] */ #define AR5K_PHY_TXPOWER_RATE1 0x9934 #define AR5K_PHY_TXPOWER_RATE2 0x9938 #define AR5K_PHY_TXPOWER_RATE_MAX 0x993c #define AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE 0x00000040 #define AR5K_PHY_TXPOWER_RATE3 0xa234 #define AR5K_PHY_TXPOWER_RATE4 0xa238 /* * PHY frame control register [5111+] */ #define AR5K_PHY_FRAME_CTL_5210 0x9804 #define AR5K_PHY_FRAME_CTL_5211 0x9944 #define AR5K_PHY_FRAME_CTL (ah->ah_version == AR5K_AR5210 ? \ AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211) /*---[5111+]---*/ #define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */ #define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3 #define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */ #define AR5K_PHY_FRAME_CTL_EMU 0x80000000 #define AR5K_PHY_FRAME_CTL_EMU_S 31 /*---[5110/5111]---*/ #define AR5K_PHY_FRAME_CTL_TIMING_ERR 0x01000000 /* PHY timing error */ #define AR5K_PHY_FRAME_CTL_PARITY_ERR 0x02000000 /* Parity error */ #define AR5K_PHY_FRAME_CTL_ILLRATE_ERR 0x04000000 /* Illegal rate */ #define AR5K_PHY_FRAME_CTL_ILLLEN_ERR 0x08000000 /* Illegal length */ #define AR5K_PHY_FRAME_CTL_SERVICE_ERR 0x20000000 #define AR5K_PHY_FRAME_CTL_TXURN_ERR 0x40000000 /* TX underrun */ #define AR5K_PHY_FRAME_CTL_INI AR5K_PHY_FRAME_CTL_SERVICE_ERR | \ AR5K_PHY_FRAME_CTL_TXURN_ERR | \ AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \ AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \ AR5K_PHY_FRAME_CTL_PARITY_ERR | \ AR5K_PHY_FRAME_CTL_TIMING_ERR /* * PHY Tx Power adjustment register [5212A+] */ #define AR5K_PHY_TX_PWR_ADJ 0x994c #define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA 0x00000fc0 #define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S 6 #define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX 0x00fc0000 #define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S 18 /* * PHY radar detection register [5111+] */ #define AR5K_PHY_RADAR 0x9954 #define AR5K_PHY_RADAR_ENABLE 0x00000001 #define AR5K_PHY_RADAR_DISABLE 0x00000000 #define AR5K_PHY_RADAR_INBANDTHR 0x0000003e /* Inband threshold 5-bits, units unknown {0..31} (? MHz ?) */ #define AR5K_PHY_RADAR_INBANDTHR_S 1 #define AR5K_PHY_RADAR_PRSSI_THR 0x00000fc0 /* Pulse RSSI/SNR threshold 6-bits, dBm range {0..63} in dBm units. */ #define AR5K_PHY_RADAR_PRSSI_THR_S 6 #define AR5K_PHY_RADAR_PHEIGHT_THR 0x0003f000 /* Pulse height threshold 6-bits, dBm range {0..63} in dBm units. */ #define AR5K_PHY_RADAR_PHEIGHT_THR_S 12 #define AR5K_PHY_RADAR_RSSI_THR 0x00fc0000 /* Radar RSSI/SNR threshold. 6-bits, dBm range {0..63} in dBm units. */ #define AR5K_PHY_RADAR_RSSI_THR_S 18 #define AR5K_PHY_RADAR_FIRPWR_THR 0x7f000000 /* Finite Impulse Response filter power out threshold. 7-bits, standard power range {0..127} in 1/2 dBm units. */ #define AR5K_PHY_RADAR_FIRPWR_THRS 24 /* * PHY antenna switch table registers */ #define AR5K_PHY_ANT_SWITCH_TABLE_0 0x9960 #define AR5K_PHY_ANT_SWITCH_TABLE_1 0x9964 /* * PHY Noise floor threshold */ #define AR5K_PHY_NFTHRES 0x9968 /* * Sigma Delta register (?) [5213] */ #define AR5K_PHY_SIGMA_DELTA 0x996C #define AR5K_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 #define AR5K_PHY_SIGMA_DELTA_ADC_SEL_S 0 #define AR5K_PHY_SIGMA_DELTA_FILT2 0x000000f8 #define AR5K_PHY_SIGMA_DELTA_FILT2_S 3 #define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00 #define AR5K_PHY_SIGMA_DELTA_FILT1_S 8 #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000 #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13 /* * RF restart register [5112+] (?) */ #define AR5K_PHY_RESTART 0x9970 /* restart */ #define AR5K_PHY_RESTART_DIV_GC 0x001c0000 /* Fast diversity gc_limit (?) */ #define AR5K_PHY_RESTART_DIV_GC_S 18 /* * RF Bus access request register (for synth-oly channel switching) */ #define AR5K_PHY_RFBUS_REQ 0x997C #define AR5K_PHY_RFBUS_REQ_REQUEST 0x00000001 /* * Spur mitigation masks (?) */ #define AR5K_PHY_TIMING_7 0x9980 #define AR5K_PHY_TIMING_8 0x9984 #define AR5K_PHY_TIMING_8_PILOT_MASK_2 0x000fffff #define AR5K_PHY_TIMING_8_PILOT_MASK_2_S 0 #define AR5K_PHY_BIN_MASK2_1 0x9988 #define AR5K_PHY_BIN_MASK2_2 0x998c #define AR5K_PHY_BIN_MASK2_3 0x9990 #define AR5K_PHY_BIN_MASK2_4 0x9994 #define AR5K_PHY_BIN_MASK2_4_MASK_4 0x00003fff #define AR5K_PHY_BIN_MASK2_4_MASK_4_S 0 #define AR5K_PHY_TIMING_9 0x9998 #define AR5K_PHY_TIMING_10 0x999c #define AR5K_PHY_TIMING_10_PILOT_MASK_2 0x000fffff #define AR5K_PHY_TIMING_10_PILOT_MASK_2_S 0 /* * Spur mitigation control */ #define AR5K_PHY_TIMING_11 0x99a0 /* Register address */ #define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */ #define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0 #define AR5K_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */ #define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S 20 #define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */ #define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */ /* * Gain tables */ #define AR5K_BB_GAIN_BASE 0x9b00 /* BaseBand Amplifier Gain table base address */ #define AR5K_BB_GAIN(_n) (AR5K_BB_GAIN_BASE + ((_n) << 2)) #define AR5K_RF_GAIN_BASE 0x9a00 /* RF Amplrifier Gain table base address */ #define AR5K_RF_GAIN(_n) (AR5K_RF_GAIN_BASE + ((_n) << 2)) /* * PHY timing IQ calibration result register [5111+] */ #define AR5K_PHY_IQRES_CAL_PWR_I 0x9c10 /* I (Inphase) power value */ #define AR5K_PHY_IQRES_CAL_PWR_Q 0x9c14 /* Q (Quadrature) power value */ #define AR5K_PHY_IQRES_CAL_CORR 0x9c18 /* I/Q Correlation */ /* * PHY current RSSI register [5111+] */ #define AR5K_PHY_CURRENT_RSSI 0x9c1c /* * PHY RF Bus grant register */ #define AR5K_PHY_RFBUS_GRANT 0x9c20 #define AR5K_PHY_RFBUS_GRANT_OK 0x00000001 /* * PHY ADC test register */ #define AR5K_PHY_ADC_TEST 0x9c24 #define AR5K_PHY_ADC_TEST_I 0x00000001 #define AR5K_PHY_ADC_TEST_Q 0x00000200 /* * PHY DAC test register */ #define AR5K_PHY_DAC_TEST 0x9c28 #define AR5K_PHY_DAC_TEST_I 0x00000001 #define AR5K_PHY_DAC_TEST_Q 0x00000200 /* * PHY PTAT register (?) */ #define AR5K_PHY_PTAT 0x9c2c /* * PHY Illegal TX rate register [5112+] */ #define AR5K_PHY_BAD_TX_RATE 0x9c30 /* * PHY SPUR Power register [5112+] */ #define AR5K_PHY_SPUR_PWR 0x9c34 /* Register Address */ #define AR5K_PHY_SPUR_PWR_I 0x00000001 /* SPUR Power estimate for I (field) */ #define AR5K_PHY_SPUR_PWR_Q 0x00000100 /* SPUR Power estimate for Q (field) */ #define AR5K_PHY_SPUR_PWR_FILT 0x00010000 /* Power with SPUR removed (field) */ /* * PHY Channel status register [5112+] (?) */ #define AR5K_PHY_CHAN_STATUS 0x9c38 #define AR5K_PHY_CHAN_STATUS_BT_ACT 0x00000001 #define AR5K_PHY_CHAN_STATUS_RX_CLR_RAW 0x00000002 #define AR5K_PHY_CHAN_STATUS_RX_CLR_MAC 0x00000004 #define AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008 /* * Heavy clip enable register */ #define AR5K_PHY_HEAVY_CLIP_ENABLE 0x99e0 /* * PHY clock sleep registers [5112+] */ #define AR5K_PHY_SCLOCK 0x99f0 #define AR5K_PHY_SCLOCK_32MHZ 0x0000000c #define AR5K_PHY_SDELAY 0x99f4 #define AR5K_PHY_SDELAY_32MHZ 0x000000ff #define AR5K_PHY_SPENDING 0x99f8 /* * PHY PAPD I (power?) table (?) * (92! entries) */ #define AR5K_PHY_PAPD_I_BASE 0xa000 #define AR5K_PHY_PAPD_I(_n) (AR5K_PHY_PAPD_I_BASE + ((_n) << 2)) /* * PHY PCDAC TX power table */ #define AR5K_PHY_PCDAC_TXPOWER_BASE 0xa180 #define AR5K_PHY_PCDAC_TXPOWER(_n) (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2)) /* * PHY mode register [5111+] */ #define AR5K_PHY_MODE 0x0a200 /* Register Address */ #define AR5K_PHY_MODE_MOD 0x00000001 /* PHY Modulation bit */ #define AR5K_PHY_MODE_MOD_OFDM 0 #define AR5K_PHY_MODE_MOD_CCK 1 #define AR5K_PHY_MODE_FREQ 0x00000002 /* Freq mode bit */ #define AR5K_PHY_MODE_FREQ_5GHZ 0 #define AR5K_PHY_MODE_FREQ_2GHZ 2 #define AR5K_PHY_MODE_MOD_DYN 0x00000004 /* Enable Dynamic OFDM/CCK mode [5112+] */ #define AR5K_PHY_MODE_RAD 0x00000008 /* [5212+] */ #define AR5K_PHY_MODE_RAD_RF5111 0 #define AR5K_PHY_MODE_RAD_RF5112 8 #define AR5K_PHY_MODE_XR 0x00000010 /* Enable XR mode [5112+] */ #define AR5K_PHY_MODE_HALF_RATE 0x00000020 /* Enable Half rate (test) */ #define AR5K_PHY_MODE_QUARTER_RATE 0x00000040 /* Enable Quarter rat (test) */ /* * PHY CCK transmit control register [5111+ (?)] */ #define AR5K_PHY_CCKTXCTL 0xa204 #define AR5K_PHY_CCKTXCTL_WORLD 0x00000000 #define AR5K_PHY_CCKTXCTL_JAPAN 0x00000010 #define AR5K_PHY_CCKTXCTL_SCRAMBLER_DIS 0x00000001 #define AR5K_PHY_CCKTXCTK_DAC_SCALE 0x00000004 /* * PHY CCK Cross-correlator Barker RSSI threshold register [5212+] */ #define AR5K_PHY_CCK_CROSSCORR 0xa208 #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000000f #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0 /* Same address is used for antenna diversity activation */ #define AR5K_PHY_FAST_ANT_DIV 0xa208 #define AR5K_PHY_FAST_ANT_DIV_EN 0x00002000 /* * PHY 2GHz gain register [5111+] */ #define AR5K_PHY_GAIN_2GHZ 0xa20c #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX 0x00fc0000 #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S 18 #define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6480416c #define AR5K_PHY_CCK_RX_CTL_4 0xa21c #define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT 0x01f80000 #define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT_S 19 #define AR5K_PHY_DAG_CCK_CTL 0xa228 #define AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR 0x00000200 #define AR5K_PHY_DAG_CCK_CTL_RSSI_THR 0x0001fc00 #define AR5K_PHY_DAG_CCK_CTL_RSSI_THR_S 10 #define AR5K_PHY_FAST_ADC 0xa24c #define AR5K_PHY_BLUETOOTH 0xa254 /* * Transmit Power Control register * [2413+] */ #define AR5K_PHY_TPC_RG1 0xa258 #define AR5K_PHY_TPC_RG1_NUM_PD_GAIN 0x0000c000 #define AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S 14 #define AR5K_PHY_TPC_RG1_PDGAIN_1 0x00030000 #define AR5K_PHY_TPC_RG1_PDGAIN_1_S 16 #define AR5K_PHY_TPC_RG1_PDGAIN_2 0x000c0000 #define AR5K_PHY_TPC_RG1_PDGAIN_2_S 18 #define AR5K_PHY_TPC_RG1_PDGAIN_3 0x00300000 #define AR5K_PHY_TPC_RG1_PDGAIN_3_S 20 #define AR5K_PHY_TPC_RG5 0xa26C #define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP 0x0000000F #define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP_S 0 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1 0x000003F0 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1_S 4 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2 0x0000FC00 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2_S 10 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3 0x003F0000 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S 16 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4 0x0FC00000 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S 22 /* * PHY PDADC Tx power table */ #define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280 #define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2)) debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/desc.h0000664000000000000000000003030412524662415021312 0ustar /* * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2006-2008 Nick Kossifidis * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ /* * Internal RX/TX descriptor structures * (rX: reserved fields possibily used by future versions of the ar5k chipset) */ /* * common hardware RX control descriptor */ struct ath5k_hw_rx_ctl { u32 rx_control_0; /* RX control word 0 */ u32 rx_control_1; /* RX control word 1 */ } __attribute__ ((packed)); /* RX control word 0 field/sflags */ #define AR5K_DESC_RX_CTL0 0x00000000 /* RX control word 1 fields/flags */ #define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff #define AR5K_DESC_RX_CTL1_INTREQ 0x00002000 /* * common hardware RX status descriptor * 5210/11 and 5212 differ only in the flags defined below */ struct ath5k_hw_rx_status { u32 rx_status_0; /* RX status word 0 */ u32 rx_status_1; /* RX status word 1 */ } __attribute__ ((packed)); /* 5210/5211 */ /* RX status word 0 fields/flags */ #define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff #define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000 #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000 #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S 15 #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000 #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19 #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000 #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27 /* RX status word 1 fields/flags */ #define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001 #define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 #define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004 #define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN 0x00000008 #define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010 #define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR 0x000000e0 #define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S 5 #define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 #define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX 0x00007e00 #define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S 9 #define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000 #define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15 #define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000 /* 5212 */ /* RX status word 0 fields/flags */ #define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff #define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000 #define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000 #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000 #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S 15 #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000 #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20 #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000 #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28 /* RX status word 1 fields/flags */ #define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001 #define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 #define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004 #define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008 #define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR 0x00000010 #define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR 0x00000020 #define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 #define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00 #define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S 9 #define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000 #define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16 #define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000 /* * common hardware RX error descriptor */ struct ath5k_hw_rx_error { u32 rx_error_0; /* RX status word 0 */ u32 rx_error_1; /* RX status word 1 */ } __attribute__ ((packed)); /* RX error word 0 fields/flags */ #define AR5K_RX_DESC_ERROR0 0x00000000 /* RX error word 1 fields/flags */ #define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00 #define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8 /* PHY Error codes */ #define AR5K_DESC_RX_PHY_ERROR_NONE 0x00 #define AR5K_DESC_RX_PHY_ERROR_TIMING 0x20 #define AR5K_DESC_RX_PHY_ERROR_PARITY 0x40 #define AR5K_DESC_RX_PHY_ERROR_RATE 0x60 #define AR5K_DESC_RX_PHY_ERROR_LENGTH 0x80 #define AR5K_DESC_RX_PHY_ERROR_64QAM 0xa0 #define AR5K_DESC_RX_PHY_ERROR_SERVICE 0xc0 #define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR 0xe0 /* * 5210/5211 hardware 2-word TX control descriptor */ struct ath5k_hw_2w_tx_ctl { u32 tx_control_0; /* TX control word 0 */ u32 tx_control_1; /* TX control word 1 */ } __attribute__ ((packed)); /* TX control word 0 fields/flags */ #define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff #define AR5K_2W_TX_DESC_CTL0_HEADER_LEN 0x0003f000 /*[5210 ?]*/ #define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S 12 #define AR5K_2W_TX_DESC_CTL0_XMIT_RATE 0x003c0000 #define AR5K_2W_TX_DESC_CTL0_XMIT_RATE_S 18 #define AR5K_2W_TX_DESC_CTL0_RTSENA 0x00400000 #define AR5K_2W_TX_DESC_CTL0_CLRDMASK 0x01000000 #define AR5K_2W_TX_DESC_CTL0_LONG_PACKET 0x00800000 /*[5210]*/ #define AR5K_2W_TX_DESC_CTL0_VEOL 0x00800000 /*[5211]*/ #define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE 0x1c000000 /*[5210]*/ #define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S 26 #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000 #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000 #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT \ (ah->ah_version == AR5K_AR5210 ? \ AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 : \ AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211) #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25 #define AR5K_2W_TX_DESC_CTL0_INTREQ 0x20000000 #define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 /* TX control word 1 fields/flags */ #define AR5K_2W_TX_DESC_CTL1_BUF_LEN 0x00000fff #define AR5K_2W_TX_DESC_CTL1_MORE 0x00001000 #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 0x0007e000 #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211 0x000fe000 #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX \ (ah->ah_version == AR5K_AR5210 ? \ AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 : \ AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211) #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13 #define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE 0x00700000 /*[5211]*/ #define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S 20 #define AR5K_2W_TX_DESC_CTL1_NOACK 0x00800000 /*[5211]*/ #define AR5K_2W_TX_DESC_CTL1_RTS_DURATION 0xfff80000 /*[5210 ?]*/ /* Frame types */ #define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0x00 #define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 0x04 #define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 0x08 #define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 0x0c #define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 0x10 /* * 5212 hardware 4-word TX control descriptor */ struct ath5k_hw_4w_tx_ctl { u32 tx_control_0; /* TX control word 0 */ #define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff #define AR5K_4W_TX_DESC_CTL0_XMIT_POWER 0x003f0000 #define AR5K_4W_TX_DESC_CTL0_XMIT_POWER_S 16 #define AR5K_4W_TX_DESC_CTL0_RTSENA 0x00400000 #define AR5K_4W_TX_DESC_CTL0_VEOL 0x00800000 #define AR5K_4W_TX_DESC_CTL0_CLRDMASK 0x01000000 #define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT 0x1e000000 #define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25 #define AR5K_4W_TX_DESC_CTL0_INTREQ 0x20000000 #define AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 #define AR5K_4W_TX_DESC_CTL0_CTSENA 0x80000000 u32 tx_control_1; /* TX control word 1 */ #define AR5K_4W_TX_DESC_CTL1_BUF_LEN 0x00000fff #define AR5K_4W_TX_DESC_CTL1_MORE 0x00001000 #define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX 0x000fe000 #define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13 #define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE 0x00f00000 #define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE_S 20 #define AR5K_4W_TX_DESC_CTL1_NOACK 0x01000000 #define AR5K_4W_TX_DESC_CTL1_COMP_PROC 0x06000000 #define AR5K_4W_TX_DESC_CTL1_COMP_PROC_S 25 #define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN 0x18000000 #define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN_S 27 #define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN 0x60000000 #define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN_S 29 u32 tx_control_2; /* TX control word 2 */ #define AR5K_4W_TX_DESC_CTL2_RTS_DURATION 0x00007fff #define AR5K_4W_TX_DESC_CTL2_DURATION_UPDATE_ENABLE 0x00008000 #define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0 0x000f0000 #define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0_S 16 #define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1 0x00f00000 #define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1_S 20 #define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2 0x0f000000 #define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2_S 24 #define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3 0xf0000000 #define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3_S 28 u32 tx_control_3; /* TX control word 3 */ #define AR5K_4W_TX_DESC_CTL3_XMIT_RATE0 0x0000001f #define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1 0x000003e0 #define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1_S 5 #define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2 0x00007c00 #define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2_S 10 #define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3 0x000f8000 #define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3_S 15 #define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE 0x01f00000 #define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE_S 20 } __attribute__ ((packed)); /* * Common TX status descriptor */ struct ath5k_hw_tx_status { u32 tx_status_0; /* TX status word 0 */ u32 tx_status_1; /* TX status word 1 */ } __attribute__ ((packed)); /* TX status word 0 fields/flags */ #define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 #define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002 #define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN 0x00000004 #define AR5K_DESC_TX_STATUS0_FILTERED 0x00000008 /*??? #define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT 0x000000f0 #define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT_S 4 */ #define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT 0x000000f0 #define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT_S 4 /*??? #define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT 0x00000f00 #define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT_S 8 */ #define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT 0x00000f00 #define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT_S 8 #define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT 0x0000f000 #define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT_S 12 #define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP 0xffff0000 #define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S 16 /* TX status word 1 fields/flags */ #define AR5K_DESC_TX_STATUS1_DONE 0x00000001 #define AR5K_DESC_TX_STATUS1_SEQ_NUM 0x00001ffe #define AR5K_DESC_TX_STATUS1_SEQ_NUM_S 1 #define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH 0x001fe000 #define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH_S 13 #define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX 0x00600000 #define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S 21 #define AR5K_DESC_TX_STATUS1_COMP_SUCCESS 0x00800000 #define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA 0x01000000 /* * 5210/5211 hardware TX descriptor */ struct ath5k_hw_5210_tx_desc { struct ath5k_hw_2w_tx_ctl tx_ctl; struct ath5k_hw_tx_status tx_stat; } __attribute__ ((packed)); /* * 5212 hardware TX descriptor */ struct ath5k_hw_5212_tx_desc { struct ath5k_hw_4w_tx_ctl tx_ctl; struct ath5k_hw_tx_status tx_stat; } __attribute__ ((packed)); /* * common hardware RX descriptor */ struct ath5k_hw_all_rx_desc { struct ath5k_hw_rx_ctl rx_ctl; union { struct ath5k_hw_rx_status rx_stat; struct ath5k_hw_rx_error rx_err; } u; } __attribute__ ((packed)); /* * Atheros hardware descriptor * This is read and written to by the hardware */ struct ath5k_desc { u32 ds_link; /* physical address of the next descriptor */ u32 ds_data; /* physical address of data buffer (skb) */ union { struct ath5k_hw_5210_tx_desc ds_tx5210; struct ath5k_hw_5212_tx_desc ds_tx5212; struct ath5k_hw_all_rx_desc ds_rx; } ud; } __attribute__ ((packed)); #define AR5K_RXDESC_INTREQ 0x0020 #define AR5K_TXDESC_CLRDMASK 0x0001 #define AR5K_TXDESC_NOACK 0x0002 /*[5211+]*/ #define AR5K_TXDESC_RTSENA 0x0004 #define AR5K_TXDESC_CTSENA 0x0008 #define AR5K_TXDESC_INTREQ 0x0010 #define AR5K_TXDESC_VEOL 0x0020 /*[5211+]*/ debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k_attach.c0000664000000000000000000002233112524662415022730 0ustar /* * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2006-2008 Nick Kossifidis * * Modified for gPXE, July 2009, by Joshua Oreman * Original from Linux kernel 2.6.30. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ FILE_LICENCE ( MIT ); /*************************************\ * Attach/Detach Functions and helpers * \*************************************/ #include #include #include #include "ath5k.h" #include "reg.h" #include "base.h" /** * ath5k_hw_post - Power On Self Test helper function * * @ah: The &struct ath5k_hw */ static int ath5k_hw_post(struct ath5k_hw *ah) { static const u32 static_pattern[4] = { 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999 }; static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) }; int i, c; u16 cur_reg; u32 var_pattern; u32 init_val; u32 cur_val; for (c = 0; c < 2; c++) { cur_reg = regs[c]; /* Save previous value */ init_val = ath5k_hw_reg_read(ah, cur_reg); for (i = 0; i < 256; i++) { var_pattern = i << 16 | i; ath5k_hw_reg_write(ah, var_pattern, cur_reg); cur_val = ath5k_hw_reg_read(ah, cur_reg); if (cur_val != var_pattern) { DBG("ath5k: POST failed!\n"); return -EAGAIN; } /* Found on ndiswrapper dumps */ var_pattern = 0x0039080f; ath5k_hw_reg_write(ah, var_pattern, cur_reg); } for (i = 0; i < 4; i++) { var_pattern = static_pattern[i]; ath5k_hw_reg_write(ah, var_pattern, cur_reg); cur_val = ath5k_hw_reg_read(ah, cur_reg); if (cur_val != var_pattern) { DBG("ath5k: POST failed!\n"); return -EAGAIN; } /* Found on ndiswrapper dumps */ var_pattern = 0x003b080f; ath5k_hw_reg_write(ah, var_pattern, cur_reg); } /* Restore previous value */ ath5k_hw_reg_write(ah, init_val, cur_reg); } return 0; } /** * ath5k_hw_attach - Check if hw is supported and init the needed structs * * @sc: The &struct ath5k_softc we got from the driver's attach function * @mac_version: The mac version id (check out ath5k.h) based on pci id * @hw: Returned newly allocated hardware structure, on success * * Check if the device is supported, perform a POST and initialize the needed * structs. Returns -ENOMEM if we don't have memory for the needed structs, * -ENODEV if the device is not supported or prints an error msg if something * else went wrong. */ int ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version, struct ath5k_hw **hw) { struct ath5k_hw *ah; struct pci_device *pdev = sc->pdev; int ret; u32 srev; ah = zalloc(sizeof(struct ath5k_hw)); if (ah == NULL) { ret = -ENOMEM; DBG("ath5k: out of memory\n"); goto err; } ah->ah_sc = sc; ah->ah_iobase = sc->iobase; /* * HW information */ ah->ah_turbo = 0; ah->ah_txpower.txp_tpc = 0; ah->ah_imr = 0; ah->ah_atim_window = 0; ah->ah_aifs = AR5K_TUNE_AIFS; ah->ah_cw_min = AR5K_TUNE_CWMIN; ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; ah->ah_software_retry = 0; ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY; /* * Set the mac version based on the pci id */ ah->ah_version = mac_version; /*Fill the ath5k_hw struct with the needed functions*/ ret = ath5k_hw_init_desc_functions(ah); if (ret) goto err_free; /* Bring device out of sleep and reset it's units */ ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, 1); if (ret) goto err_free; /* Get MAC, PHY and RADIO revisions */ srev = ath5k_hw_reg_read(ah, AR5K_SREV); ah->ah_mac_srev = srev; ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV); ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID); ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, CHANNEL_5GHZ); ah->ah_phy = AR5K_PHY(0); /* Try to identify radio chip based on it's srev */ switch (ah->ah_radio_5ghz_revision & 0xf0) { case AR5K_SREV_RAD_5111: ah->ah_radio = AR5K_RF5111; ah->ah_single_chip = 0; ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, CHANNEL_2GHZ); break; case AR5K_SREV_RAD_5112: case AR5K_SREV_RAD_2112: ah->ah_radio = AR5K_RF5112; ah->ah_single_chip = 0; ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, CHANNEL_2GHZ); break; case AR5K_SREV_RAD_2413: ah->ah_radio = AR5K_RF2413; ah->ah_single_chip = 1; break; case AR5K_SREV_RAD_5413: ah->ah_radio = AR5K_RF5413; ah->ah_single_chip = 1; break; case AR5K_SREV_RAD_2316: ah->ah_radio = AR5K_RF2316; ah->ah_single_chip = 1; break; case AR5K_SREV_RAD_2317: ah->ah_radio = AR5K_RF2317; ah->ah_single_chip = 1; break; case AR5K_SREV_RAD_5424: if (ah->ah_mac_version == AR5K_SREV_AR2425 || ah->ah_mac_version == AR5K_SREV_AR2417) { ah->ah_radio = AR5K_RF2425; } else { ah->ah_radio = AR5K_RF5413; } ah->ah_single_chip = 1; break; default: /* Identify radio based on mac/phy srev */ if (ah->ah_version == AR5K_AR5210) { ah->ah_radio = AR5K_RF5110; ah->ah_single_chip = 0; } else if (ah->ah_version == AR5K_AR5211) { ah->ah_radio = AR5K_RF5111; ah->ah_single_chip = 0; ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, CHANNEL_2GHZ); } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) || ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) || ah->ah_phy_revision == AR5K_SREV_PHY_2425) { ah->ah_radio = AR5K_RF2425; ah->ah_single_chip = 1; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425; } else if (srev == AR5K_SREV_AR5213A && ah->ah_phy_revision == AR5K_SREV_PHY_5212B) { ah->ah_radio = AR5K_RF5112; ah->ah_single_chip = 0; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B; } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) { ah->ah_radio = AR5K_RF2316; ah->ah_single_chip = 1; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) || ah->ah_phy_revision == AR5K_SREV_PHY_5413) { ah->ah_radio = AR5K_RF5413; ah->ah_single_chip = 1; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413; } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) || ah->ah_phy_revision == AR5K_SREV_PHY_2413) { ah->ah_radio = AR5K_RF2413; ah->ah_single_chip = 1; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413; } else { DBG("ath5k: Couldn't identify radio revision.\n"); ret = -ENOTSUP; goto err_free; } } /* Return on unsuported chips (unsupported eeprom etc) */ if ((srev >= AR5K_SREV_AR5416) && (srev < AR5K_SREV_AR2425)) { DBG("ath5k: Device not yet supported.\n"); ret = -ENOTSUP; goto err_free; } /* * Write PCI-E power save settings */ if ((ah->ah_version == AR5K_AR5212) && pci_find_capability(pdev, PCI_CAP_ID_EXP)) { ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES); ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); /* Shut off RX when elecidle is asserted */ ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES); ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES); /* TODO: EEPROM work */ ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES); /* Shut off PLL and CLKREQ active in L1 */ ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES); /* Preserce other settings */ ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES); ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES); ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES); /* Reset SERDES to load new settings */ ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET); mdelay(1); } /* * POST */ ret = ath5k_hw_post(ah); if (ret) goto err_free; /* Enable pci core retry fix on Hainan (5213A) and later chips */ if (srev >= AR5K_SREV_AR5213A) ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG); /* * Get card capabilities, calibration values etc * TODO: EEPROM work */ ret = ath5k_eeprom_init(ah); if (ret) { DBG("ath5k: unable to init EEPROM\n"); goto err_free; } /* Get misc capabilities */ ret = ath5k_hw_set_capabilities(ah); if (ret) { DBG("ath5k: unable to get device capabilities: 0x%04x\n", sc->pdev->device); goto err_free; } if (srev >= AR5K_SREV_AR2414) { ah->ah_combined_mic = 1; AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE, AR5K_MISC_MODE_COMBINED_MIC); } /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ memset(ah->ah_bssid, 0xff, ETH_ALEN); ath5k_hw_set_associd(ah, ah->ah_bssid, 0); ath5k_hw_set_opmode(ah); ath5k_hw_rfgain_opt_init(ah); *hw = ah; return 0; err_free: free(ah); err: return ret; } /** * ath5k_hw_detach - Free the ath5k_hw struct * * @ah: The &struct ath5k_hw */ void ath5k_hw_detach(struct ath5k_hw *ah) { free(ah->ah_rf_banks); ath5k_eeprom_detach(ah); free(ah); } debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k_dma.c0000664000000000000000000004107012524662415022226 0ustar /* * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2006-2008 Nick Kossifidis * * Lightly modified for gPXE, July 2009, by Joshua Oreman . * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ FILE_LICENCE ( MIT ); /*************************************\ * DMA and interrupt masking functions * \*************************************/ /* * dma.c - DMA and interrupt masking functions * * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and * handle queue setup for 5210 chipset (rest are handled on qcu.c). * Also we setup interrupt mask register (IMR) and read the various iterrupt * status registers (ISR). * * TODO: Handle SISR on 5211+ and introduce a function to return the queue * number that resulted the interrupt. */ #include #include "ath5k.h" #include "reg.h" #include "base.h" /*********\ * Receive * \*********/ /** * ath5k_hw_start_rx_dma - Start DMA receive * * @ah: The &struct ath5k_hw */ void ath5k_hw_start_rx_dma(struct ath5k_hw *ah) { ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR); ath5k_hw_reg_read(ah, AR5K_CR); } /** * ath5k_hw_stop_rx_dma - Stop DMA receive * * @ah: The &struct ath5k_hw */ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) { unsigned int i; ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR); /* * It may take some time to disable the DMA receive unit */ for (i = 1000; i > 0 && (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0; i--) udelay(10); return i ? 0 : -EBUSY; } /** * ath5k_hw_get_rxdp - Get RX Descriptor's address * * @ah: The &struct ath5k_hw * * XXX: Is RXDP read and clear ? */ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah) { return ath5k_hw_reg_read(ah, AR5K_RXDP); } /** * ath5k_hw_set_rxdp - Set RX Descriptor's address * * @ah: The &struct ath5k_hw * @phys_addr: RX descriptor address * * XXX: Should we check if rx is enabled before setting rxdp ? */ void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr) { ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP); } /**********\ * Transmit * \**********/ /** * ath5k_hw_start_tx_dma - Start DMA transmit for a specific queue * * @ah: The &struct ath5k_hw * @queue: The hw queue number * * Start DMA transmit for a specific queue and since 5210 doesn't have * QCU/DCU, set up queue parameters for 5210 here based on queue type (one * queue for normal data and one queue for beacons). For queue setup * on newer chips check out qcu.c. Returns -EINVAL if queue number is out * of range or if queue is already disabled. * * NOTE: Must be called after setting up tx control descriptor for that * queue (see below). */ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue) { u32 tx_queue; /* Return if queue is declared inactive */ if (ah->ah_txq.tqi_type == AR5K_TX_QUEUE_INACTIVE) return -EIO; if (ah->ah_version == AR5K_AR5210) { tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); /* Assume always a data queue */ tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0; /* Start queue */ ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); ath5k_hw_reg_read(ah, AR5K_CR); } else { /* Return if queue is disabled */ if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue)) return -EIO; /* Start queue */ AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue); } return 0; } /** * ath5k_hw_stop_tx_dma - Stop DMA transmit on a specific queue * * @ah: The &struct ath5k_hw * @queue: The hw queue number * * Stop DMA transmit on a specific hw queue and drain queue so we don't * have any pending frames. Returns -EBUSY if we still have pending frames, * -EINVAL if queue number is out of range. * */ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) { unsigned int i = 40; u32 tx_queue, pending; /* Return if queue is declared inactive */ if (ah->ah_txq.tqi_type == AR5K_TX_QUEUE_INACTIVE) return -EIO; if (ah->ah_version == AR5K_AR5210) { tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); /* Assume a data queue */ tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0; /* Stop queue */ ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); ath5k_hw_reg_read(ah, AR5K_CR); } else { /* * Schedule TX disable and wait until queue is empty */ AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue); /*Check for pending frames*/ do { pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue)) & AR5K_QCU_STS_FRMPENDCNT; udelay(100); } while (--i && pending); /* For 2413+ order PCU to drop packets using * QUIET mechanism */ if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) && pending) { /* Set periodicity and duration */ ath5k_hw_reg_write(ah, AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)| AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR), AR5K_QUIET_CTL2); /* Enable quiet period for current TSF */ ath5k_hw_reg_write(ah, AR5K_QUIET_CTL1_QT_EN | AR5K_REG_SM(ath5k_hw_reg_read(ah, AR5K_TSF_L32_5211) >> 10, AR5K_QUIET_CTL1_NEXT_QT_TSF), AR5K_QUIET_CTL1); /* Force channel idle high */ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, AR5K_DIAG_SW_CHANEL_IDLE_HIGH); /* Wait a while and disable mechanism */ udelay(200); AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1, AR5K_QUIET_CTL1_QT_EN); /* Re-check for pending frames */ i = 40; do { pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue)) & AR5K_QCU_STS_FRMPENDCNT; udelay(100); } while (--i && pending); AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, AR5K_DIAG_SW_CHANEL_IDLE_HIGH); } /* Clear register */ ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD); if (pending) return -EBUSY; } /* TODO: Check for success on 5210 else return error */ return 0; } /** * ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue * * @ah: The &struct ath5k_hw * @queue: The hw queue number * * Get TX descriptor's address for a specific queue. For 5210 we ignore * the queue number and use tx queue type since we only have 2 queues. * We use TXDP0 for normal data queue and TXDP1 for beacon queue. * For newer chips with QCU/DCU we just read the corresponding TXDP register. * * XXX: Is TXDP read and clear ? */ u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue) { u16 tx_reg; /* * Get the transmit queue descriptor pointer from the selected queue */ /*5210 doesn't have QCU*/ if (ah->ah_version == AR5K_AR5210) { /* Assume a data queue */ tx_reg = AR5K_NOQCU_TXDP0; } else { tx_reg = AR5K_QUEUE_TXDP(queue); } return ath5k_hw_reg_read(ah, tx_reg); } /** * ath5k_hw_set_txdp - Set TX Descriptor's address for a specific queue * * @ah: The &struct ath5k_hw * @queue: The hw queue number * * Set TX descriptor's address for a specific queue. For 5210 we ignore * the queue number and we use tx queue type since we only have 2 queues * so as above we use TXDP0 for normal data queue and TXDP1 for beacon queue. * For newer chips with QCU/DCU we just set the corresponding TXDP register. * Returns -EINVAL if queue type is invalid for 5210 and -EIO if queue is still * active. */ int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr) { u16 tx_reg; /* * Set the transmit queue descriptor pointer register by type * on 5210 */ if (ah->ah_version == AR5K_AR5210) { /* Assume a data queue */ tx_reg = AR5K_NOQCU_TXDP0; } else { /* * Set the transmit queue descriptor pointer for * the selected queue on QCU for 5211+ * (this won't work if the queue is still active) */ if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue)) return -EIO; tx_reg = AR5K_QUEUE_TXDP(queue); } /* Set descriptor pointer */ ath5k_hw_reg_write(ah, phys_addr, tx_reg); return 0; } /** * ath5k_hw_update_tx_triglevel - Update tx trigger level * * @ah: The &struct ath5k_hw * @increase: Flag to force increase of trigger level * * This function increases/decreases the tx trigger level for the tx fifo * buffer (aka FIFO threshold) that is used to indicate when PCU flushes * the buffer and transmits it's data. Lowering this results sending small * frames more quickly but can lead to tx underruns, raising it a lot can * result other problems (i think bmiss is related). Right now we start with * the lowest possible (64Bytes) and if we get tx underrun we increase it using * the increase flag. Returns -EIO if we have have reached maximum/minimum. * * XXX: Link this with tx DMA size ? * XXX: Use it to save interrupts ? * TODO: Needs testing, i think it's related to bmiss... */ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, int increase) { u32 trigger_level, imr; int ret = -EIO; /* * Disable interrupts by setting the mask */ imr = ath5k_hw_set_imr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL); trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG), AR5K_TXCFG_TXFULL); if (!increase) { if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES) goto done; } else trigger_level += ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2); /* * Update trigger level on success */ if (ah->ah_version == AR5K_AR5210) ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL); else AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_TXFULL, trigger_level); ret = 0; done: /* * Restore interrupt mask */ ath5k_hw_set_imr(ah, imr); return ret; } /*******************\ * Interrupt masking * \*******************/ /** * ath5k_hw_is_intr_pending - Check if we have pending interrupts * * @ah: The &struct ath5k_hw * * Check if we have pending interrupts to process. Returns 1 if we * have pending interrupts and 0 if we haven't. */ int ath5k_hw_is_intr_pending(struct ath5k_hw *ah) { return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0; } /** * ath5k_hw_get_isr - Get interrupt status * * @ah: The @struct ath5k_hw * @interrupt_mask: Driver's interrupt mask used to filter out * interrupts in sw. * * This function is used inside our interrupt handler to determine the reason * for the interrupt by reading Primary Interrupt Status Register. Returns an * abstract interrupt status mask which is mostly ISR with some uncommon bits * being mapped on some standard non hw-specific positions * (check out &ath5k_int). * * NOTE: We use read-and-clear register, so after this function is called ISR * is zeroed. */ int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask) { u32 data; /* * Read interrupt status from the Interrupt Status register * on 5210 */ if (ah->ah_version == AR5K_AR5210) { data = ath5k_hw_reg_read(ah, AR5K_ISR); if (data == AR5K_INT_NOCARD) { *interrupt_mask = data; return -ENODEV; } } else { /* * Read interrupt status from Interrupt * Status Register shadow copy (Read And Clear) * * Note: PISR/SISR Not available on 5210 */ data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR); if (data == AR5K_INT_NOCARD) { *interrupt_mask = data; return -ENODEV; } } /* * Get abstract interrupt mask (driver-compatible) */ *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr; if (ah->ah_version != AR5K_AR5210) { u32 sisr2 = ath5k_hw_reg_read(ah, AR5K_RAC_SISR2); /*HIU = Host Interface Unit (PCI etc)*/ if (data & (AR5K_ISR_HIUERR)) *interrupt_mask |= AR5K_INT_FATAL; /*Beacon Not Ready*/ if (data & (AR5K_ISR_BNR)) *interrupt_mask |= AR5K_INT_BNR; if (sisr2 & (AR5K_SISR2_SSERR | AR5K_SISR2_DPERR | AR5K_SISR2_MCABT)) *interrupt_mask |= AR5K_INT_FATAL; if (data & AR5K_ISR_TIM) *interrupt_mask |= AR5K_INT_TIM; if (data & AR5K_ISR_BCNMISC) { if (sisr2 & AR5K_SISR2_TIM) *interrupt_mask |= AR5K_INT_TIM; if (sisr2 & AR5K_SISR2_DTIM) *interrupt_mask |= AR5K_INT_DTIM; if (sisr2 & AR5K_SISR2_DTIM_SYNC) *interrupt_mask |= AR5K_INT_DTIM_SYNC; if (sisr2 & AR5K_SISR2_BCN_TIMEOUT) *interrupt_mask |= AR5K_INT_BCN_TIMEOUT; if (sisr2 & AR5K_SISR2_CAB_TIMEOUT) *interrupt_mask |= AR5K_INT_CAB_TIMEOUT; } if (data & AR5K_ISR_RXDOPPLER) *interrupt_mask |= AR5K_INT_RX_DOPPLER; if (data & AR5K_ISR_QCBRORN) { *interrupt_mask |= AR5K_INT_QCBRORN; ah->ah_txq_isr |= AR5K_REG_MS( ath5k_hw_reg_read(ah, AR5K_RAC_SISR3), AR5K_SISR3_QCBRORN); } if (data & AR5K_ISR_QCBRURN) { *interrupt_mask |= AR5K_INT_QCBRURN; ah->ah_txq_isr |= AR5K_REG_MS( ath5k_hw_reg_read(ah, AR5K_RAC_SISR3), AR5K_SISR3_QCBRURN); } if (data & AR5K_ISR_QTRIG) { *interrupt_mask |= AR5K_INT_QTRIG; ah->ah_txq_isr |= AR5K_REG_MS( ath5k_hw_reg_read(ah, AR5K_RAC_SISR4), AR5K_SISR4_QTRIG); } if (data & AR5K_ISR_TXOK) ah->ah_txq_isr |= AR5K_REG_MS( ath5k_hw_reg_read(ah, AR5K_RAC_SISR0), AR5K_SISR0_QCU_TXOK); if (data & AR5K_ISR_TXDESC) ah->ah_txq_isr |= AR5K_REG_MS( ath5k_hw_reg_read(ah, AR5K_RAC_SISR0), AR5K_SISR0_QCU_TXDESC); if (data & AR5K_ISR_TXERR) ah->ah_txq_isr |= AR5K_REG_MS( ath5k_hw_reg_read(ah, AR5K_RAC_SISR1), AR5K_SISR1_QCU_TXERR); if (data & AR5K_ISR_TXEOL) ah->ah_txq_isr |= AR5K_REG_MS( ath5k_hw_reg_read(ah, AR5K_RAC_SISR1), AR5K_SISR1_QCU_TXEOL); if (data & AR5K_ISR_TXURN) ah->ah_txq_isr |= AR5K_REG_MS( ath5k_hw_reg_read(ah, AR5K_RAC_SISR2), AR5K_SISR2_QCU_TXURN); } else { if (data & (AR5K_ISR_SSERR | AR5K_ISR_MCABT | AR5K_ISR_HIUERR | AR5K_ISR_DPERR)) *interrupt_mask |= AR5K_INT_FATAL; /* * XXX: BMISS interrupts may occur after association. * I found this on 5210 code but it needs testing. If this is * true we should disable them before assoc and re-enable them * after a successful assoc + some jiffies. interrupt_mask &= ~AR5K_INT_BMISS; */ } return 0; } /** * ath5k_hw_set_imr - Set interrupt mask * * @ah: The &struct ath5k_hw * @new_mask: The new interrupt mask to be set * * Set the interrupt mask in hw to save interrupts. We do that by mapping * ath5k_int bits to hw-specific bits to remove abstraction and writing * Interrupt Mask Register. */ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask) { enum ath5k_int old_mask, int_mask; old_mask = ah->ah_imr; /* * Disable card interrupts to prevent any race conditions * (they will be re-enabled afterwards if AR5K_INT GLOBAL * is set again on the new mask). */ if (old_mask & AR5K_INT_GLOBAL) { ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER); ath5k_hw_reg_read(ah, AR5K_IER); } /* * Add additional, chipset-dependent interrupt mask flags * and write them to the IMR (interrupt mask register). */ int_mask = new_mask & AR5K_INT_COMMON; if (ah->ah_version != AR5K_AR5210) { /* Preserve per queue TXURN interrupt mask */ u32 simr2 = ath5k_hw_reg_read(ah, AR5K_SIMR2) & AR5K_SIMR2_QCU_TXURN; if (new_mask & AR5K_INT_FATAL) { int_mask |= AR5K_IMR_HIUERR; simr2 |= (AR5K_SIMR2_MCABT | AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR); } /*Beacon Not Ready*/ if (new_mask & AR5K_INT_BNR) int_mask |= AR5K_INT_BNR; if (new_mask & AR5K_INT_TIM) int_mask |= AR5K_IMR_TIM; if (new_mask & AR5K_INT_TIM) simr2 |= AR5K_SISR2_TIM; if (new_mask & AR5K_INT_DTIM) simr2 |= AR5K_SISR2_DTIM; if (new_mask & AR5K_INT_DTIM_SYNC) simr2 |= AR5K_SISR2_DTIM_SYNC; if (new_mask & AR5K_INT_BCN_TIMEOUT) simr2 |= AR5K_SISR2_BCN_TIMEOUT; if (new_mask & AR5K_INT_CAB_TIMEOUT) simr2 |= AR5K_SISR2_CAB_TIMEOUT; if (new_mask & AR5K_INT_RX_DOPPLER) int_mask |= AR5K_IMR_RXDOPPLER; /* Note: Per queue interrupt masks * are set via reset_tx_queue (qcu.c) */ ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR); ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2); } else { if (new_mask & AR5K_INT_FATAL) int_mask |= (AR5K_IMR_SSERR | AR5K_IMR_MCABT | AR5K_IMR_HIUERR | AR5K_IMR_DPERR); ath5k_hw_reg_write(ah, int_mask, AR5K_IMR); } /* If RXNOFRM interrupt is masked disable it * by setting AR5K_RXNOFRM to zero */ if (!(new_mask & AR5K_INT_RXNOFRM)) ath5k_hw_reg_write(ah, 0, AR5K_RXNOFRM); /* Store new interrupt mask */ ah->ah_imr = new_mask; /* ..re-enable interrupts if AR5K_INT_GLOBAL is set */ if (new_mask & AR5K_INT_GLOBAL) { ath5k_hw_reg_write(ah, ah->ah_ier, AR5K_IER); ath5k_hw_reg_read(ah, AR5K_IER); } return old_mask; } debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k.c0000664000000000000000000012616112524662415021412 0ustar /* * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting * Copyright (c) 2004-2005 Atheros Communications, Inc. * Copyright (c) 2006 Devicescape Software, Inc. * Copyright (c) 2007 Jiri Slaby * Copyright (c) 2007 Luis R. Rodriguez * * Modified for gPXE, July 2009, by Joshua Oreman * Original from Linux kernel 2.6.30. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * */ FILE_LICENCE ( BSD3 ); #include #include #include #include #include #include #include "base.h" #include "reg.h" #define ATH5K_CALIB_INTERVAL 10 /* Calibrate PHY every 10 seconds */ #define ATH5K_RETRIES 4 /* Number of times to retry packet sends */ #define ATH5K_DESC_ALIGN 16 /* Alignment for TX/RX descriptors */ /******************\ * Internal defines * \******************/ /* Known PCI ids */ static struct pci_device_id ath5k_nics[] = { PCI_ROM(0x168c, 0x0207, "ath5210e", "Atheros 5210 early", AR5K_AR5210), PCI_ROM(0x168c, 0x0007, "ath5210", "Atheros 5210", AR5K_AR5210), PCI_ROM(0x168c, 0x0011, "ath5311", "Atheros 5311 (AHB)", AR5K_AR5211), PCI_ROM(0x168c, 0x0012, "ath5211", "Atheros 5211", AR5K_AR5211), PCI_ROM(0x168c, 0x0013, "ath5212", "Atheros 5212", AR5K_AR5212), PCI_ROM(0xa727, 0x0013, "ath5212c","3com Ath 5212", AR5K_AR5212), PCI_ROM(0x10b7, 0x0013, "rdag675", "3com 3CRDAG675", AR5K_AR5212), PCI_ROM(0x168c, 0x1014, "ath5212m", "Ath 5212 miniPCI", AR5K_AR5212), PCI_ROM(0x168c, 0x0014, "ath5212x14", "Atheros 5212 x14", AR5K_AR5212), PCI_ROM(0x168c, 0x0015, "ath5212x15", "Atheros 5212 x15", AR5K_AR5212), PCI_ROM(0x168c, 0x0016, "ath5212x16", "Atheros 5212 x16", AR5K_AR5212), PCI_ROM(0x168c, 0x0017, "ath5212x17", "Atheros 5212 x17", AR5K_AR5212), PCI_ROM(0x168c, 0x0018, "ath5212x18", "Atheros 5212 x18", AR5K_AR5212), PCI_ROM(0x168c, 0x0019, "ath5212x19", "Atheros 5212 x19", AR5K_AR5212), PCI_ROM(0x168c, 0x001a, "ath2413", "Atheros 2413 Griffin", AR5K_AR5212), PCI_ROM(0x168c, 0x001b, "ath5413", "Atheros 5413 Eagle", AR5K_AR5212), PCI_ROM(0x168c, 0x001c, "ath5212e", "Atheros 5212 PCI-E", AR5K_AR5212), PCI_ROM(0x168c, 0x001d, "ath2417", "Atheros 2417 Nala", AR5K_AR5212), }; /* Known SREVs */ static const struct ath5k_srev_name srev_names[] = { { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, { "5311B", AR5K_VERSION_MAC, AR5K_SREV_AR5311B }, { "5211", AR5K_VERSION_MAC, AR5K_SREV_AR5211 }, { "5212", AR5K_VERSION_MAC, AR5K_SREV_AR5212 }, { "5213", AR5K_VERSION_MAC, AR5K_SREV_AR5213 }, { "5213A", AR5K_VERSION_MAC, AR5K_SREV_AR5213A }, { "2413", AR5K_VERSION_MAC, AR5K_SREV_AR2413 }, { "2414", AR5K_VERSION_MAC, AR5K_SREV_AR2414 }, { "5424", AR5K_VERSION_MAC, AR5K_SREV_AR5424 }, { "5413", AR5K_VERSION_MAC, AR5K_SREV_AR5413 }, { "5414", AR5K_VERSION_MAC, AR5K_SREV_AR5414 }, { "2415", AR5K_VERSION_MAC, AR5K_SREV_AR2415 }, { "5416", AR5K_VERSION_MAC, AR5K_SREV_AR5416 }, { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, { "5111A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111A }, { "2111", AR5K_VERSION_RAD, AR5K_SREV_RAD_2111 }, { "5112", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112 }, { "5112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A }, { "5112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112B }, { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 }, { "2112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A }, { "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B }, { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 }, { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, }; #define ATH5K_SPMBL_NO 1 #define ATH5K_SPMBL_YES 2 #define ATH5K_SPMBL_BOTH 3 static const struct { u16 bitrate; u8 short_pmbl; u8 hw_code; } ath5k_rates[] = { { 10, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_1M }, { 20, ATH5K_SPMBL_NO, ATH5K_RATE_CODE_2M }, { 55, ATH5K_SPMBL_NO, ATH5K_RATE_CODE_5_5M }, { 110, ATH5K_SPMBL_NO, ATH5K_RATE_CODE_11M }, { 60, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_6M }, { 90, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_9M }, { 120, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_12M }, { 180, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_18M }, { 240, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_24M }, { 360, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_36M }, { 480, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_48M }, { 540, ATH5K_SPMBL_BOTH, ATH5K_RATE_CODE_54M }, { 20, ATH5K_SPMBL_YES, ATH5K_RATE_CODE_2M | AR5K_SET_SHORT_PREAMBLE }, { 55, ATH5K_SPMBL_YES, ATH5K_RATE_CODE_5_5M | AR5K_SET_SHORT_PREAMBLE }, { 110, ATH5K_SPMBL_YES, ATH5K_RATE_CODE_11M | AR5K_SET_SHORT_PREAMBLE }, { 0, 0, 0 }, }; #define ATH5K_NR_RATES 15 /* * Prototypes - PCI stack related functions */ static int ath5k_probe(struct pci_device *pdev, const struct pci_device_id *id); static void ath5k_remove(struct pci_device *pdev); struct pci_driver ath5k_pci_driver __pci_driver = { .ids = ath5k_nics, .id_count = sizeof(ath5k_nics) / sizeof(ath5k_nics[0]), .probe = ath5k_probe, .remove = ath5k_remove, }; /* * Prototypes - MAC 802.11 stack related functions */ static int ath5k_tx(struct net80211_device *dev, struct io_buffer *skb); static int ath5k_reset(struct ath5k_softc *sc, struct net80211_channel *chan); static int ath5k_reset_wake(struct ath5k_softc *sc); static int ath5k_start(struct net80211_device *dev); static void ath5k_stop(struct net80211_device *dev); static int ath5k_config(struct net80211_device *dev, int changed); static void ath5k_poll(struct net80211_device *dev); static void ath5k_irq(struct net80211_device *dev, int enable); static struct net80211_device_operations ath5k_ops = { .open = ath5k_start, .close = ath5k_stop, .transmit = ath5k_tx, .poll = ath5k_poll, .irq = ath5k_irq, .config = ath5k_config, }; /* * Prototypes - Internal functions */ /* Attach detach */ static int ath5k_attach(struct net80211_device *dev); static void ath5k_detach(struct net80211_device *dev); /* Channel/mode setup */ static unsigned int ath5k_copy_channels(struct ath5k_hw *ah, struct net80211_channel *channels, unsigned int mode, unsigned int max); static int ath5k_setup_bands(struct net80211_device *dev); static int ath5k_chan_set(struct ath5k_softc *sc, struct net80211_channel *chan); static void ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode); static void ath5k_mode_setup(struct ath5k_softc *sc); /* Descriptor setup */ static int ath5k_desc_alloc(struct ath5k_softc *sc); static void ath5k_desc_free(struct ath5k_softc *sc); /* Buffers setup */ static int ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf); static int ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf); static inline void ath5k_txbuf_free(struct ath5k_softc *sc, struct ath5k_buf *bf) { if (!bf->iob) return; net80211_tx_complete(sc->dev, bf->iob, 0, ECANCELED); bf->iob = NULL; } static inline void ath5k_rxbuf_free(struct ath5k_softc *sc __unused, struct ath5k_buf *bf) { free_iob(bf->iob); bf->iob = NULL; } /* Queues setup */ static int ath5k_txq_setup(struct ath5k_softc *sc, int qtype, int subtype); static void ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq); static void ath5k_txq_cleanup(struct ath5k_softc *sc); static void ath5k_txq_release(struct ath5k_softc *sc); /* Rx handling */ static int ath5k_rx_start(struct ath5k_softc *sc); static void ath5k_rx_stop(struct ath5k_softc *sc); /* Tx handling */ static void ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq); /* Interrupt handling */ static int ath5k_init(struct ath5k_softc *sc); static int ath5k_stop_hw(struct ath5k_softc *sc); static void ath5k_calibrate(struct ath5k_softc *sc); /* Filter */ static void ath5k_configure_filter(struct ath5k_softc *sc); /********************\ * PCI Initialization * \********************/ #if DBGLVL_MAX static const char * ath5k_chip_name(enum ath5k_srev_type type, u16 val) { const char *name = "xxxxx"; unsigned int i; for (i = 0; i < ARRAY_SIZE(srev_names); i++) { if (srev_names[i].sr_type != type) continue; if ((val & 0xf0) == srev_names[i].sr_val) name = srev_names[i].sr_name; if ((val & 0xff) == srev_names[i].sr_val) { name = srev_names[i].sr_name; break; } } return name; } #endif static int ath5k_probe(struct pci_device *pdev, const struct pci_device_id *id) { void *mem; struct ath5k_softc *sc; struct net80211_device *dev; int ret; u8 csz; adjust_pci_device(pdev); /* * Cache line size is used to size and align various * structures used to communicate with the hardware. */ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); if (csz == 0) { /* * We must have this setup properly for rx buffer * DMA to work so force a reasonable value here if it * comes up zero. */ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 16); } /* * The default setting of latency timer yields poor results, * set it to the value used by other systems. It may be worth * tweaking this setting more. */ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); /* * Disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state. */ pci_write_config_byte(pdev, 0x41, 0); mem = ioremap(pdev->membase, 0x10000); if (!mem) { DBG("ath5k: cannot remap PCI memory region\n"); ret = -EIO; goto err; } /* * Allocate dev (net80211 main struct) * and dev->priv (driver private data) */ dev = net80211_alloc(sizeof(*sc)); if (!dev) { DBG("ath5k: cannot allocate 802.11 device\n"); ret = -ENOMEM; goto err_map; } /* Initialize driver private data */ sc = dev->priv; sc->dev = dev; sc->pdev = pdev; sc->hwinfo = zalloc(sizeof(*sc->hwinfo)); if (!sc->hwinfo) { DBG("ath5k: cannot allocate 802.11 hardware info structure\n"); ret = -ENOMEM; goto err_free; } sc->hwinfo->flags = NET80211_HW_RX_HAS_FCS; sc->hwinfo->signal_type = NET80211_SIGNAL_DB; sc->hwinfo->signal_max = 40; /* 35dB should give perfect 54Mbps */ sc->hwinfo->channel_change_time = 5000; /* Avoid working with the device until setup is complete */ sc->status |= ATH_STAT_INVALID; sc->iobase = mem; sc->cachelsz = csz * 4; /* convert to bytes */ DBG("ath5k: register base at %p (%08lx)\n", sc->iobase, pdev->membase); DBG("ath5k: cache line size %d\n", sc->cachelsz); /* Set private data */ pci_set_drvdata(pdev, dev); dev->netdev->dev = (struct device *)pdev; /* Initialize device */ ret = ath5k_hw_attach(sc, id->driver_data, &sc->ah); if (ret) goto err_free_hwinfo; /* Finish private driver data initialization */ ret = ath5k_attach(dev); if (ret) goto err_ah; #if DBGLVL_MAX DBG("Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), sc->ah->ah_mac_srev, sc->ah->ah_phy_revision); if (!sc->ah->ah_single_chip) { /* Single chip radio (!RF5111) */ if (sc->ah->ah_radio_5ghz_revision && !sc->ah->ah_radio_2ghz_revision) { /* No 5GHz support -> report 2GHz radio */ if (!(sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11A)) { DBG("RF%s 2GHz radio found (0x%x)\n", ath5k_chip_name(AR5K_VERSION_RAD, sc->ah->ah_radio_5ghz_revision), sc->ah->ah_radio_5ghz_revision); /* No 2GHz support (5110 and some * 5Ghz only cards) -> report 5Ghz radio */ } else if (!(sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11B)) { DBG("RF%s 5GHz radio found (0x%x)\n", ath5k_chip_name(AR5K_VERSION_RAD, sc->ah->ah_radio_5ghz_revision), sc->ah->ah_radio_5ghz_revision); /* Multiband radio */ } else { DBG("RF%s multiband radio found (0x%x)\n", ath5k_chip_name(AR5K_VERSION_RAD, sc->ah->ah_radio_5ghz_revision), sc->ah->ah_radio_5ghz_revision); } } /* Multi chip radio (RF5111 - RF2111) -> * report both 2GHz/5GHz radios */ else if (sc->ah->ah_radio_5ghz_revision && sc->ah->ah_radio_2ghz_revision) { DBG("RF%s 5GHz radio found (0x%x)\n", ath5k_chip_name(AR5K_VERSION_RAD, sc->ah->ah_radio_5ghz_revision), sc->ah->ah_radio_5ghz_revision); DBG("RF%s 2GHz radio found (0x%x)\n", ath5k_chip_name(AR5K_VERSION_RAD, sc->ah->ah_radio_2ghz_revision), sc->ah->ah_radio_2ghz_revision); } } #endif /* Ready to go */ sc->status &= ~ATH_STAT_INVALID; return 0; err_ah: ath5k_hw_detach(sc->ah); err_free_hwinfo: free(sc->hwinfo); err_free: net80211_free(dev); err_map: iounmap(mem); err: return ret; } static void ath5k_remove(struct pci_device *pdev) { struct net80211_device *dev = pci_get_drvdata(pdev); struct ath5k_softc *sc = dev->priv; ath5k_detach(dev); ath5k_hw_detach(sc->ah); iounmap(sc->iobase); free(sc->hwinfo); net80211_free(dev); } /***********************\ * Driver Initialization * \***********************/ static int ath5k_attach(struct net80211_device *dev) { struct ath5k_softc *sc = dev->priv; struct ath5k_hw *ah = sc->ah; int ret; /* * Collect the channel list. The 802.11 layer * is resposible for filtering this list based * on settings like the phy mode and regulatory * domain restrictions. */ ret = ath5k_setup_bands(dev); if (ret) { DBG("ath5k: can't get channels\n"); goto err; } /* NB: setup here so ath5k_rate_update is happy */ if (ah->ah_modes & AR5K_MODE_BIT_11A) ath5k_setcurmode(sc, AR5K_MODE_11A); else ath5k_setcurmode(sc, AR5K_MODE_11B); /* * Allocate tx+rx descriptors and populate the lists. */ ret = ath5k_desc_alloc(sc); if (ret) { DBG("ath5k: can't allocate descriptors\n"); goto err; } /* * Allocate hardware transmit queues. Note that hw functions * handle reseting these queues at the needed time. */ ret = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE); if (ret) { DBG("ath5k: can't setup xmit queue\n"); goto err_desc; } sc->last_calib_ticks = currticks(); ret = ath5k_eeprom_read_mac(ah, sc->hwinfo->hwaddr); if (ret) { DBG("ath5k: unable to read address from EEPROM: 0x%04x\n", sc->pdev->device); goto err_queues; } memset(sc->bssidmask, 0xff, ETH_ALEN); ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); ret = net80211_register(sc->dev, &ath5k_ops, sc->hwinfo); if (ret) { DBG("ath5k: can't register ieee80211 hw\n"); goto err_queues; } return 0; err_queues: ath5k_txq_release(sc); err_desc: ath5k_desc_free(sc); err: return ret; } static void ath5k_detach(struct net80211_device *dev) { struct ath5k_softc *sc = dev->priv; net80211_unregister(dev); ath5k_desc_free(sc); ath5k_txq_release(sc); } /********************\ * Channel/mode setup * \********************/ /* * Convert IEEE channel number to MHz frequency. */ static inline short ath5k_ieee2mhz(short chan) { if (chan < 14) return 2407 + 5 * chan; if (chan == 14) return 2484; if (chan < 27) return 2212 + 20 * chan; return 5000 + 5 * chan; } static unsigned int ath5k_copy_channels(struct ath5k_hw *ah, struct net80211_channel *channels, unsigned int mode, unsigned int max) { unsigned int i, count, size, chfreq, freq, ch; if (!(ah->ah_modes & (1 << mode))) return 0; switch (mode) { case AR5K_MODE_11A: case AR5K_MODE_11A_TURBO: /* 1..220, but 2GHz frequencies are filtered by check_channel */ size = 220; chfreq = CHANNEL_5GHZ; break; case AR5K_MODE_11B: case AR5K_MODE_11G: case AR5K_MODE_11G_TURBO: size = 26; chfreq = CHANNEL_2GHZ; break; default: return 0; } for (i = 0, count = 0; i < size && max > 0; i++) { ch = i + 1 ; freq = ath5k_ieee2mhz(ch); /* Check if channel is supported by the chipset */ if (!ath5k_channel_ok(ah, freq, chfreq)) continue; /* Write channel info and increment counter */ channels[count].center_freq = freq; channels[count].maxpower = 0; /* use regulatory */ channels[count].band = (chfreq == CHANNEL_2GHZ) ? NET80211_BAND_2GHZ : NET80211_BAND_5GHZ; switch (mode) { case AR5K_MODE_11A: case AR5K_MODE_11G: channels[count].hw_value = chfreq | CHANNEL_OFDM; break; case AR5K_MODE_11A_TURBO: case AR5K_MODE_11G_TURBO: channels[count].hw_value = chfreq | CHANNEL_OFDM | CHANNEL_TURBO; break; case AR5K_MODE_11B: channels[count].hw_value = CHANNEL_B; } count++; max--; } return count; } static int ath5k_setup_bands(struct net80211_device *dev) { struct ath5k_softc *sc = dev->priv; struct ath5k_hw *ah = sc->ah; int max_c, count_c = 0; int i; int band; max_c = sizeof(sc->hwinfo->channels) / sizeof(sc->hwinfo->channels[0]); /* 2GHz band */ if (sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11G) { /* G mode */ band = NET80211_BAND_2GHZ; sc->hwinfo->bands = NET80211_BAND_BIT_2GHZ; sc->hwinfo->modes = (NET80211_MODE_G | NET80211_MODE_B); for (i = 0; i < 12; i++) sc->hwinfo->rates[band][i] = ath5k_rates[i].bitrate; sc->hwinfo->nr_rates[band] = 12; sc->hwinfo->nr_channels = ath5k_copy_channels(ah, sc->hwinfo->channels, AR5K_MODE_11G, max_c); count_c = sc->hwinfo->nr_channels; max_c -= count_c; } else if (sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11B) { /* B mode */ band = NET80211_BAND_2GHZ; sc->hwinfo->bands = NET80211_BAND_BIT_2GHZ; sc->hwinfo->modes = NET80211_MODE_B; for (i = 0; i < 4; i++) sc->hwinfo->rates[band][i] = ath5k_rates[i].bitrate; sc->hwinfo->nr_rates[band] = 4; sc->hwinfo->nr_channels = ath5k_copy_channels(ah, sc->hwinfo->channels, AR5K_MODE_11B, max_c); count_c = sc->hwinfo->nr_channels; max_c -= count_c; } /* 5GHz band, A mode */ if (sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11A) { band = NET80211_BAND_5GHZ; sc->hwinfo->bands |= NET80211_BAND_BIT_5GHZ; sc->hwinfo->modes |= NET80211_MODE_A; for (i = 0; i < 8; i++) sc->hwinfo->rates[band][i] = ath5k_rates[i+4].bitrate; sc->hwinfo->nr_rates[band] = 8; sc->hwinfo->nr_channels = ath5k_copy_channels(ah, sc->hwinfo->channels, AR5K_MODE_11B, max_c); count_c = sc->hwinfo->nr_channels; max_c -= count_c; } return 0; } /* * Set/change channels. If the channel is really being changed, * it's done by reseting the chip. To accomplish this we must * first cleanup any pending DMA, then restart stuff after a la * ath5k_init. */ static int ath5k_chan_set(struct ath5k_softc *sc, struct net80211_channel *chan) { if (chan->center_freq != sc->curchan->center_freq || chan->hw_value != sc->curchan->hw_value) { /* * To switch channels clear any pending DMA operations; * wait long enough for the RX fifo to drain, reset the * hardware at the new frequency, and then re-enable * the relevant bits of the h/w. */ DBG2("ath5k: resetting for channel change (%d -> %d MHz)\n", sc->curchan->center_freq, chan->center_freq); return ath5k_reset(sc, chan); } return 0; } static void ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) { sc->curmode = mode; if (mode == AR5K_MODE_11A) { sc->curband = NET80211_BAND_5GHZ; } else { sc->curband = NET80211_BAND_2GHZ; } } static void ath5k_mode_setup(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; u32 rfilt; /* configure rx filter */ rfilt = sc->filter_flags; ath5k_hw_set_rx_filter(ah, rfilt); if (ath5k_hw_hasbssidmask(ah)) ath5k_hw_set_bssid_mask(ah, sc->bssidmask); /* configure operational mode */ ath5k_hw_set_opmode(ah); ath5k_hw_set_mcast_filter(ah, 0, 0); } static inline int ath5k_hw_rix_to_bitrate(int hw_rix) { int i; for (i = 0; i < ATH5K_NR_RATES; i++) { if (ath5k_rates[i].hw_code == hw_rix) return ath5k_rates[i].bitrate; } DBG("ath5k: invalid rix %02x\n", hw_rix); return 10; /* use lowest rate */ } int ath5k_bitrate_to_hw_rix(int bitrate) { int i; for (i = 0; i < ATH5K_NR_RATES; i++) { if (ath5k_rates[i].bitrate == bitrate) return ath5k_rates[i].hw_code; } DBG("ath5k: invalid bitrate %d\n", bitrate); return ATH5K_RATE_CODE_1M; /* use lowest rate */ } /***************\ * Buffers setup * \***************/ static struct io_buffer * ath5k_rx_iob_alloc(struct ath5k_softc *sc, u32 *iob_addr) { struct io_buffer *iob; unsigned int off; /* * Allocate buffer with headroom_needed space for the * fake physical layer header at the start. */ iob = alloc_iob(sc->rxbufsize + sc->cachelsz - 1); if (!iob) { DBG("ath5k: can't alloc iobuf of size %d\n", sc->rxbufsize + sc->cachelsz - 1); return NULL; } *iob_addr = virt_to_bus(iob->data); /* * Cache-line-align. This is important (for the * 5210 at least) as not doing so causes bogus data * in rx'd frames. */ off = *iob_addr % sc->cachelsz; if (off != 0) { iob_reserve(iob, sc->cachelsz - off); *iob_addr += sc->cachelsz - off; } return iob; } static int ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) { struct ath5k_hw *ah = sc->ah; struct io_buffer *iob = bf->iob; struct ath5k_desc *ds; if (!iob) { iob = ath5k_rx_iob_alloc(sc, &bf->iobaddr); if (!iob) return -ENOMEM; bf->iob = iob; } /* * Setup descriptors. For receive we always terminate * the descriptor list with a self-linked entry so we'll * not get overrun under high load (as can happen with a * 5212 when ANI processing enables PHY error frames). * * To insure the last descriptor is self-linked we create * each descriptor as self-linked and add it to the end. As * each additional descriptor is added the previous self-linked * entry is ``fixed'' naturally. This should be safe even * if DMA is happening. When processing RX interrupts we * never remove/process the last, self-linked, entry on the * descriptor list. This insures the hardware always has * someplace to write a new frame. */ ds = bf->desc; ds->ds_link = bf->daddr; /* link to self */ ds->ds_data = bf->iobaddr; if (ah->ah_setup_rx_desc(ah, ds, iob_tailroom(iob), /* buffer size */ 0) != 0) { DBG("ath5k: error setting up RX descriptor for %d bytes\n", iob_tailroom(iob)); return -EINVAL; } if (sc->rxlink != NULL) *sc->rxlink = bf->daddr; sc->rxlink = &ds->ds_link; return 0; } static int ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) { struct ath5k_hw *ah = sc->ah; struct ath5k_txq *txq = &sc->txq; struct ath5k_desc *ds = bf->desc; struct io_buffer *iob = bf->iob; unsigned int pktlen, flags; int ret; u16 duration = 0; u16 cts_rate = 0; flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; bf->iobaddr = virt_to_bus(iob->data); pktlen = iob_len(iob); /* FIXME: If we are in g mode and rate is a CCK rate * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta * from tx power (value is in dB units already) */ if (sc->dev->phy_flags & NET80211_PHY_USE_PROTECTION) { struct net80211_device *dev = sc->dev; flags |= AR5K_TXDESC_CTSENA; cts_rate = sc->hw_rtscts_rate; duration = net80211_cts_duration(dev, pktlen); } ret = ah->ah_setup_tx_desc(ah, ds, pktlen, IEEE80211_TYP_FRAME_HEADER_LEN, AR5K_PKT_TYPE_NORMAL, sc->power_level * 2, sc->hw_rate, ATH5K_RETRIES, AR5K_TXKEYIX_INVALID, 0, flags, cts_rate, duration); if (ret) return ret; ds->ds_link = 0; ds->ds_data = bf->iobaddr; list_add_tail(&bf->list, &txq->q); if (txq->link == NULL) /* is this first packet? */ ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); else /* no, so only link it */ *txq->link = bf->daddr; txq->link = &ds->ds_link; ath5k_hw_start_tx_dma(ah, txq->qnum); mb(); return 0; } /*******************\ * Descriptors setup * \*******************/ static int ath5k_desc_alloc(struct ath5k_softc *sc) { struct ath5k_desc *ds; struct ath5k_buf *bf; u32 da; unsigned int i; int ret; /* allocate descriptors */ sc->desc_len = sizeof(struct ath5k_desc) * (ATH_TXBUF + ATH_RXBUF + 1); sc->desc = malloc_dma(sc->desc_len, ATH5K_DESC_ALIGN); if (sc->desc == NULL) { DBG("ath5k: can't allocate descriptors\n"); ret = -ENOMEM; goto err; } memset(sc->desc, 0, sc->desc_len); sc->desc_daddr = virt_to_bus(sc->desc); ds = sc->desc; da = sc->desc_daddr; bf = calloc(ATH_TXBUF + ATH_RXBUF + 1, sizeof(struct ath5k_buf)); if (bf == NULL) { DBG("ath5k: can't allocate buffer pointers\n"); ret = -ENOMEM; goto err_free; } sc->bufptr = bf; INIT_LIST_HEAD(&sc->rxbuf); for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) { bf->desc = ds; bf->daddr = da; list_add_tail(&bf->list, &sc->rxbuf); } INIT_LIST_HEAD(&sc->txbuf); sc->txbuf_len = ATH_TXBUF; for (i = 0; i < ATH_TXBUF; i++, bf++, ds++, da += sizeof(*ds)) { bf->desc = ds; bf->daddr = da; list_add_tail(&bf->list, &sc->txbuf); } return 0; err_free: free_dma(sc->desc, sc->desc_len); err: sc->desc = NULL; return ret; } static void ath5k_desc_free(struct ath5k_softc *sc) { struct ath5k_buf *bf; list_for_each_entry(bf, &sc->txbuf, list) ath5k_txbuf_free(sc, bf); list_for_each_entry(bf, &sc->rxbuf, list) ath5k_rxbuf_free(sc, bf); /* Free memory associated with all descriptors */ free_dma(sc->desc, sc->desc_len); free(sc->bufptr); sc->bufptr = NULL; } /**************\ * Queues setup * \**************/ static int ath5k_txq_setup(struct ath5k_softc *sc, int qtype, int subtype) { struct ath5k_hw *ah = sc->ah; struct ath5k_txq *txq; struct ath5k_txq_info qi = { .tqi_subtype = subtype, .tqi_aifs = AR5K_TXQ_USEDEFAULT, .tqi_cw_min = AR5K_TXQ_USEDEFAULT, .tqi_cw_max = AR5K_TXQ_USEDEFAULT }; int qnum; /* * Enable interrupts only for EOL and DESC conditions. * We mark tx descriptors to receive a DESC interrupt * when a tx queue gets deep; otherwise waiting for the * EOL to reap descriptors. Note that this is done to * reduce interrupt load and this only defers reaping * descriptors, never transmitting frames. Aside from * reducing interrupts this also permits more concurrency. * The only potential downside is if the tx queue backs * up in which case the top half of the kernel may backup * due to a lack of tx descriptors. */ qi.tqi_flags = AR5K_TXQ_FLAG_TXEOLINT_ENABLE | AR5K_TXQ_FLAG_TXDESCINT_ENABLE; qnum = ath5k_hw_setup_tx_queue(ah, qtype, &qi); if (qnum < 0) { DBG("ath5k: can't set up a TX queue\n"); return -EIO; } txq = &sc->txq; if (!txq->setup) { txq->qnum = qnum; txq->link = NULL; INIT_LIST_HEAD(&txq->q); txq->setup = 1; } return 0; } static void ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) { struct ath5k_buf *bf, *bf0; list_for_each_entry_safe(bf, bf0, &txq->q, list) { ath5k_txbuf_free(sc, bf); list_del(&bf->list); list_add_tail(&bf->list, &sc->txbuf); sc->txbuf_len++; } txq->link = NULL; } /* * Drain the transmit queues and reclaim resources. */ static void ath5k_txq_cleanup(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; if (!(sc->status & ATH_STAT_INVALID)) { /* don't touch the hardware if marked invalid */ if (sc->txq.setup) { ath5k_hw_stop_tx_dma(ah, sc->txq.qnum); DBG("ath5k: txq [%d] %x, link %p\n", sc->txq.qnum, ath5k_hw_get_txdp(ah, sc->txq.qnum), sc->txq.link); } } if (sc->txq.setup) ath5k_txq_drainq(sc, &sc->txq); } static void ath5k_txq_release(struct ath5k_softc *sc) { if (sc->txq.setup) { ath5k_hw_release_tx_queue(sc->ah); sc->txq.setup = 0; } } /*************\ * RX Handling * \*************/ /* * Enable the receive h/w following a reset. */ static int ath5k_rx_start(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; struct ath5k_buf *bf; int ret; sc->rxbufsize = IEEE80211_MAX_LEN; if (sc->rxbufsize % sc->cachelsz != 0) sc->rxbufsize += sc->cachelsz - (sc->rxbufsize % sc->cachelsz); sc->rxlink = NULL; list_for_each_entry(bf, &sc->rxbuf, list) { ret = ath5k_rxbuf_setup(sc, bf); if (ret != 0) return ret; } bf = list_entry(sc->rxbuf.next, struct ath5k_buf, list); ath5k_hw_set_rxdp(ah, bf->daddr); ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ ath5k_mode_setup(sc); /* set filters, etc. */ ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ return 0; } /* * Disable the receive h/w in preparation for a reset. */ static void ath5k_rx_stop(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; ath5k_hw_stop_rx_pcu(ah); /* disable PCU */ ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ sc->rxlink = NULL; /* just in case */ } static void ath5k_handle_rx(struct ath5k_softc *sc) { struct ath5k_rx_status rs; struct io_buffer *iob, *next_iob; u32 next_iob_addr; struct ath5k_buf *bf, *bf_last; struct ath5k_desc *ds; int ret; memset(&rs, 0, sizeof(rs)); if (list_empty(&sc->rxbuf)) { DBG("ath5k: empty rx buf pool\n"); return; } bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list); do { bf = list_entry(sc->rxbuf.next, struct ath5k_buf, list); assert(bf->iob != NULL); iob = bf->iob; ds = bf->desc; /* * last buffer must not be freed to ensure proper hardware * function. When the hardware finishes also a packet next to * it, we are sure, it doesn't use it anymore and we can go on. */ if (bf_last == bf) bf->flags |= 1; if (bf->flags) { struct ath5k_buf *bf_next = list_entry(bf->list.next, struct ath5k_buf, list); ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc, &rs); if (ret) break; bf->flags &= ~1; /* skip the overwritten one (even status is martian) */ goto next; } ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs); if (ret) { if (ret != -EINPROGRESS) { DBG("ath5k: error in processing rx desc: %s\n", strerror(ret)); net80211_rx_err(sc->dev, NULL, -ret); } else { /* normal return, reached end of available descriptors */ } return; } if (rs.rs_more) { DBG("ath5k: unsupported fragmented rx\n"); goto next; } if (rs.rs_status) { if (rs.rs_status & AR5K_RXERR_PHY) { DBG("ath5k: rx PHY error\n"); goto next; } if (rs.rs_status & AR5K_RXERR_CRC) { net80211_rx_err(sc->dev, NULL, EIO); goto next; } if (rs.rs_status & AR5K_RXERR_DECRYPT) { /* * Decrypt error. If the error occurred * because there was no hardware key, then * let the frame through so the upper layers * can process it. This is necessary for 5210 * parts which have no way to setup a ``clear'' * key cache entry. * * XXX do key cache faulting */ if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && !(rs.rs_status & AR5K_RXERR_CRC)) goto accept; } /* any other error, unhandled */ DBG("ath5k: packet rx status %x\n", rs.rs_status); goto next; } accept: next_iob = ath5k_rx_iob_alloc(sc, &next_iob_addr); /* * If we can't replace bf->iob with a new iob under memory * pressure, just skip this packet */ if (!next_iob) { DBG("ath5k: dropping packet under memory pressure\n"); goto next; } iob_put(iob, rs.rs_datalen); /* The MAC header is padded to have 32-bit boundary if the * packet payload is non-zero. However, gPXE only * supports standard 802.11 packets with 24-byte * header, so no padding correction should be needed. */ DBG2("ath5k: rx %d bytes, signal %d\n", rs.rs_datalen, rs.rs_rssi); net80211_rx(sc->dev, iob, rs.rs_rssi, ath5k_hw_rix_to_bitrate(rs.rs_rate)); bf->iob = next_iob; bf->iobaddr = next_iob_addr; next: list_del(&bf->list); list_add_tail(&bf->list, &sc->rxbuf); } while (ath5k_rxbuf_setup(sc, bf) == 0); } /*************\ * TX Handling * \*************/ static void ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) { struct ath5k_tx_status ts; struct ath5k_buf *bf, *bf0; struct ath5k_desc *ds; struct io_buffer *iob; int ret; memset(&ts, 0, sizeof(ts)); list_for_each_entry_safe(bf, bf0, &txq->q, list) { ds = bf->desc; ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); if (ret) { if (ret != -EINPROGRESS) { DBG("ath5k: error in processing tx desc: %s\n", strerror(ret)); } else { /* normal return, reached end of tx completions */ } break; } iob = bf->iob; bf->iob = NULL; DBG2("ath5k: tx %d bytes complete, %d retries\n", iob_len(iob), ts.ts_retry[0]); net80211_tx_complete(sc->dev, iob, ts.ts_retry[0], ts.ts_status ? EIO : 0); list_del(&bf->list); list_add_tail(&bf->list, &sc->txbuf); sc->txbuf_len++; } if (list_empty(&txq->q)) txq->link = NULL; } static void ath5k_handle_tx(struct ath5k_softc *sc) { ath5k_tx_processq(sc, &sc->txq); } /********************\ * Interrupt handling * \********************/ static void ath5k_irq(struct net80211_device *dev, int enable) { struct ath5k_softc *sc = dev->priv; struct ath5k_hw *ah = sc->ah; sc->irq_ena = enable; ah->ah_ier = enable ? AR5K_IER_ENABLE : AR5K_IER_DISABLE; ath5k_hw_reg_write(ah, ah->ah_ier, AR5K_IER); ath5k_hw_set_imr(ah, sc->imask); } static int ath5k_init(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; int ret, i; /* * Stop anything previously setup. This is safe * no matter this is the first time through or not. */ ath5k_stop_hw(sc); /* * The basic interface to setting the hardware in a good * state is ``reset''. On return the hardware is known to * be powered up and with interrupts disabled. This must * be followed by initialization of the appropriate bits * and then setup of the interrupt mask. */ sc->curchan = sc->dev->channels + sc->dev->channel; sc->curband = sc->curchan->band; sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | AR5K_INT_FATAL | AR5K_INT_GLOBAL; ret = ath5k_reset(sc, NULL); if (ret) goto done; /* * Reset the key cache since some parts do not reset the * contents on initial power up or resume from suspend. */ for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) ath5k_hw_reset_key(ah, i); /* Set ack to be sent at low bit-rates */ ath5k_hw_set_ack_bitrate_high(ah, 0); ret = 0; done: mb(); return ret; } static int ath5k_stop_hw(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; /* * Shutdown the hardware and driver: * stop output from above * disable interrupts * turn off timers * turn off the radio * clear transmit machinery * clear receive machinery * drain and release tx queues * reclaim beacon resources * power down hardware * * Note that some of this work is not possible if the * hardware is gone (invalid). */ if (!(sc->status & ATH_STAT_INVALID)) { ath5k_hw_set_imr(ah, 0); } ath5k_txq_cleanup(sc); if (!(sc->status & ATH_STAT_INVALID)) { ath5k_rx_stop(sc); ath5k_hw_phy_disable(ah); } else sc->rxlink = NULL; return 0; } static void ath5k_poll(struct net80211_device *dev) { struct ath5k_softc *sc = dev->priv; struct ath5k_hw *ah = sc->ah; enum ath5k_int status; unsigned int counter = 1000; if (currticks() - sc->last_calib_ticks > ATH5K_CALIB_INTERVAL * ticks_per_sec()) { ath5k_calibrate(sc); sc->last_calib_ticks = currticks(); } if ((sc->status & ATH_STAT_INVALID) || (sc->irq_ena && !ath5k_hw_is_intr_pending(ah))) return; do { ath5k_hw_get_isr(ah, &status); /* NB: clears IRQ too */ DBGP("ath5k: status %#x/%#x\n", status, sc->imask); if (status & AR5K_INT_FATAL) { /* * Fatal errors are unrecoverable. * Typically these are caused by DMA errors. */ DBG("ath5k: fatal error, resetting\n"); ath5k_reset_wake(sc); } else if (status & AR5K_INT_RXORN) { DBG("ath5k: rx overrun, resetting\n"); ath5k_reset_wake(sc); } else { if (status & AR5K_INT_RXEOL) { /* * NB: the hardware should re-read the link when * RXE bit is written, but it doesn't work at * least on older hardware revs. */ DBG("ath5k: rx EOL\n"); sc->rxlink = NULL; } if (status & AR5K_INT_TXURN) { /* bump tx trigger level */ DBG("ath5k: tx underrun\n"); ath5k_hw_update_tx_triglevel(ah, 1); } if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) ath5k_handle_rx(sc); if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC | AR5K_INT_TXERR | AR5K_INT_TXEOL)) ath5k_handle_tx(sc); } } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0); if (!counter) DBG("ath5k: too many interrupts, giving up for now\n"); } /* * Periodically recalibrate the PHY to account * for temperature/environment changes. */ static void ath5k_calibrate(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) { /* * Rfgain is out of bounds, reset the chip * to load new gain values. */ DBG("ath5k: resetting for calibration\n"); ath5k_reset_wake(sc); } if (ath5k_hw_phy_calibrate(ah, sc->curchan)) DBG("ath5k: calibration of channel %d failed\n", sc->curchan->channel_nr); } /********************\ * Net80211 functions * \********************/ static int ath5k_tx(struct net80211_device *dev, struct io_buffer *iob) { struct ath5k_softc *sc = dev->priv; struct ath5k_buf *bf; int rc; /* * The hardware expects the header padded to 4 byte boundaries. * gPXE only ever sends 24-byte headers, so no action necessary. */ if (list_empty(&sc->txbuf)) { DBG("ath5k: dropping packet because no tx bufs available\n"); return -ENOBUFS; } bf = list_entry(sc->txbuf.next, struct ath5k_buf, list); list_del(&bf->list); sc->txbuf_len--; bf->iob = iob; if ((rc = ath5k_txbuf_setup(sc, bf)) != 0) { bf->iob = NULL; list_add_tail(&bf->list, &sc->txbuf); sc->txbuf_len++; return rc; } return 0; } /* * Reset the hardware. If chan is not NULL, then also pause rx/tx * and change to the given channel. */ static int ath5k_reset(struct ath5k_softc *sc, struct net80211_channel *chan) { struct ath5k_hw *ah = sc->ah; int ret; if (chan) { ath5k_hw_set_imr(ah, 0); ath5k_txq_cleanup(sc); ath5k_rx_stop(sc); sc->curchan = chan; sc->curband = chan->band; } ret = ath5k_hw_reset(ah, sc->curchan, 1); if (ret) { DBG("ath5k: can't reset hardware: %s\n", strerror(ret)); return ret; } ret = ath5k_rx_start(sc); if (ret) { DBG("ath5k: can't start rx logic: %s\n", strerror(ret)); return ret; } /* * Change channels and update the h/w rate map if we're switching; * e.g. 11a to 11b/g. * * We may be doing a reset in response to an ioctl that changes the * channel so update any state that might change as a result. * * XXX needed? */ /* ath5k_chan_change(sc, c); */ /* Reenable interrupts if necessary */ ath5k_irq(sc->dev, sc->irq_ena); return 0; } static int ath5k_reset_wake(struct ath5k_softc *sc) { return ath5k_reset(sc, sc->curchan); } static int ath5k_start(struct net80211_device *dev) { struct ath5k_softc *sc = dev->priv; int ret; if ((ret = ath5k_init(sc)) != 0) return ret; sc->assoc = 0; ath5k_configure_filter(sc); ath5k_hw_set_lladdr(sc->ah, dev->netdev->ll_addr); return 0; } static void ath5k_stop(struct net80211_device *dev) { struct ath5k_softc *sc = dev->priv; u8 mac[ETH_ALEN] = {}; ath5k_hw_set_lladdr(sc->ah, mac); ath5k_stop_hw(sc); } static int ath5k_config(struct net80211_device *dev, int changed) { struct ath5k_softc *sc = dev->priv; struct ath5k_hw *ah = sc->ah; struct net80211_channel *chan = &dev->channels[dev->channel]; int ret; if (changed & NET80211_CFG_CHANNEL) { sc->power_level = chan->maxpower; if ((ret = ath5k_chan_set(sc, chan)) != 0) return ret; } if ((changed & NET80211_CFG_RATE) || (changed & NET80211_CFG_PHY_PARAMS)) { int spmbl = ATH5K_SPMBL_NO; u16 rate = dev->rates[dev->rate]; u16 slowrate = dev->rates[dev->rtscts_rate]; int i; if (dev->phy_flags & NET80211_PHY_USE_SHORT_PREAMBLE) spmbl = ATH5K_SPMBL_YES; for (i = 0; i < ATH5K_NR_RATES; i++) { if (ath5k_rates[i].bitrate == rate && (ath5k_rates[i].short_pmbl & spmbl)) sc->hw_rate = ath5k_rates[i].hw_code; if (ath5k_rates[i].bitrate == slowrate && (ath5k_rates[i].short_pmbl & spmbl)) sc->hw_rtscts_rate = ath5k_rates[i].hw_code; } } if (changed & NET80211_CFG_ASSOC) { sc->assoc = !!(dev->state & NET80211_ASSOCIATED); if (sc->assoc) { memcpy(ah->ah_bssid, dev->bssid, ETH_ALEN); } else { memset(ah->ah_bssid, 0xff, ETH_ALEN); } ath5k_hw_set_associd(ah, ah->ah_bssid, 0); } return 0; } /* * o always accept unicast, broadcast, and multicast traffic * o multicast traffic for all BSSIDs will be enabled if mac80211 * says it should be * o maintain current state of phy ofdm or phy cck error reception. * If the hardware detects any of these type of errors then * ath5k_hw_get_rx_filter() will pass to us the respective * hardware filters to be able to receive these type of frames. * o probe request frames are accepted only when operating in * hostap, adhoc, or monitor modes * o enable promiscuous mode according to the interface state * o accept beacons: * - when operating in adhoc mode so the 802.11 layer creates * node table entries for peers, * - when operating in station mode for collecting rssi data when * the station is otherwise quiet, or * - when scanning */ static void ath5k_configure_filter(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; u32 mfilt[2], rfilt; /* Enable all multicast */ mfilt[0] = ~0; mfilt[1] = ~0; /* Enable data frames and beacons */ rfilt = (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | AR5K_RX_FILTER_MCAST | AR5K_RX_FILTER_BEACON); /* Set filters */ ath5k_hw_set_rx_filter(ah, rfilt); /* Set multicast bits */ ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); /* Set the cached hw filter flags, this will alter actually * be set in HW */ sc->filter_flags = rfilt; } debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/rfgain.h0000664000000000000000000005524412524662415021654 0ustar /* * RF Gain optimization * * Copyright (c) 2004-2009 Reyk Floeter * Copyright (c) 2006-2009 Nick Kossifidis * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ /* * Mode-specific RF Gain table (64bytes) for RF5111/5112 * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial * RF Gain values are included in AR5K_AR5210_INI) */ struct ath5k_ini_rfgain { u16 rfg_register; /* RF Gain register address */ u32 rfg_value[2]; /* [freq (see below)] */ }; /* Initial RF Gain settings for RF5111 */ static const struct ath5k_ini_rfgain rfgain_5111[] = { /* 5Ghz 2Ghz */ { AR5K_RF_GAIN(0), { 0x000001a9, 0x00000000 } }, { AR5K_RF_GAIN(1), { 0x000001e9, 0x00000040 } }, { AR5K_RF_GAIN(2), { 0x00000029, 0x00000080 } }, { AR5K_RF_GAIN(3), { 0x00000069, 0x00000150 } }, { AR5K_RF_GAIN(4), { 0x00000199, 0x00000190 } }, { AR5K_RF_GAIN(5), { 0x000001d9, 0x000001d0 } }, { AR5K_RF_GAIN(6), { 0x00000019, 0x00000010 } }, { AR5K_RF_GAIN(7), { 0x00000059, 0x00000044 } }, { AR5K_RF_GAIN(8), { 0x00000099, 0x00000084 } }, { AR5K_RF_GAIN(9), { 0x000001a5, 0x00000148 } }, { AR5K_RF_GAIN(10), { 0x000001e5, 0x00000188 } }, { AR5K_RF_GAIN(11), { 0x00000025, 0x000001c8 } }, { AR5K_RF_GAIN(12), { 0x000001c8, 0x00000014 } }, { AR5K_RF_GAIN(13), { 0x00000008, 0x00000042 } }, { AR5K_RF_GAIN(14), { 0x00000048, 0x00000082 } }, { AR5K_RF_GAIN(15), { 0x00000088, 0x00000178 } }, { AR5K_RF_GAIN(16), { 0x00000198, 0x000001b8 } }, { AR5K_RF_GAIN(17), { 0x000001d8, 0x000001f8 } }, { AR5K_RF_GAIN(18), { 0x00000018, 0x00000012 } }, { AR5K_RF_GAIN(19), { 0x00000058, 0x00000052 } }, { AR5K_RF_GAIN(20), { 0x00000098, 0x00000092 } }, { AR5K_RF_GAIN(21), { 0x000001a4, 0x0000017c } }, { AR5K_RF_GAIN(22), { 0x000001e4, 0x000001bc } }, { AR5K_RF_GAIN(23), { 0x00000024, 0x000001fc } }, { AR5K_RF_GAIN(24), { 0x00000064, 0x0000000a } }, { AR5K_RF_GAIN(25), { 0x000000a4, 0x0000004a } }, { AR5K_RF_GAIN(26), { 0x000000e4, 0x0000008a } }, { AR5K_RF_GAIN(27), { 0x0000010a, 0x0000015a } }, { AR5K_RF_GAIN(28), { 0x0000014a, 0x0000019a } }, { AR5K_RF_GAIN(29), { 0x0000018a, 0x000001da } }, { AR5K_RF_GAIN(30), { 0x000001ca, 0x0000000e } }, { AR5K_RF_GAIN(31), { 0x0000000a, 0x0000004e } }, { AR5K_RF_GAIN(32), { 0x0000004a, 0x0000008e } }, { AR5K_RF_GAIN(33), { 0x0000008a, 0x0000015e } }, { AR5K_RF_GAIN(34), { 0x000001ba, 0x0000019e } }, { AR5K_RF_GAIN(35), { 0x000001fa, 0x000001de } }, { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000009 } }, { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000049 } }, { AR5K_RF_GAIN(38), { 0x00000186, 0x00000089 } }, { AR5K_RF_GAIN(39), { 0x000001c6, 0x00000179 } }, { AR5K_RF_GAIN(40), { 0x00000006, 0x000001b9 } }, { AR5K_RF_GAIN(41), { 0x00000046, 0x000001f9 } }, { AR5K_RF_GAIN(42), { 0x00000086, 0x00000039 } }, { AR5K_RF_GAIN(43), { 0x000000c6, 0x00000079 } }, { AR5K_RF_GAIN(44), { 0x000000c6, 0x000000b9 } }, { AR5K_RF_GAIN(45), { 0x000000c6, 0x000001bd } }, { AR5K_RF_GAIN(46), { 0x000000c6, 0x000001fd } }, { AR5K_RF_GAIN(47), { 0x000000c6, 0x0000003d } }, { AR5K_RF_GAIN(48), { 0x000000c6, 0x0000007d } }, { AR5K_RF_GAIN(49), { 0x000000c6, 0x000000bd } }, { AR5K_RF_GAIN(50), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(51), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(52), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(53), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(54), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(55), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(56), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(57), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(58), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(59), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(60), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(61), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(62), { 0x000000c6, 0x000000fd } }, { AR5K_RF_GAIN(63), { 0x000000c6, 0x000000fd } }, }; /* Initial RF Gain settings for RF5112 */ static const struct ath5k_ini_rfgain rfgain_5112[] = { /* 5Ghz 2Ghz */ { AR5K_RF_GAIN(0), { 0x00000007, 0x00000007 } }, { AR5K_RF_GAIN(1), { 0x00000047, 0x00000047 } }, { AR5K_RF_GAIN(2), { 0x00000087, 0x00000087 } }, { AR5K_RF_GAIN(3), { 0x000001a0, 0x000001a0 } }, { AR5K_RF_GAIN(4), { 0x000001e0, 0x000001e0 } }, { AR5K_RF_GAIN(5), { 0x00000020, 0x00000020 } }, { AR5K_RF_GAIN(6), { 0x00000060, 0x00000060 } }, { AR5K_RF_GAIN(7), { 0x000001a1, 0x000001a1 } }, { AR5K_RF_GAIN(8), { 0x000001e1, 0x000001e1 } }, { AR5K_RF_GAIN(9), { 0x00000021, 0x00000021 } }, { AR5K_RF_GAIN(10), { 0x00000061, 0x00000061 } }, { AR5K_RF_GAIN(11), { 0x00000162, 0x00000162 } }, { AR5K_RF_GAIN(12), { 0x000001a2, 0x000001a2 } }, { AR5K_RF_GAIN(13), { 0x000001e2, 0x000001e2 } }, { AR5K_RF_GAIN(14), { 0x00000022, 0x00000022 } }, { AR5K_RF_GAIN(15), { 0x00000062, 0x00000062 } }, { AR5K_RF_GAIN(16), { 0x00000163, 0x00000163 } }, { AR5K_RF_GAIN(17), { 0x000001a3, 0x000001a3 } }, { AR5K_RF_GAIN(18), { 0x000001e3, 0x000001e3 } }, { AR5K_RF_GAIN(19), { 0x00000023, 0x00000023 } }, { AR5K_RF_GAIN(20), { 0x00000063, 0x00000063 } }, { AR5K_RF_GAIN(21), { 0x00000184, 0x00000184 } }, { AR5K_RF_GAIN(22), { 0x000001c4, 0x000001c4 } }, { AR5K_RF_GAIN(23), { 0x00000004, 0x00000004 } }, { AR5K_RF_GAIN(24), { 0x000001ea, 0x0000000b } }, { AR5K_RF_GAIN(25), { 0x0000002a, 0x0000004b } }, { AR5K_RF_GAIN(26), { 0x0000006a, 0x0000008b } }, { AR5K_RF_GAIN(27), { 0x000000aa, 0x000001ac } }, { AR5K_RF_GAIN(28), { 0x000001ab, 0x000001ec } }, { AR5K_RF_GAIN(29), { 0x000001eb, 0x0000002c } }, { AR5K_RF_GAIN(30), { 0x0000002b, 0x00000012 } }, { AR5K_RF_GAIN(31), { 0x0000006b, 0x00000052 } }, { AR5K_RF_GAIN(32), { 0x000000ab, 0x00000092 } }, { AR5K_RF_GAIN(33), { 0x000001ac, 0x00000193 } }, { AR5K_RF_GAIN(34), { 0x000001ec, 0x000001d3 } }, { AR5K_RF_GAIN(35), { 0x0000002c, 0x00000013 } }, { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000053 } }, { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000093 } }, { AR5K_RF_GAIN(38), { 0x000000ba, 0x00000194 } }, { AR5K_RF_GAIN(39), { 0x000001bb, 0x000001d4 } }, { AR5K_RF_GAIN(40), { 0x000001fb, 0x00000014 } }, { AR5K_RF_GAIN(41), { 0x0000003b, 0x0000003a } }, { AR5K_RF_GAIN(42), { 0x0000007b, 0x0000007a } }, { AR5K_RF_GAIN(43), { 0x000000bb, 0x000000ba } }, { AR5K_RF_GAIN(44), { 0x000001bc, 0x000001bb } }, { AR5K_RF_GAIN(45), { 0x000001fc, 0x000001fb } }, { AR5K_RF_GAIN(46), { 0x0000003c, 0x0000003b } }, { AR5K_RF_GAIN(47), { 0x0000007c, 0x0000007b } }, { AR5K_RF_GAIN(48), { 0x000000bc, 0x000000bb } }, { AR5K_RF_GAIN(49), { 0x000000fc, 0x000001bc } }, { AR5K_RF_GAIN(50), { 0x000000fc, 0x000001fc } }, { AR5K_RF_GAIN(51), { 0x000000fc, 0x0000003c } }, { AR5K_RF_GAIN(52), { 0x000000fc, 0x0000007c } }, { AR5K_RF_GAIN(53), { 0x000000fc, 0x000000bc } }, { AR5K_RF_GAIN(54), { 0x000000fc, 0x000000fc } }, { AR5K_RF_GAIN(55), { 0x000000fc, 0x000000fc } }, { AR5K_RF_GAIN(56), { 0x000000fc, 0x000000fc } }, { AR5K_RF_GAIN(57), { 0x000000fc, 0x000000fc } }, { AR5K_RF_GAIN(58), { 0x000000fc, 0x000000fc } }, { AR5K_RF_GAIN(59), { 0x000000fc, 0x000000fc } }, { AR5K_RF_GAIN(60), { 0x000000fc, 0x000000fc } }, { AR5K_RF_GAIN(61), { 0x000000fc, 0x000000fc } }, { AR5K_RF_GAIN(62), { 0x000000fc, 0x000000fc } }, { AR5K_RF_GAIN(63), { 0x000000fc, 0x000000fc } }, }; /* Initial RF Gain settings for RF2413 */ static const struct ath5k_ini_rfgain rfgain_2413[] = { { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } }, { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } }, { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } }, { AR5K_RF_GAIN(3), { 0x00000000, 0x00000181 } }, { AR5K_RF_GAIN(4), { 0x00000000, 0x000001c1 } }, { AR5K_RF_GAIN(5), { 0x00000000, 0x00000001 } }, { AR5K_RF_GAIN(6), { 0x00000000, 0x00000041 } }, { AR5K_RF_GAIN(7), { 0x00000000, 0x00000081 } }, { AR5K_RF_GAIN(8), { 0x00000000, 0x00000168 } }, { AR5K_RF_GAIN(9), { 0x00000000, 0x000001a8 } }, { AR5K_RF_GAIN(10), { 0x00000000, 0x000001e8 } }, { AR5K_RF_GAIN(11), { 0x00000000, 0x00000028 } }, { AR5K_RF_GAIN(12), { 0x00000000, 0x00000068 } }, { AR5K_RF_GAIN(13), { 0x00000000, 0x00000189 } }, { AR5K_RF_GAIN(14), { 0x00000000, 0x000001c9 } }, { AR5K_RF_GAIN(15), { 0x00000000, 0x00000009 } }, { AR5K_RF_GAIN(16), { 0x00000000, 0x00000049 } }, { AR5K_RF_GAIN(17), { 0x00000000, 0x00000089 } }, { AR5K_RF_GAIN(18), { 0x00000000, 0x00000190 } }, { AR5K_RF_GAIN(19), { 0x00000000, 0x000001d0 } }, { AR5K_RF_GAIN(20), { 0x00000000, 0x00000010 } }, { AR5K_RF_GAIN(21), { 0x00000000, 0x00000050 } }, { AR5K_RF_GAIN(22), { 0x00000000, 0x00000090 } }, { AR5K_RF_GAIN(23), { 0x00000000, 0x00000191 } }, { AR5K_RF_GAIN(24), { 0x00000000, 0x000001d1 } }, { AR5K_RF_GAIN(25), { 0x00000000, 0x00000011 } }, { AR5K_RF_GAIN(26), { 0x00000000, 0x00000051 } }, { AR5K_RF_GAIN(27), { 0x00000000, 0x00000091 } }, { AR5K_RF_GAIN(28), { 0x00000000, 0x00000178 } }, { AR5K_RF_GAIN(29), { 0x00000000, 0x000001b8 } }, { AR5K_RF_GAIN(30), { 0x00000000, 0x000001f8 } }, { AR5K_RF_GAIN(31), { 0x00000000, 0x00000038 } }, { AR5K_RF_GAIN(32), { 0x00000000, 0x00000078 } }, { AR5K_RF_GAIN(33), { 0x00000000, 0x00000199 } }, { AR5K_RF_GAIN(34), { 0x00000000, 0x000001d9 } }, { AR5K_RF_GAIN(35), { 0x00000000, 0x00000019 } }, { AR5K_RF_GAIN(36), { 0x00000000, 0x00000059 } }, { AR5K_RF_GAIN(37), { 0x00000000, 0x00000099 } }, { AR5K_RF_GAIN(38), { 0x00000000, 0x000000d9 } }, { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f9 } }, }; /* Initial RF Gain settings for AR2316 */ static const struct ath5k_ini_rfgain rfgain_2316[] = { { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } }, { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } }, { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } }, { AR5K_RF_GAIN(3), { 0x00000000, 0x000000c0 } }, { AR5K_RF_GAIN(4), { 0x00000000, 0x000000e0 } }, { AR5K_RF_GAIN(5), { 0x00000000, 0x000000e0 } }, { AR5K_RF_GAIN(6), { 0x00000000, 0x00000128 } }, { AR5K_RF_GAIN(7), { 0x00000000, 0x00000128 } }, { AR5K_RF_GAIN(8), { 0x00000000, 0x00000128 } }, { AR5K_RF_GAIN(9), { 0x00000000, 0x00000168 } }, { AR5K_RF_GAIN(10), { 0x00000000, 0x000001a8 } }, { AR5K_RF_GAIN(11), { 0x00000000, 0x000001e8 } }, { AR5K_RF_GAIN(12), { 0x00000000, 0x00000028 } }, { AR5K_RF_GAIN(13), { 0x00000000, 0x00000068 } }, { AR5K_RF_GAIN(14), { 0x00000000, 0x000000a8 } }, { AR5K_RF_GAIN(15), { 0x00000000, 0x000000e8 } }, { AR5K_RF_GAIN(16), { 0x00000000, 0x000000e8 } }, { AR5K_RF_GAIN(17), { 0x00000000, 0x00000130 } }, { AR5K_RF_GAIN(18), { 0x00000000, 0x00000130 } }, { AR5K_RF_GAIN(19), { 0x00000000, 0x00000170 } }, { AR5K_RF_GAIN(20), { 0x00000000, 0x000001b0 } }, { AR5K_RF_GAIN(21), { 0x00000000, 0x000001f0 } }, { AR5K_RF_GAIN(22), { 0x00000000, 0x00000030 } }, { AR5K_RF_GAIN(23), { 0x00000000, 0x00000070 } }, { AR5K_RF_GAIN(24), { 0x00000000, 0x000000b0 } }, { AR5K_RF_GAIN(25), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(26), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(27), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(28), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(29), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(30), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(31), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(32), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(33), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(34), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(35), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(36), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(37), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(38), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f0 } }, { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f0 } }, }; /* Initial RF Gain settings for RF5413 */ static const struct ath5k_ini_rfgain rfgain_5413[] = { /* 5Ghz 2Ghz */ { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } }, { AR5K_RF_GAIN(1), { 0x00000040, 0x00000040 } }, { AR5K_RF_GAIN(2), { 0x00000080, 0x00000080 } }, { AR5K_RF_GAIN(3), { 0x000001a1, 0x00000161 } }, { AR5K_RF_GAIN(4), { 0x000001e1, 0x000001a1 } }, { AR5K_RF_GAIN(5), { 0x00000021, 0x000001e1 } }, { AR5K_RF_GAIN(6), { 0x00000061, 0x00000021 } }, { AR5K_RF_GAIN(7), { 0x00000188, 0x00000061 } }, { AR5K_RF_GAIN(8), { 0x000001c8, 0x00000188 } }, { AR5K_RF_GAIN(9), { 0x00000008, 0x000001c8 } }, { AR5K_RF_GAIN(10), { 0x00000048, 0x00000008 } }, { AR5K_RF_GAIN(11), { 0x00000088, 0x00000048 } }, { AR5K_RF_GAIN(12), { 0x000001a9, 0x00000088 } }, { AR5K_RF_GAIN(13), { 0x000001e9, 0x00000169 } }, { AR5K_RF_GAIN(14), { 0x00000029, 0x000001a9 } }, { AR5K_RF_GAIN(15), { 0x00000069, 0x000001e9 } }, { AR5K_RF_GAIN(16), { 0x000001d0, 0x00000029 } }, { AR5K_RF_GAIN(17), { 0x00000010, 0x00000069 } }, { AR5K_RF_GAIN(18), { 0x00000050, 0x00000190 } }, { AR5K_RF_GAIN(19), { 0x00000090, 0x000001d0 } }, { AR5K_RF_GAIN(20), { 0x000001b1, 0x00000010 } }, { AR5K_RF_GAIN(21), { 0x000001f1, 0x00000050 } }, { AR5K_RF_GAIN(22), { 0x00000031, 0x00000090 } }, { AR5K_RF_GAIN(23), { 0x00000071, 0x00000171 } }, { AR5K_RF_GAIN(24), { 0x000001b8, 0x000001b1 } }, { AR5K_RF_GAIN(25), { 0x000001f8, 0x000001f1 } }, { AR5K_RF_GAIN(26), { 0x00000038, 0x00000031 } }, { AR5K_RF_GAIN(27), { 0x00000078, 0x00000071 } }, { AR5K_RF_GAIN(28), { 0x00000199, 0x00000198 } }, { AR5K_RF_GAIN(29), { 0x000001d9, 0x000001d8 } }, { AR5K_RF_GAIN(30), { 0x00000019, 0x00000018 } }, { AR5K_RF_GAIN(31), { 0x00000059, 0x00000058 } }, { AR5K_RF_GAIN(32), { 0x00000099, 0x00000098 } }, { AR5K_RF_GAIN(33), { 0x000000d9, 0x00000179 } }, { AR5K_RF_GAIN(34), { 0x000000f9, 0x000001b9 } }, { AR5K_RF_GAIN(35), { 0x000000f9, 0x000001f9 } }, { AR5K_RF_GAIN(36), { 0x000000f9, 0x00000039 } }, { AR5K_RF_GAIN(37), { 0x000000f9, 0x00000079 } }, { AR5K_RF_GAIN(38), { 0x000000f9, 0x000000b9 } }, { AR5K_RF_GAIN(39), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(40), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(41), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(42), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(43), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(44), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(45), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(46), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(47), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(48), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(49), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(50), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(51), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(52), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(53), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(54), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(55), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(56), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(57), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(58), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(59), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(60), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(61), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(62), { 0x000000f9, 0x000000f9 } }, { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } }, }; /* Initial RF Gain settings for RF2425 */ static const struct ath5k_ini_rfgain rfgain_2425[] = { { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } }, { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } }, { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } }, { AR5K_RF_GAIN(3), { 0x00000000, 0x00000181 } }, { AR5K_RF_GAIN(4), { 0x00000000, 0x000001c1 } }, { AR5K_RF_GAIN(5), { 0x00000000, 0x00000001 } }, { AR5K_RF_GAIN(6), { 0x00000000, 0x00000041 } }, { AR5K_RF_GAIN(7), { 0x00000000, 0x00000081 } }, { AR5K_RF_GAIN(8), { 0x00000000, 0x00000188 } }, { AR5K_RF_GAIN(9), { 0x00000000, 0x000001c8 } }, { AR5K_RF_GAIN(10), { 0x00000000, 0x00000008 } }, { AR5K_RF_GAIN(11), { 0x00000000, 0x00000048 } }, { AR5K_RF_GAIN(12), { 0x00000000, 0x00000088 } }, { AR5K_RF_GAIN(13), { 0x00000000, 0x00000189 } }, { AR5K_RF_GAIN(14), { 0x00000000, 0x000001c9 } }, { AR5K_RF_GAIN(15), { 0x00000000, 0x00000009 } }, { AR5K_RF_GAIN(16), { 0x00000000, 0x00000049 } }, { AR5K_RF_GAIN(17), { 0x00000000, 0x00000089 } }, { AR5K_RF_GAIN(18), { 0x00000000, 0x000001b0 } }, { AR5K_RF_GAIN(19), { 0x00000000, 0x000001f0 } }, { AR5K_RF_GAIN(20), { 0x00000000, 0x00000030 } }, { AR5K_RF_GAIN(21), { 0x00000000, 0x00000070 } }, { AR5K_RF_GAIN(22), { 0x00000000, 0x00000171 } }, { AR5K_RF_GAIN(23), { 0x00000000, 0x000001b1 } }, { AR5K_RF_GAIN(24), { 0x00000000, 0x000001f1 } }, { AR5K_RF_GAIN(25), { 0x00000000, 0x00000031 } }, { AR5K_RF_GAIN(26), { 0x00000000, 0x00000071 } }, { AR5K_RF_GAIN(27), { 0x00000000, 0x000001b8 } }, { AR5K_RF_GAIN(28), { 0x00000000, 0x000001f8 } }, { AR5K_RF_GAIN(29), { 0x00000000, 0x00000038 } }, { AR5K_RF_GAIN(30), { 0x00000000, 0x00000078 } }, { AR5K_RF_GAIN(31), { 0x00000000, 0x000000b8 } }, { AR5K_RF_GAIN(32), { 0x00000000, 0x000001b9 } }, { AR5K_RF_GAIN(33), { 0x00000000, 0x000001f9 } }, { AR5K_RF_GAIN(34), { 0x00000000, 0x00000039 } }, { AR5K_RF_GAIN(35), { 0x00000000, 0x00000079 } }, { AR5K_RF_GAIN(36), { 0x00000000, 0x000000b9 } }, { AR5K_RF_GAIN(37), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(38), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f9 } }, { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f9 } }, }; #define AR5K_GAIN_CRN_FIX_BITS_5111 4 #define AR5K_GAIN_CRN_FIX_BITS_5112 7 #define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112 #define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15 #define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20 #define AR5K_GAIN_CCK_PROBE_CORR 5 #define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15 #define AR5K_GAIN_STEP_COUNT 10 /* Check if our current measurement is inside our * current variable attenuation window */ #define AR5K_GAIN_CHECK_ADJUST(_g) \ ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high) struct ath5k_gain_opt_step { s8 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS]; s8 gos_gain; }; struct ath5k_gain_opt { u8 go_default; u8 go_steps_count; const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT]; }; /* * Parameters on gos_param: * 1) Tx clip PHY register * 2) PWD 90 RF register * 3) PWD 84 RF register * 4) RFGainSel RF register */ static const struct ath5k_gain_opt rfgain_opt_5111 = { 4, 9, { { { 4, 1, 1, 1 }, 6 }, { { 4, 0, 1, 1 }, 4 }, { { 3, 1, 1, 1 }, 3 }, { { 4, 0, 0, 1 }, 1 }, { { 4, 1, 1, 0 }, 0 }, { { 4, 0, 1, 0 }, -2 }, { { 3, 1, 1, 0 }, -3 }, { { 4, 0, 0, 0 }, -4 }, { { 2, 1, 1, 0 }, -6 } } }; /* * Parameters on gos_param: * 1) Mixgain ovr RF register * 2) PWD 138 RF register * 3) PWD 137 RF register * 4) PWD 136 RF register * 5) PWD 132 RF register * 6) PWD 131 RF register * 7) PWD 130 RF register */ static const struct ath5k_gain_opt rfgain_opt_5112 = { 1, 8, { { { 3, 0, 0, 0, 0, 0, 0 }, 6 }, { { 2, 0, 0, 0, 0, 0, 0 }, 0 }, { { 1, 0, 0, 0, 0, 0, 0 }, -3 }, { { 0, 0, 0, 0, 0, 0, 0 }, -6 }, { { 0, 1, 1, 0, 0, 0, 0 }, -8 }, { { 0, 1, 1, 0, 1, 1, 0 }, -10 }, { { 0, 1, 0, 1, 1, 1, 0 }, -13 }, { { 0, 1, 0, 1, 1, 0, 1 }, -16 }, } }; debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k_gpio.c0000664000000000000000000000545112524662415022426 0ustar /* * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2006-2008 Nick Kossifidis * * Lightly modified for gPXE, July 2009, by Joshua Oreman . * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ FILE_LICENCE ( MIT ); /****************\ GPIO Functions \****************/ #include "ath5k.h" #include "reg.h" #include "base.h" /* * Set GPIO inputs */ int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) { if (gpio >= AR5K_NUM_GPIO) return -EINVAL; ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR); return 0; } /* * Set GPIO outputs */ int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) { if (gpio >= AR5K_NUM_GPIO) return -EINVAL; ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR); return 0; } /* * Get GPIO state */ u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) { if (gpio >= AR5K_NUM_GPIO) return 0xffffffff; /* GPIO input magic */ return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) & 0x1; } /* * Set GPIO state */ int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val) { u32 data; if (gpio >= AR5K_NUM_GPIO) return -EINVAL; /* GPIO output magic */ data = ath5k_hw_reg_read(ah, AR5K_GPIODO); data &= ~(1 << gpio); data |= (val & 1) << gpio; ath5k_hw_reg_write(ah, data, AR5K_GPIODO); return 0; } /* * Initialize the GPIO interrupt (RFKill switch) */ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level) { u32 data; if (gpio >= AR5K_NUM_GPIO) return; /* * Set the GPIO interrupt */ data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH | AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) | (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA); ath5k_hw_reg_write(ah, interrupt_level ? data : (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR); ah->ah_imr |= AR5K_IMR_GPIO; /* Enable GPIO interrupts */ AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO); } debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k_pcu.c0000664000000000000000000003475312524662415022266 0ustar /* * Copyright (c) 2004-2008 Reyk Floeter * Copyright (c) 2006-2008 Nick Kossifidis * Copyright (c) 2007-2008 Matthew W. S. Bell * Copyright (c) 2007-2008 Luis Rodriguez * Copyright (c) 2007-2008 Pavel Roskin * Copyright (c) 2007-2008 Jiri Slaby * * Lightly modified for gPXE, July 2009, by Joshua Oreman . * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ FILE_LICENCE ( MIT ); /*********************************\ * Protocol Control Unit Functions * \*********************************/ #include "ath5k.h" #include "reg.h" #include "base.h" /*******************\ * Generic functions * \*******************/ /** * ath5k_hw_set_opmode - Set PCU operating mode * * @ah: The &struct ath5k_hw * * Initialize PCU for the various operating modes (AP/STA etc) * * For gPXE we always assume STA mode. */ int ath5k_hw_set_opmode(struct ath5k_hw *ah) { u32 pcu_reg, beacon_reg, low_id, high_id; /* Preserve rest settings */ pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE | (ah->ah_version == AR5K_AR5210 ? (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0)); beacon_reg = 0; pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE | (ah->ah_version == AR5K_AR5210 ? AR5K_STA_ID1_PWR_SV : 0); /* * Set PCU registers */ low_id = AR5K_LOW_ID(ah->ah_sta_id); high_id = AR5K_HIGH_ID(ah->ah_sta_id); ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); /* * Set Beacon Control Register on 5210 */ if (ah->ah_version == AR5K_AR5210) ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR); return 0; } /** * ath5k_hw_set_ack_bitrate - set bitrate for ACKs * * @ah: The &struct ath5k_hw * @high: Flag to determine if we want to use high transmition rate * for ACKs or not * * If high flag is set, we tell hw to use a set of control rates based on * the current transmition rate (check out control_rates array inside reset.c). * If not hw just uses the lowest rate available for the current modulation * scheme being used (1Mbit for CCK and 6Mbits for OFDM). */ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, int high) { if (ah->ah_version != AR5K_AR5212) return; else { u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; if (high) AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val); else AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val); } } /******************\ * ACK/CTS Timeouts * \******************/ /** * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec * * @ah: The &struct ath5k_hw */ unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah) { return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo); } /** * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU * * @ah: The &struct ath5k_hw * @timeout: Timeout in usec */ int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) { if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK), ah->ah_turbo) <= timeout) return -EINVAL; AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, ath5k_hw_htoclock(timeout, ah->ah_turbo)); return 0; } /** * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec * * @ah: The &struct ath5k_hw */ unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah) { return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo); } /** * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU * * @ah: The &struct ath5k_hw * @timeout: Timeout in usec */ int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) { if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS), ah->ah_turbo) <= timeout) return -EINVAL; AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, ath5k_hw_htoclock(timeout, ah->ah_turbo)); return 0; } /****************\ * BSSID handling * \****************/ /** * ath5k_hw_get_lladdr - Get station id * * @ah: The &struct ath5k_hw * @mac: The card's mac address * * Initialize ah->ah_sta_id using the mac address provided * (just a memcpy). * * TODO: Remove it once we merge ath5k_softc and ath5k_hw */ void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac) { memcpy(mac, ah->ah_sta_id, ETH_ALEN); } /** * ath5k_hw_set_lladdr - Set station id * * @ah: The &struct ath5k_hw * @mac: The card's mac address * * Set station id on hw using the provided mac address */ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) { u32 low_id, high_id; u32 pcu_reg; /* Set new station ID */ memcpy(ah->ah_sta_id, mac, ETH_ALEN); pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; low_id = AR5K_LOW_ID(mac); high_id = AR5K_HIGH_ID(mac); ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); return 0; } /** * ath5k_hw_set_associd - Set BSSID for association * * @ah: The &struct ath5k_hw * @bssid: BSSID * @assoc_id: Assoc id * * Sets the BSSID which trigers the "SME Join" operation */ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id) { u32 low_id, high_id; /* * Set simple BSSID mask on 5212 */ if (ah->ah_version == AR5K_AR5212) { ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_bssid_mask), AR5K_BSS_IDM0); ath5k_hw_reg_write(ah, AR5K_HIGH_ID(ah->ah_bssid_mask), AR5K_BSS_IDM1); } /* * Set BSSID which triggers the "SME Join" operation */ low_id = AR5K_LOW_ID(bssid); high_id = AR5K_HIGH_ID(bssid); ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0); ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) << AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1); } /** * ath5k_hw_set_bssid_mask - filter out bssids we listen * * @ah: the &struct ath5k_hw * @mask: the bssid_mask, a u8 array of size ETH_ALEN * * BSSID masking is a method used by AR5212 and newer hardware to inform PCU * which bits of the interface's MAC address should be looked at when trying * to decide which packets to ACK. In station mode and AP mode with a single * BSS every bit matters since we lock to only one BSS. In AP mode with * multiple BSSes (virtual interfaces) not every bit matters because hw must * accept frames for all BSSes and so we tweak some bits of our mac address * in order to have multiple BSSes. * * NOTE: This is a simple filter and does *not* filter out all * relevant frames. Some frames that are not for us might get ACKed from us * by PCU because they just match the mask. * * When handling multiple BSSes you can get the BSSID mask by computing the * set of ~ ( MAC XOR BSSID ) for all bssids we handle. * * When you do this you are essentially computing the common bits of all your * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with * the MAC address to obtain the relevant bits and compare the result with * (frame's BSSID & mask) to see if they match. */ /* * Simple example: on your card you have have two BSSes you have created with * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address. * There is another BSSID-03 but you are not part of it. For simplicity's sake, * assuming only 4 bits for a mac address and for BSSIDs you can then have: * * \ * MAC: 0001 | * BSSID-01: 0100 | --> Belongs to us * BSSID-02: 1001 | * / * ------------------- * BSSID-03: 0110 | --> External * ------------------- * * Our bssid_mask would then be: * * On loop iteration for BSSID-01: * ~(0001 ^ 0100) -> ~(0101) * -> 1010 * bssid_mask = 1010 * * On loop iteration for BSSID-02: * bssid_mask &= ~(0001 ^ 1001) * bssid_mask = (1010) & ~(0001 ^ 1001) * bssid_mask = (1010) & ~(1001) * bssid_mask = (1010) & (0110) * bssid_mask = 0010 * * A bssid_mask of 0010 means "only pay attention to the second least * significant bit". This is because its the only bit common * amongst the MAC and all BSSIDs we support. To findout what the real * common bit is we can simply "&" the bssid_mask now with any BSSID we have * or our MAC address (we assume the hardware uses the MAC address). * * Now, suppose there's an incoming frame for BSSID-03: * * IFRAME-01: 0110 * * An easy eye-inspeciton of this already should tell you that this frame * will not pass our check. This is beacuse the bssid_mask tells the * hardware to only look at the second least significant bit and the * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB * as 1, which does not match 0. * * So with IFRAME-01 we *assume* the hardware will do: * * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0; * --> allow = (0010) == 0000 ? 1 : 0; * --> allow = 0 * * Lets now test a frame that should work: * * IFRAME-02: 0001 (we should allow) * * allow = (0001 & 1010) == 1010 * * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0; * --> allow = (0010) == (0010) * --> allow = 1 * * Other examples: * * IFRAME-03: 0100 --> allowed * IFRAME-04: 1001 --> allowed * IFRAME-05: 1101 --> allowed but its not for us!!! * */ int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask) { u32 low_id, high_id; /* Cache bssid mask so that we can restore it * on reset */ memcpy(ah->ah_bssid_mask, mask, ETH_ALEN); if (ah->ah_version == AR5K_AR5212) { low_id = AR5K_LOW_ID(mask); high_id = AR5K_HIGH_ID(mask); ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0); ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1); return 0; } return -EIO; } /************\ * RX Control * \************/ /** * ath5k_hw_start_rx_pcu - Start RX engine * * @ah: The &struct ath5k_hw * * Starts RX engine on PCU so that hw can process RXed frames * (ACK etc). * * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma * TODO: Init ANI here */ void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) { AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); } /** * at5k_hw_stop_rx_pcu - Stop RX engine * * @ah: The &struct ath5k_hw * * Stops RX engine on PCU * * TODO: Detach ANI here */ void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah) { AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); } /* * Set multicast filter */ void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1) { /* Set the multicat filter */ ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0); ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); } /** * ath5k_hw_get_rx_filter - Get current rx filter * * @ah: The &struct ath5k_hw * * Returns the RX filter by reading rx filter and * phy error filter registers. RX filter is used * to set the allowed frame types that PCU will accept * and pass to the driver. For a list of frame types * check out reg.h. */ u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah) { u32 data, filter = 0; filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER); /*Radar detection for 5212*/ if (ah->ah_version == AR5K_AR5212) { data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL); if (data & AR5K_PHY_ERR_FIL_RADAR) filter |= AR5K_RX_FILTER_RADARERR; if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK)) filter |= AR5K_RX_FILTER_PHYERR; } return filter; } /** * ath5k_hw_set_rx_filter - Set rx filter * * @ah: The &struct ath5k_hw * @filter: RX filter mask (see reg.h) * * Sets RX filter register and also handles PHY error filter * register on 5212 and newer chips so that we have proper PHY * error reporting. */ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter) { u32 data = 0; /* Set PHY error filter register on 5212*/ if (ah->ah_version == AR5K_AR5212) { if (filter & AR5K_RX_FILTER_RADARERR) data |= AR5K_PHY_ERR_FIL_RADAR; if (filter & AR5K_RX_FILTER_PHYERR) data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK; } /* * The AR5210 uses promiscous mode to detect radar activity */ if (ah->ah_version == AR5K_AR5210 && (filter & AR5K_RX_FILTER_RADARERR)) { filter &= ~AR5K_RX_FILTER_RADARERR; filter |= AR5K_RX_FILTER_PROM; } /*Zero length DMA (phy error reporting) */ if (data) AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA); else AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA); /*Write RX Filter register*/ ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER); /*Write PHY error filter register on 5212*/ if (ah->ah_version == AR5K_AR5212) ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL); } /*********************\ * Key table functions * \*********************/ /* * Reset a key entry on the table */ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) { unsigned int i, type; u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry)); for (i = 0; i < AR5K_KEYCACHE_SIZE; i++) ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i)); /* Reset associated MIC entry if TKIP * is enabled located at offset (entry + 64) */ if (type == AR5K_KEYTABLE_TYPE_TKIP) { for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++) ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(micentry, i)); } /* * Set NULL encryption on AR5212+ * * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5) * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007 * * Note2: Windows driver (ndiswrapper) sets this to * 0x00000714 instead of 0x00000007 */ if (ah->ah_version > AR5K_AR5211) { ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, AR5K_KEYTABLE_TYPE(entry)); if (type == AR5K_KEYTABLE_TYPE_TKIP) { ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, AR5K_KEYTABLE_TYPE(micentry)); } } return 0; } debian/grub-extras/disabled/gpxe/src/drivers/net/ath5k/ath5k.h0000664000000000000000000012127712524662415021422 0ustar /* * Copyright (c) 2004-2007 Reyk Floeter * Copyright (c) 2006-2007 Nick Kossifidis * * Modified for gPXE, July 2009, by Joshua Oreman * Original from Linux kernel 2.6.30. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _ATH5K_H #define _ATH5K_H FILE_LICENCE ( MIT ); #include #include #include #include #include #include /* Keep all ath5k files under one errfile ID */ #undef ERRFILE #define ERRFILE ERRFILE_ath5k #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) /* RX/TX descriptor hw structs */ #include "desc.h" /* EEPROM structs/offsets */ #include "eeprom.h" /* PCI IDs */ #define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ #define PCI_DEVICE_ID_ATHEROS_AR5311 0x0011 /* AR5311 */ #define PCI_DEVICE_ID_ATHEROS_AR5211 0x0012 /* AR5211 */ #define PCI_DEVICE_ID_ATHEROS_AR5212 0x0013 /* AR5212 */ #define PCI_DEVICE_ID_3COM_3CRDAG675 0x0013 /* 3CRDAG675 (Atheros AR5212) */ #define PCI_DEVICE_ID_3COM_2_3CRPAG175 0x0013 /* 3CRPAG175 (Atheros AR5212) */ #define PCI_DEVICE_ID_ATHEROS_AR5210_AP 0x0207 /* AR5210 (Early) */ #define PCI_DEVICE_ID_ATHEROS_AR5212_IBM 0x1014 /* AR5212 (IBM MiniPCI) */ #define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT 0x1107 /* AR5210 (no eeprom) */ #define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT 0x1113 /* AR5212 (no eeprom) */ #define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT 0x1112 /* AR5211 (no eeprom) */ #define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA 0xf013 /* AR5212 (emulation board) */ #define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY 0xff12 /* AR5211 (emulation board) */ #define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B 0xf11b /* AR5211 (emulation board) */ #define PCI_DEVICE_ID_ATHEROS_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ #define PCI_DEVICE_ID_ATHEROS_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ #define PCI_DEVICE_ID_ATHEROS_AR5312_REV8 0x0058 /* AR5312 WMAC (AP43-030) */ #define PCI_DEVICE_ID_ATHEROS_AR5212_0014 0x0014 /* AR5212 compatible */ #define PCI_DEVICE_ID_ATHEROS_AR5212_0015 0x0015 /* AR5212 compatible */ #define PCI_DEVICE_ID_ATHEROS_AR5212_0016 0x0016 /* AR5212 compatible */ #define PCI_DEVICE_ID_ATHEROS_AR5212_0017 0x0017 /* AR5212 compatible */ #define PCI_DEVICE_ID_ATHEROS_AR5212_0018 0x0018 /* AR5212 compatible */ #define PCI_DEVICE_ID_ATHEROS_AR5212_0019 0x0019 /* AR5212 compatible */ #define PCI_DEVICE_ID_ATHEROS_AR2413 0x001a /* AR2413 (Griffin-lite) */ #define PCI_DEVICE_ID_ATHEROS_AR5413 0x001b /* AR5413 (Eagle) */ #define PCI_DEVICE_ID_ATHEROS_AR5424 0x001c /* AR5424 (Condor PCI-E) */ #define PCI_DEVICE_ID_ATHEROS_AR5416 0x0023 /* AR5416 */ #define PCI_DEVICE_ID_ATHEROS_AR5418 0x0024 /* AR5418 */ /****************************\ GENERIC DRIVER DEFINITIONS \****************************/ /* * AR5K REGISTER ACCESS */ /* Some macros to read/write fields */ /* First shift, then mask */ #define AR5K_REG_SM(_val, _flags) \ (((_val) << _flags##_S) & (_flags)) /* First mask, then shift */ #define AR5K_REG_MS(_val, _flags) \ (((_val) & (_flags)) >> _flags##_S) /* Some registers can hold multiple values of interest. For this * reason when we want to write to these registers we must first * retrieve the values which we do not want to clear (lets call this * old_data) and then set the register with this and our new_value: * ( old_data | new_value) */ #define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val) \ ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & ~(_flags)) | \ (((_val) << _flags##_S) & (_flags)), _reg) #define AR5K_REG_MASKED_BITS(ah, _reg, _flags, _mask) \ ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & \ (_mask)) | (_flags), _reg) #define AR5K_REG_ENABLE_BITS(ah, _reg, _flags) \ ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) | (_flags), _reg) #define AR5K_REG_DISABLE_BITS(ah, _reg, _flags) \ ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg) /* Access to PHY registers */ #define AR5K_PHY_READ(ah, _reg) \ ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2)) #define AR5K_PHY_WRITE(ah, _reg, _val) \ ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2)) /* Access QCU registers per queue */ #define AR5K_REG_READ_Q(ah, _reg, _queue) \ (ath5k_hw_reg_read(ah, _reg) & (1 << _queue)) \ #define AR5K_REG_WRITE_Q(ah, _reg, _queue) \ ath5k_hw_reg_write(ah, (1 << _queue), _reg) #define AR5K_Q_ENABLE_BITS(_reg, _queue) do { \ _reg |= 1 << _queue; \ } while (0) #define AR5K_Q_DISABLE_BITS(_reg, _queue) do { \ _reg &= ~(1 << _queue); \ } while (0) /* Used while writing initvals */ #define AR5K_REG_WAIT(_i) do { \ if (_i % 64) \ udelay(1); \ } while (0) /* Register dumps are done per operation mode */ #define AR5K_INI_RFGAIN_5GHZ 0 #define AR5K_INI_RFGAIN_2GHZ 1 /* TODO: Clean this up */ #define AR5K_INI_VAL_11A 0 #define AR5K_INI_VAL_11A_TURBO 1 #define AR5K_INI_VAL_11B 2 #define AR5K_INI_VAL_11G 3 #define AR5K_INI_VAL_11G_TURBO 4 #define AR5K_INI_VAL_XR 0 #define AR5K_INI_VAL_MAX 5 /* Used for BSSID etc manipulation */ #define AR5K_LOW_ID(_a)( \ (_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \ ) #define AR5K_HIGH_ID(_a) ((_a)[4] | (_a)[5] << 8) #define IEEE80211_MAX_LEN 2352 /* * Some tuneable values (these should be changeable by the user) */ #define AR5K_TUNE_DMA_BEACON_RESP 2 #define AR5K_TUNE_SW_BEACON_RESP 10 #define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0 #define AR5K_TUNE_RADAR_ALERT 0 #define AR5K_TUNE_MIN_TX_FIFO_THRES 1 #define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_LEN / 64) + 1) #define AR5K_TUNE_REGISTER_TIMEOUT 20000 /* Register for RSSI threshold has a mask of 0xff, so 255 seems to * be the max value. */ #define AR5K_TUNE_RSSI_THRES 129 /* This must be set when setting the RSSI threshold otherwise it can * prevent a reset. If AR5K_RSSI_THR is read after writing to it * the BMISS_THRES will be seen as 0, seems harware doesn't keep * track of it. Max value depends on harware. For AR5210 this is just 7. * For AR5211+ this seems to be up to 255. */ #define AR5K_TUNE_BMISS_THRES 7 #define AR5K_TUNE_REGISTER_DWELL_TIME 20000 #define AR5K_TUNE_BEACON_INTERVAL 100 #define AR5K_TUNE_AIFS 2 #define AR5K_TUNE_AIFS_11B 2 #define AR5K_TUNE_AIFS_XR 0 #define AR5K_TUNE_CWMIN 15 #define AR5K_TUNE_CWMIN_11B 31 #define AR5K_TUNE_CWMIN_XR 3 #define AR5K_TUNE_CWMAX 1023 #define AR5K_TUNE_CWMAX_11B 1023 #define AR5K_TUNE_CWMAX_XR 7 #define AR5K_TUNE_NOISE_FLOOR -72 #define AR5K_TUNE_MAX_TXPOWER 63 #define AR5K_TUNE_DEFAULT_TXPOWER 25 #define AR5K_TUNE_TPC_TXPOWER 0 #define AR5K_TUNE_ANT_DIVERSITY 1 #define AR5K_TUNE_HWTXTRIES 4 #define AR5K_INIT_CARR_SENSE_EN 1 /*Swap RX/TX Descriptor for big endian archs*/ #if __BYTE_ORDER == __BIG_ENDIAN #define AR5K_INIT_CFG ( \ AR5K_CFG_SWTD | AR5K_CFG_SWRD \ ) #else #define AR5K_INIT_CFG 0x00000000 #endif /* Initial values */ #define AR5K_INIT_CYCRSSI_THR1 2 #define AR5K_INIT_TX_LATENCY 502 #define AR5K_INIT_USEC 39 #define AR5K_INIT_USEC_TURBO 79 #define AR5K_INIT_USEC_32 31 #define AR5K_INIT_SLOT_TIME 396 #define AR5K_INIT_SLOT_TIME_TURBO 480 #define AR5K_INIT_ACK_CTS_TIMEOUT 1024 #define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800 #define AR5K_INIT_PROG_IFS 920 #define AR5K_INIT_PROG_IFS_TURBO 960 #define AR5K_INIT_EIFS 3440 #define AR5K_INIT_EIFS_TURBO 6880 #define AR5K_INIT_SIFS 560 #define AR5K_INIT_SIFS_TURBO 480 #define AR5K_INIT_SH_RETRY 10 #define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY #define AR5K_INIT_SSH_RETRY 32 #define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY #define AR5K_INIT_TX_RETRY 10 #define AR5K_INIT_TRANSMIT_LATENCY ( \ (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \ (AR5K_INIT_USEC) \ ) #define AR5K_INIT_TRANSMIT_LATENCY_TURBO ( \ (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \ (AR5K_INIT_USEC_TURBO) \ ) #define AR5K_INIT_PROTO_TIME_CNTRL ( \ (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \ (AR5K_INIT_PROG_IFS) \ ) #define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \ (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \ (AR5K_INIT_PROG_IFS_TURBO) \ ) /* token to use for aifs, cwmin, cwmax in MadWiFi */ #define AR5K_TXQ_USEDEFAULT ((u32) -1) /* GENERIC CHIPSET DEFINITIONS */ /* MAC Chips */ enum ath5k_version { AR5K_AR5210 = 0, AR5K_AR5211 = 1, AR5K_AR5212 = 2, }; /* PHY Chips */ enum ath5k_radio { AR5K_RF5110 = 0, AR5K_RF5111 = 1, AR5K_RF5112 = 2, AR5K_RF2413 = 3, AR5K_RF5413 = 4, AR5K_RF2316 = 5, AR5K_RF2317 = 6, AR5K_RF2425 = 7, }; /* * Common silicon revision/version values */ enum ath5k_srev_type { AR5K_VERSION_MAC, AR5K_VERSION_RAD, }; struct ath5k_srev_name { const char *sr_name; enum ath5k_srev_type sr_type; unsigned sr_val; }; #define AR5K_SREV_UNKNOWN 0xffff #define AR5K_SREV_AR5210 0x00 /* Crete */ #define AR5K_SREV_AR5311 0x10 /* Maui 1 */ #define AR5K_SREV_AR5311A 0x20 /* Maui 2 */ #define AR5K_SREV_AR5311B 0x30 /* Spirit */ #define AR5K_SREV_AR5211 0x40 /* Oahu */ #define AR5K_SREV_AR5212 0x50 /* Venice */ #define AR5K_SREV_AR5213 0x55 /* ??? */ #define AR5K_SREV_AR5213A 0x59 /* Hainan */ #define AR5K_SREV_AR2413 0x78 /* Griffin lite */ #define AR5K_SREV_AR2414 0x70 /* Griffin */ #define AR5K_SREV_AR5424 0x90 /* Condor */ #define AR5K_SREV_AR5413 0xa4 /* Eagle lite */ #define AR5K_SREV_AR5414 0xa0 /* Eagle */ #define AR5K_SREV_AR2415 0xb0 /* Talon */ #define AR5K_SREV_AR5416 0xc0 /* PCI-E */ #define AR5K_SREV_AR5418 0xca /* PCI-E */ #define AR5K_SREV_AR2425 0xe0 /* Swan */ #define AR5K_SREV_AR2417 0xf0 /* Nala */ #define AR5K_SREV_RAD_5110 0x00 #define AR5K_SREV_RAD_5111 0x10 #define AR5K_SREV_RAD_5111A 0x15 #define AR5K_SREV_RAD_2111 0x20 #define AR5K_SREV_RAD_5112 0x30 #define AR5K_SREV_RAD_5112A 0x35 #define AR5K_SREV_RAD_5112B 0x36 #define AR5K_SREV_RAD_2112 0x40 #define AR5K_SREV_RAD_2112A 0x45 #define AR5K_SREV_RAD_2112B 0x46 #define AR5K_SREV_RAD_2413 0x50 #define AR5K_SREV_RAD_5413 0x60 #define AR5K_SREV_RAD_2316 0x70 /* Cobra SoC */ #define AR5K_SREV_RAD_2317 0x80 #define AR5K_SREV_RAD_5424 0xa0 /* Mostly same as 5413 */ #define AR5K_SREV_RAD_2425 0xa2 #define AR5K_SREV_RAD_5133 0xc0 #define AR5K_SREV_PHY_5211 0x30 #define AR5K_SREV_PHY_5212 0x41 #define AR5K_SREV_PHY_5212A 0x42 #define AR5K_SREV_PHY_5212B 0x43 #define AR5K_SREV_PHY_2413 0x45 #define AR5K_SREV_PHY_5413 0x61 #define AR5K_SREV_PHY_2425 0x70 /* * Some of this information is based on Documentation from: * * http://madwifi.org/wiki/ChipsetFeatures/SuperAG * * Modulation for Atheros' eXtended Range - range enhancing extension that is * supposed to double the distance an Atheros client device can keep a * connection with an Atheros access point. This is achieved by increasing * the receiver sensitivity up to, -105dBm, which is about 20dB above what * the 802.11 specifications demand. In addition, new (proprietary) data rates * are introduced: 3, 2, 1, 0.5 and 0.25 MBit/s. * * Please note that can you either use XR or TURBO but you cannot use both, * they are exclusive. * */ #define MODULATION_XR 0x00000200 /* * Modulation for Atheros' Turbo G and Turbo A, its supposed to provide a * throughput transmission speed up to 40Mbit/s-60Mbit/s at a 108Mbit/s * signaling rate achieved through the bonding of two 54Mbit/s 802.11g * channels. To use this feature your Access Point must also suport it. * There is also a distinction between "static" and "dynamic" turbo modes: * * - Static: is the dumb version: devices set to this mode stick to it until * the mode is turned off. * - Dynamic: is the intelligent version, the network decides itself if it * is ok to use turbo. As soon as traffic is detected on adjacent channels * (which would get used in turbo mode), or when a non-turbo station joins * the network, turbo mode won't be used until the situation changes again. * Dynamic mode is achieved by Atheros' Adaptive Radio (AR) feature which * monitors the used radio band in order to decide whether turbo mode may * be used or not. * * This article claims Super G sticks to bonding of channels 5 and 6 for * USA: * * http://www.pcworld.com/article/id,113428-page,1/article.html * * The channel bonding seems to be driver specific though. In addition to * deciding what channels will be used, these "Turbo" modes are accomplished * by also enabling the following features: * * - Bursting: allows multiple frames to be sent at once, rather than pausing * after each frame. Bursting is a standards-compliant feature that can be * used with any Access Point. * - Fast frames: increases the amount of information that can be sent per * frame, also resulting in a reduction of transmission overhead. It is a * proprietary feature that needs to be supported by the Access Point. * - Compression: data frames are compressed in real time using a Lempel Ziv * algorithm. This is done transparently. Once this feature is enabled, * compression and decompression takes place inside the chipset, without * putting additional load on the host CPU. * */ #define MODULATION_TURBO 0x00000080 enum ath5k_driver_mode { AR5K_MODE_11A = 0, AR5K_MODE_11A_TURBO = 1, AR5K_MODE_11B = 2, AR5K_MODE_11G = 3, AR5K_MODE_11G_TURBO = 4, AR5K_MODE_XR = 5, }; enum { AR5K_MODE_BIT_11A = (1 << AR5K_MODE_11A), AR5K_MODE_BIT_11A_TURBO = (1 << AR5K_MODE_11A_TURBO), AR5K_MODE_BIT_11B = (1 << AR5K_MODE_11B), AR5K_MODE_BIT_11G = (1 << AR5K_MODE_11G), AR5K_MODE_BIT_11G_TURBO = (1 << AR5K_MODE_11G_TURBO), AR5K_MODE_BIT_XR = (1 << AR5K_MODE_XR), }; /****************\ TX DEFINITIONS \****************/ /* * TX Status descriptor */ struct ath5k_tx_status { u16 ts_seqnum; u16 ts_tstamp; u8 ts_status; u8 ts_rate[4]; u8 ts_retry[4]; u8 ts_final_idx; s8 ts_rssi; u8 ts_shortretry; u8 ts_longretry; u8 ts_virtcol; u8 ts_antenna; } __attribute__ ((packed)); #define AR5K_TXSTAT_ALTRATE 0x80 #define AR5K_TXERR_XRETRY 0x01 #define AR5K_TXERR_FILT 0x02 #define AR5K_TXERR_FIFO 0x04 /** * enum ath5k_tx_queue - Queue types used to classify tx queues. * @AR5K_TX_QUEUE_INACTIVE: q is unused -- see ath5k_hw_release_tx_queue * @AR5K_TX_QUEUE_DATA: A normal data queue * @AR5K_TX_QUEUE_XR_DATA: An XR-data queue * @AR5K_TX_QUEUE_BEACON: The beacon queue * @AR5K_TX_QUEUE_CAB: The after-beacon queue * @AR5K_TX_QUEUE_UAPSD: Unscheduled Automatic Power Save Delivery queue */ enum ath5k_tx_queue { AR5K_TX_QUEUE_INACTIVE = 0, AR5K_TX_QUEUE_DATA, AR5K_TX_QUEUE_XR_DATA, AR5K_TX_QUEUE_BEACON, AR5K_TX_QUEUE_CAB, AR5K_TX_QUEUE_UAPSD, }; /* * Queue syb-types to classify normal data queues. * These are the 4 Access Categories as defined in * WME spec. 0 is the lowest priority and 4 is the * highest. Normal data that hasn't been classified * goes to the Best Effort AC. */ enum ath5k_tx_queue_subtype { AR5K_WME_AC_BK = 0, /*Background traffic*/ AR5K_WME_AC_BE, /*Best-effort (normal) traffic)*/ AR5K_WME_AC_VI, /*Video traffic*/ AR5K_WME_AC_VO, /*Voice traffic*/ }; /* * Queue ID numbers as returned by the hw functions, each number * represents a hw queue. If hw does not support hw queues * (eg 5210) all data goes in one queue. These match * d80211 definitions (net80211/MadWiFi don't use them). */ enum ath5k_tx_queue_id { AR5K_TX_QUEUE_ID_NOQCU_DATA = 0, AR5K_TX_QUEUE_ID_NOQCU_BEACON = 1, AR5K_TX_QUEUE_ID_DATA_MIN = 0, /*IEEE80211_TX_QUEUE_DATA0*/ AR5K_TX_QUEUE_ID_DATA_MAX = 4, /*IEEE80211_TX_QUEUE_DATA4*/ AR5K_TX_QUEUE_ID_DATA_SVP = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/ AR5K_TX_QUEUE_ID_CAB = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/ AR5K_TX_QUEUE_ID_BEACON = 7, /*IEEE80211_TX_QUEUE_BEACON*/ AR5K_TX_QUEUE_ID_UAPSD = 8, AR5K_TX_QUEUE_ID_XR_DATA = 9, }; /* * Flags to set hw queue's parameters... */ #define AR5K_TXQ_FLAG_TXOKINT_ENABLE 0x0001 /* Enable TXOK interrupt */ #define AR5K_TXQ_FLAG_TXERRINT_ENABLE 0x0002 /* Enable TXERR interrupt */ #define AR5K_TXQ_FLAG_TXEOLINT_ENABLE 0x0004 /* Enable TXEOL interrupt -not used- */ #define AR5K_TXQ_FLAG_TXDESCINT_ENABLE 0x0008 /* Enable TXDESC interrupt -not used- */ #define AR5K_TXQ_FLAG_TXURNINT_ENABLE 0x0010 /* Enable TXURN interrupt */ #define AR5K_TXQ_FLAG_CBRORNINT_ENABLE 0x0020 /* Enable CBRORN interrupt */ #define AR5K_TXQ_FLAG_CBRURNINT_ENABLE 0x0040 /* Enable CBRURN interrupt */ #define AR5K_TXQ_FLAG_QTRIGINT_ENABLE 0x0080 /* Enable QTRIG interrupt */ #define AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE 0x0100 /* Enable TXNOFRM interrupt */ #define AR5K_TXQ_FLAG_BACKOFF_DISABLE 0x0200 /* Disable random post-backoff */ #define AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE 0x0300 /* Enable ready time expiry policy (?)*/ #define AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE 0x0800 /* Enable backoff while bursting */ #define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS 0x1000 /* Disable backoff while bursting */ #define AR5K_TXQ_FLAG_COMPRESSION_ENABLE 0x2000 /* Enable hw compression -not implemented-*/ /* * A struct to hold tx queue's parameters */ struct ath5k_txq_info { enum ath5k_tx_queue tqi_type; enum ath5k_tx_queue_subtype tqi_subtype; u16 tqi_flags; /* Tx queue flags (see above) */ u32 tqi_aifs; /* Arbitrated Interframe Space */ s32 tqi_cw_min; /* Minimum Contention Window */ s32 tqi_cw_max; /* Maximum Contention Window */ u32 tqi_cbr_period; /* Constant bit rate period */ u32 tqi_cbr_overflow_limit; u32 tqi_burst_time; u32 tqi_ready_time; /* Not used */ }; /* * Transmit packet types. * used on tx control descriptor * TODO: Use them inside base.c corectly */ enum ath5k_pkt_type { AR5K_PKT_TYPE_NORMAL = 0, AR5K_PKT_TYPE_ATIM = 1, AR5K_PKT_TYPE_PSPOLL = 2, AR5K_PKT_TYPE_BEACON = 3, AR5K_PKT_TYPE_PROBE_RESP = 4, AR5K_PKT_TYPE_PIFS = 5, }; /* * TX power and TPC settings */ #define AR5K_TXPOWER_OFDM(_r, _v) ( \ ((0 & 1) << ((_v) + 6)) | \ (((ah->ah_txpower.txp_rates_power_table[(_r)]) & 0x3f) << (_v)) \ ) #define AR5K_TXPOWER_CCK(_r, _v) ( \ (ah->ah_txpower.txp_rates_power_table[(_r)] & 0x3f) << (_v) \ ) /* * DMA size definitions (2^n+2) */ enum ath5k_dmasize { AR5K_DMASIZE_4B = 0, AR5K_DMASIZE_8B, AR5K_DMASIZE_16B, AR5K_DMASIZE_32B, AR5K_DMASIZE_64B, AR5K_DMASIZE_128B, AR5K_DMASIZE_256B, AR5K_DMASIZE_512B }; /****************\ RX DEFINITIONS \****************/ /* * RX Status descriptor */ struct ath5k_rx_status { u16 rs_datalen; u16 rs_tstamp; u8 rs_status; u8 rs_phyerr; s8 rs_rssi; u8 rs_keyix; u8 rs_rate; u8 rs_antenna; u8 rs_more; }; #define AR5K_RXERR_CRC 0x01 #define AR5K_RXERR_PHY 0x02 #define AR5K_RXERR_FIFO 0x04 #define AR5K_RXERR_DECRYPT 0x08 #define AR5K_RXERR_MIC 0x10 #define AR5K_RXKEYIX_INVALID ((u8) - 1) #define AR5K_TXKEYIX_INVALID ((u32) - 1) /* * TSF to TU conversion: * * TSF is a 64bit value in usec (microseconds). * TU is a 32bit value and defined by IEEE802.11 (page 6) as "A measurement of * time equal to 1024 usec", so it's roughly milliseconds (usec / 1024). */ #define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10) /*******************************\ GAIN OPTIMIZATION DEFINITIONS \*******************************/ enum ath5k_rfgain { AR5K_RFGAIN_INACTIVE = 0, AR5K_RFGAIN_ACTIVE, AR5K_RFGAIN_READ_REQUESTED, AR5K_RFGAIN_NEED_CHANGE, }; struct ath5k_gain { u8 g_step_idx; u8 g_current; u8 g_target; u8 g_low; u8 g_high; u8 g_f_corr; u8 g_state; }; /********************\ COMMON DEFINITIONS \********************/ #define AR5K_SLOT_TIME_9 396 #define AR5K_SLOT_TIME_20 880 #define AR5K_SLOT_TIME_MAX 0xffff /* channel_flags */ #define CHANNEL_CW_INT 0x0008 /* Contention Window interference detected */ #define CHANNEL_TURBO 0x0010 /* Turbo Channel */ #define CHANNEL_CCK 0x0020 /* CCK channel */ #define CHANNEL_OFDM 0x0040 /* OFDM channel */ #define CHANNEL_2GHZ 0x0080 /* 2GHz channel. */ #define CHANNEL_5GHZ 0x0100 /* 5GHz channel */ #define CHANNEL_PASSIVE 0x0200 /* Only passive scan allowed */ #define CHANNEL_DYN 0x0400 /* Dynamic CCK-OFDM channel (for g operation) */ #define CHANNEL_XR 0x0800 /* XR channel */ #define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM) #define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK) #define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM) #define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO) #define CHANNEL_TG (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO) #define CHANNEL_108A CHANNEL_T #define CHANNEL_108G CHANNEL_TG #define CHANNEL_X (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR) #define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ| \ CHANNEL_TURBO) #define CHANNEL_ALL_NOTURBO (CHANNEL_ALL & ~CHANNEL_TURBO) #define CHANNEL_MODES CHANNEL_ALL /* * Used internaly for reset_tx_queue). * Also see struct struct net80211_channel. */ #define IS_CHAN_XR(_c) ((_c->hw_value & CHANNEL_XR) != 0) #define IS_CHAN_B(_c) ((_c->hw_value & CHANNEL_B) != 0) /* * The following structure is used to map 2GHz channels to * 5GHz Atheros channels. * TODO: Clean up */ struct ath5k_athchan_2ghz { u32 a2_flags; u16 a2_athchan; }; /******************\ RATE DEFINITIONS \******************/ /** * Seems the ar5xxx harware supports up to 32 rates, indexed by 1-32. * * The rate code is used to get the RX rate or set the TX rate on the * hardware descriptors. It is also used for internal modulation control * and settings. * * This is the hardware rate map we are aware of: * * rate_code 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 * rate_kbps 3000 1000 ? ? ? 2000 500 48000 * * rate_code 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 * rate_kbps 24000 12000 6000 54000 36000 18000 9000 ? * * rate_code 17 18 19 20 21 22 23 24 * rate_kbps ? ? ? ? ? ? ? 11000 * * rate_code 25 26 27 28 29 30 31 32 * rate_kbps 5500 2000 1000 11000S 5500S 2000S ? ? * * "S" indicates CCK rates with short preamble. * * AR5211 has different rate codes for CCK (802.11B) rates. It only uses the * lowest 4 bits, so they are the same as below with a 0xF mask. * (0xB, 0xA, 0x9 and 0x8 for 1M, 2M, 5.5M and 11M). * We handle this in ath5k_setup_bands(). */ #define AR5K_MAX_RATES 32 /* B */ #define ATH5K_RATE_CODE_1M 0x1B #define ATH5K_RATE_CODE_2M 0x1A #define ATH5K_RATE_CODE_5_5M 0x19 #define ATH5K_RATE_CODE_11M 0x18 /* A and G */ #define ATH5K_RATE_CODE_6M 0x0B #define ATH5K_RATE_CODE_9M 0x0F #define ATH5K_RATE_CODE_12M 0x0A #define ATH5K_RATE_CODE_18M 0x0E #define ATH5K_RATE_CODE_24M 0x09 #define ATH5K_RATE_CODE_36M 0x0D #define ATH5K_RATE_CODE_48M 0x08 #define ATH5K_RATE_CODE_54M 0x0C /* XR */ #define ATH5K_RATE_CODE_XR_500K 0x07 #define ATH5K_RATE_CODE_XR_1M 0x02 #define ATH5K_RATE_CODE_XR_2M 0x06 #define ATH5K_RATE_CODE_XR_3M 0x01 /* adding this flag to rate_code enables short preamble */ #define AR5K_SET_SHORT_PREAMBLE 0x04 /* * Crypto definitions */ #define AR5K_KEYCACHE_SIZE 8 /***********************\ HW RELATED DEFINITIONS \***********************/ /* * Misc definitions */ #define AR5K_RSSI_EP_MULTIPLIER (1<<7) #define AR5K_ASSERT_ENTRY(_e, _s) do { \ if (_e >= _s) \ return 0; \ } while (0) /* * Hardware interrupt abstraction */ /** * enum ath5k_int - Hardware interrupt masks helpers * * @AR5K_INT_RX: mask to identify received frame interrupts, of type * AR5K_ISR_RXOK or AR5K_ISR_RXERR * @AR5K_INT_RXDESC: Request RX descriptor/Read RX descriptor (?) * @AR5K_INT_RXNOFRM: No frame received (?) * @AR5K_INT_RXEOL: received End Of List for VEOL (Virtual End Of List). The * Queue Control Unit (QCU) signals an EOL interrupt only if a descriptor's * LinkPtr is NULL. For more details, refer to: * http://www.freepatentsonline.com/20030225739.html * @AR5K_INT_RXORN: Indicates we got RX overrun (eg. no more descriptors). * Note that Rx overrun is not always fatal, on some chips we can continue * operation without reseting the card, that's why int_fatal is not * common for all chips. * @AR5K_INT_TX: mask to identify received frame interrupts, of type * AR5K_ISR_TXOK or AR5K_ISR_TXERR * @AR5K_INT_TXDESC: Request TX descriptor/Read TX status descriptor (?) * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold * We currently do increments on interrupt by * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2 * @AR5K_INT_MIB: Indicates the Management Information Base counters should be * checked. We should do this with ath5k_hw_update_mib_counters() but * it seems we should also then do some noise immunity work. * @AR5K_INT_RXPHY: RX PHY Error * @AR5K_INT_RXKCM: RX Key cache miss * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a * beacon that must be handled in software. The alternative is if you * have VEOL support, in that case you let the hardware deal with things. * @AR5K_INT_BMISS: If in STA mode this indicates we have stopped seeing * beacons from the AP have associated with, we should probably try to * reassociate. When in IBSS mode this might mean we have not received * any beacons from any local stations. Note that every station in an * IBSS schedules to send beacons at the Target Beacon Transmission Time * (TBTT) with a random backoff. * @AR5K_INT_BNR: Beacon Not Ready interrupt - ?? * @AR5K_INT_GPIO: GPIO interrupt is used for RF Kill, disabled for now * until properly handled * @AR5K_INT_FATAL: Fatal errors were encountered, typically caused by DMA * errors. These types of errors we can enable seem to be of type * AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR. * @AR5K_INT_GLOBAL: Used to clear and set the IER * @AR5K_INT_NOCARD: signals the card has been removed * @AR5K_INT_COMMON: common interrupts shared amogst MACs with the same * bit value * * These are mapped to take advantage of some common bits * between the MACs, to be able to set intr properties * easier. Some of them are not used yet inside hw.c. Most map * to the respective hw interrupt value as they are common amogst different * MACs. */ enum ath5k_int { AR5K_INT_RXOK = 0x00000001, AR5K_INT_RXDESC = 0x00000002, AR5K_INT_RXERR = 0x00000004, AR5K_INT_RXNOFRM = 0x00000008, AR5K_INT_RXEOL = 0x00000010, AR5K_INT_RXORN = 0x00000020, AR5K_INT_TXOK = 0x00000040, AR5K_INT_TXDESC = 0x00000080, AR5K_INT_TXERR = 0x00000100, AR5K_INT_TXNOFRM = 0x00000200, AR5K_INT_TXEOL = 0x00000400, AR5K_INT_TXURN = 0x00000800, AR5K_INT_MIB = 0x00001000, AR5K_INT_SWI = 0x00002000, AR5K_INT_RXPHY = 0x00004000, AR5K_INT_RXKCM = 0x00008000, AR5K_INT_SWBA = 0x00010000, AR5K_INT_BRSSI = 0x00020000, AR5K_INT_BMISS = 0x00040000, AR5K_INT_FATAL = 0x00080000, /* Non common */ AR5K_INT_BNR = 0x00100000, /* Non common */ AR5K_INT_TIM = 0x00200000, /* Non common */ AR5K_INT_DTIM = 0x00400000, /* Non common */ AR5K_INT_DTIM_SYNC = 0x00800000, /* Non common */ AR5K_INT_GPIO = 0x01000000, AR5K_INT_BCN_TIMEOUT = 0x02000000, /* Non common */ AR5K_INT_CAB_TIMEOUT = 0x04000000, /* Non common */ AR5K_INT_RX_DOPPLER = 0x08000000, /* Non common */ AR5K_INT_QCBRORN = 0x10000000, /* Non common */ AR5K_INT_QCBRURN = 0x20000000, /* Non common */ AR5K_INT_QTRIG = 0x40000000, /* Non common */ AR5K_INT_GLOBAL = 0x80000000, AR5K_INT_COMMON = AR5K_INT_RXOK | AR5K_INT_RXDESC | AR5K_INT_RXERR | AR5K_INT_RXNOFRM | AR5K_INT_RXEOL | AR5K_INT_RXORN | AR5K_INT_TXOK | AR5K_INT_TXDESC | AR5K_INT_TXERR | AR5K_INT_TXNOFRM | AR5K_INT_TXEOL | AR5K_INT_TXURN | AR5K_INT_MIB | AR5K_INT_SWI | AR5K_INT_RXPHY | AR5K_INT_RXKCM | AR5K_INT_SWBA | AR5K_INT_BRSSI | AR5K_INT_BMISS | AR5K_INT_GPIO | AR5K_INT_GLOBAL, AR5K_INT_NOCARD = 0xffffffff }; /* * Power management */ enum ath5k_power_mode { AR5K_PM_UNDEFINED = 0, AR5K_PM_AUTO, AR5K_PM_AWAKE, AR5K_PM_FULL_SLEEP, AR5K_PM_NETWORK_SLEEP, }; /* GPIO-controlled software LED */ #define AR5K_SOFTLED_PIN 0 #define AR5K_SOFTLED_ON 0 #define AR5K_SOFTLED_OFF 1 /* * Chipset capabilities -see ath5k_hw_get_capability- * get_capability function is not yet fully implemented * in ath5k so most of these don't work yet... * TODO: Implement these & merge with _TUNE_ stuff above */ enum ath5k_capability_type { AR5K_CAP_REG_DMN = 0, /* Used to get current reg. domain id */ AR5K_CAP_TKIP_MIC = 2, /* Can handle TKIP MIC in hardware */ AR5K_CAP_TKIP_SPLIT = 3, /* TKIP uses split keys */ AR5K_CAP_PHYCOUNTERS = 4, /* PHY error counters */ AR5K_CAP_DIVERSITY = 5, /* Supports fast diversity */ AR5K_CAP_NUM_TXQUEUES = 6, /* Used to get max number of hw txqueues */ AR5K_CAP_VEOL = 7, /* Supports virtual EOL */ AR5K_CAP_COMPRESSION = 8, /* Supports compression */ AR5K_CAP_BURST = 9, /* Supports packet bursting */ AR5K_CAP_FASTFRAME = 10, /* Supports fast frames */ AR5K_CAP_TXPOW = 11, /* Used to get global tx power limit */ AR5K_CAP_TPC = 12, /* Can do per-packet tx power control (needed for 802.11a) */ AR5K_CAP_BSSIDMASK = 13, /* Supports bssid mask */ AR5K_CAP_MCAST_KEYSRCH = 14, /* Supports multicast key search */ AR5K_CAP_TSF_ADJUST = 15, /* Supports beacon tsf adjust */ AR5K_CAP_XR = 16, /* Supports XR mode */ AR5K_CAP_WME_TKIPMIC = 17, /* Supports TKIP MIC when using WMM */ AR5K_CAP_CHAN_HALFRATE = 18, /* Supports half rate channels */ AR5K_CAP_CHAN_QUARTERRATE = 19, /* Supports quarter rate channels */ AR5K_CAP_RFSILENT = 20, /* Supports RFsilent */ }; /* XXX: we *may* move cap_range stuff to struct wiphy */ struct ath5k_capabilities { /* * Supported PHY modes * (ie. CHANNEL_A, CHANNEL_B, ...) */ u16 cap_mode; /* * Frequency range (without regulation restrictions) */ struct { u16 range_2ghz_min; u16 range_2ghz_max; u16 range_5ghz_min; u16 range_5ghz_max; } cap_range; /* * Values stored in the EEPROM (some of them...) */ struct ath5k_eeprom_info cap_eeprom; /* * Queue information */ struct { u8 q_tx_num; } cap_queues; }; /***************************************\ HARDWARE ABSTRACTION LAYER STRUCTURE \***************************************/ /* * Misc defines */ #define AR5K_MAX_GPIO 10 #define AR5K_MAX_RF_BANKS 8 /* TODO: Clean up and merge with ath5k_softc */ struct ath5k_hw { struct ath5k_softc *ah_sc; void *ah_iobase; enum ath5k_int ah_imr; int ah_ier; struct net80211_channel *ah_current_channel; int ah_turbo; int ah_calibration; int ah_running; int ah_single_chip; int ah_combined_mic; u32 ah_mac_srev; u16 ah_mac_version; u16 ah_mac_revision; u16 ah_phy_revision; u16 ah_radio_5ghz_revision; u16 ah_radio_2ghz_revision; enum ath5k_version ah_version; enum ath5k_radio ah_radio; u32 ah_phy; int ah_5ghz; int ah_2ghz; #define ah_regdomain ah_capabilities.cap_regdomain.reg_current #define ah_regdomain_hw ah_capabilities.cap_regdomain.reg_hw #define ah_modes ah_capabilities.cap_mode #define ah_ee_version ah_capabilities.cap_eeprom.ee_version u32 ah_atim_window; u32 ah_aifs; u32 ah_cw_min; u32 ah_cw_max; int ah_software_retry; u32 ah_limit_tx_retries; u32 ah_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; int ah_ant_diversity; u8 ah_sta_id[ETH_ALEN]; /* Current BSSID we are trying to assoc to / create. * This is passed by mac80211 on config_interface() and cached here for * use in resets */ u8 ah_bssid[ETH_ALEN]; u8 ah_bssid_mask[ETH_ALEN]; u32 ah_gpio[AR5K_MAX_GPIO]; int ah_gpio_npins; struct ath5k_capabilities ah_capabilities; struct ath5k_txq_info ah_txq; u32 ah_txq_status; u32 ah_txq_imr_txok; u32 ah_txq_imr_txerr; u32 ah_txq_imr_txurn; u32 ah_txq_imr_txdesc; u32 ah_txq_imr_txeol; u32 ah_txq_imr_cbrorn; u32 ah_txq_imr_cbrurn; u32 ah_txq_imr_qtrig; u32 ah_txq_imr_nofrm; u32 ah_txq_isr; u32 *ah_rf_banks; size_t ah_rf_banks_size; size_t ah_rf_regs_count; struct ath5k_gain ah_gain; u8 ah_offset[AR5K_MAX_RF_BANKS]; struct { /* Temporary tables used for interpolation */ u8 tmpL[AR5K_EEPROM_N_PD_GAINS] [AR5K_EEPROM_POWER_TABLE_SIZE]; u8 tmpR[AR5K_EEPROM_N_PD_GAINS] [AR5K_EEPROM_POWER_TABLE_SIZE]; u8 txp_pd_table[AR5K_EEPROM_POWER_TABLE_SIZE * 2]; u16 txp_rates_power_table[AR5K_MAX_RATES]; u8 txp_min_idx; int txp_tpc; /* Values in 0.25dB units */ s16 txp_min_pwr; s16 txp_max_pwr; s16 txp_offset; s16 txp_ofdm; /* Values in dB units */ s16 txp_cck_ofdm_pwr_delta; s16 txp_cck_ofdm_gainf_delta; } ah_txpower; /* noise floor from last periodic calibration */ s32 ah_noise_floor; /* * Function pointers */ int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc, u32 size, unsigned int flags); int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, struct ath5k_tx_status *); int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *, struct ath5k_rx_status *); }; /* * Prototypes */ extern int ath5k_bitrate_to_hw_rix(int bitrate); /* Attach/Detach Functions */ extern int ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version, struct ath5k_hw **ah); extern void ath5k_hw_detach(struct ath5k_hw *ah); /* LED functions */ extern int ath5k_init_leds(struct ath5k_softc *sc); extern void ath5k_led_enable(struct ath5k_softc *sc); extern void ath5k_led_off(struct ath5k_softc *sc); extern void ath5k_unregister_leds(struct ath5k_softc *sc); /* Reset Functions */ extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, int initial); extern int ath5k_hw_reset(struct ath5k_hw *ah, struct net80211_channel *channel, int change_channel); /* Power management functions */ extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, int set_chip, u16 sleep_duration); /* DMA Related Functions */ extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr); extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, int increase); /* Interrupt handling */ extern int ath5k_hw_is_intr_pending(struct ath5k_hw *ah); extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask); /* EEPROM access functions */ extern int ath5k_eeprom_init(struct ath5k_hw *ah); extern void ath5k_eeprom_detach(struct ath5k_hw *ah); extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); extern int ath5k_eeprom_is_hb63(struct ath5k_hw *ah); /* Protocol Control Unit Functions */ extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); /* BSSID Functions */ extern void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac); extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id); extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); /* Receive start/stop functions */ extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); /* RX Filter functions */ extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah); extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); /* ACK bit rate */ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, int high); /* ACK/CTS Timeouts */ extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout); extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah); extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout); extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah); /* Key table (WEP) functions */ extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); /* Queue Control Unit, DFS Control Unit Functions */ extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, const struct ath5k_txq_info *queue_info); extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, struct ath5k_txq_info *queue_info); extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah); extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah); extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah); extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); /* Hardware Descriptor Functions */ extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); /* GPIO Functions */ extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); /* Misc functions */ int ath5k_hw_set_capabilities(struct ath5k_hw *ah); extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); /* Initial register settings functions */ extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, int change_channel); /* Initialize RF */ extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct net80211_channel *channel, unsigned int mode); extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); /* PHY/RF channel functions */ extern int ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); extern int ath5k_hw_channel(struct ath5k_hw *ah, struct net80211_channel *channel); /* PHY calibration */ extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct net80211_channel *channel); extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); /* Misc PHY functions */ extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant); extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah); extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); /* TX power setup */ extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct net80211_channel *channel, u8 ee_mode, u8 txpower); extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower); /* * Functions used internaly */ /* * Translate usec to hw clock units * TODO: Half/quarter rate */ static inline unsigned int ath5k_hw_htoclock(unsigned int usec, int turbo) { return turbo ? (usec * 80) : (usec * 40); } /* * Translate hw clock units to usec * TODO: Half/quarter rate */ static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, int turbo) { return turbo ? (clock / 80) : (clock / 40); } /* * Read from a register */ static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) { return readl(ah->ah_iobase + reg); } /* * Write to a register */ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) { writel(val, ah->ah_iobase + reg); } #if defined(_ATH5K_RESET) || defined(_ATH5K_PHY) /* * Check if a register write has been completed */ static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, int is_set) { int i; u32 data; for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) { data = ath5k_hw_reg_read(ah, reg); if (is_set && (data & flag)) break; else if ((data & flag) == val) break; udelay(15); } return (i <= 0) ? -EAGAIN : 0; } /* * Convert channel frequency to channel number */ static inline int ath5k_freq_to_channel(int freq) { if (freq == 2484) return 14; if (freq < 2484) return (freq - 2407) / 5; return freq/5 - 1000; } #endif static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) { u32 retval = 0, bit, i; for (i = 0; i < bits; i++) { bit = (val >> i) & 1; retval = (retval << 1) | bit; } return retval; } #endif debian/grub-extras/disabled/gpxe/src/drivers/net/natsemi.c0000664000000000000000000004016712524662415021023 0ustar /* natsemi.c - gPXE driver for the NatSemi DP8381x series. Based on: natsemi.c: An Etherboot driver for the NatSemi DP8381x series. Copyright (C) 2001 Entity Cyber, Inc. This development of this Etherboot driver was funded by Sicom Systems: http://www.sicompos.com/ Author: Marty Connor Adapted from a Linux driver which was written by Donald Becker This software may be used and distributed according to the terms of the GNU Public License (GPL), incorporated herein by reference. Original Copyright Notice: Written/copyright 1999-2001 by Donald Becker. This software may be used and distributed according to the terms of the GNU General Public License (GPL), incorporated herein by reference. Drivers based on or derived from this code fall under the GPL and must retain the authorship, copyright and license notice. This file is not a complete program and may only be used when the entire operating system is licensed under the GPL. License for under other terms may be available. Contact the original author for details. The original author may be reached as becker@scyld.com, or at Scyld Computing Corporation 410 Severn Ave., Suite 210 Annapolis MD 21403 Support information and updates available at http://www.scyld.com/network/netsemi.html References: http://www.scyld.com/expert/100mbps.html http://www.scyld.com/expert/NWay.html Datasheet is available from: http://www.national.com/pf/DP/DP83815.html */ FILE_LICENCE ( GPL_ANY ); /* Revision History */ /* 02 Jul 2007 Udayan Kumar 1.2 ported the driver from etherboot to gPXE API. Fully rewritten,adapting the old driver. Added a circular buffer for transmit and receive. transmit routine will not wait for transmission to finish. poll routine deals with it. 13 Dec 2003 Tim Legge 1.1 Enabled Multicast Support 29 May 2001 Marty Connor 1.0 Initial Release. Tested with Netgear FA311 and FA312 boards */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "natsemi.h" /* Function Prototypes: */ static int natsemi_spi_read_bit ( struct bit_basher *, unsigned int ); static void natsemi_spi_write_bit ( struct bit_basher *,unsigned int, unsigned long ); static void natsemi_init_eeprom ( struct natsemi_private * ); static int natsemi_probe (struct pci_device *pci, const struct pci_device_id *id); static void natsemi_reset (struct net_device *netdev); static int natsemi_open (struct net_device *netdev); static int natsemi_transmit (struct net_device *netdev, struct io_buffer *iobuf); static void natsemi_poll (struct net_device *netdev); static void natsemi_close (struct net_device *netdev); static void natsemi_irq (struct net_device *netdev, int enable); static void natsemi_remove (struct pci_device *pci); /** natsemi net device operations */ static struct net_device_operations natsemi_operations = { .open = natsemi_open, .close = natsemi_close, .transmit = natsemi_transmit, .poll = natsemi_poll, .irq = natsemi_irq, }; static int natsemi_spi_read_bit ( struct bit_basher *basher, unsigned int bit_id ) { struct natsemi_private *np = container_of ( basher, struct natsemi_private, spibit.basher ); uint8_t mask = natsemi_ee_bits[bit_id]; uint8_t eereg; eereg = inb ( np->ioaddr + EE_REG ); return ( eereg & mask ); } static void natsemi_spi_write_bit ( struct bit_basher *basher, unsigned int bit_id, unsigned long data ) { struct natsemi_private *np = container_of ( basher, struct natsemi_private, spibit.basher ); uint8_t mask = natsemi_ee_bits[bit_id]; uint8_t eereg; eereg = inb ( np->ioaddr + EE_REG ); eereg &= ~mask; eereg |= ( data & mask ); outb ( eereg, np->ioaddr + EE_REG ); } static struct bit_basher_operations natsemi_basher_ops = { .read = natsemi_spi_read_bit, .write = natsemi_spi_write_bit, }; /* It looks that this portion of EEPROM can be used for * non-volatile stored options. Data sheet does not talk about this region. * Currently it is not working. But with some efforts it can. */ static struct nvo_fragment natsemi_nvo_fragments[] = { { 0x0c, 0x68 }, { 0, 0 } }; /* * Set up for EEPROM access * * @v NAT NATSEMI NIC */ static void natsemi_init_eeprom ( struct natsemi_private *np ) { /* Initialise three-wire bus */ np->spibit.basher.op = &natsemi_basher_ops; np->spibit.bus.mode = SPI_MODE_THREEWIRE; np->spibit.endianness = SPI_BIT_LITTLE_ENDIAN; init_spi_bit_basher ( &np->spibit ); /*natsemi DP 83815 only supports at93c46 */ init_at93c46 ( &np->eeprom, 16 ); np->eeprom.bus = &np->spibit.bus; np->nvo.nvs = &np->eeprom.nvs; np->nvo.fragments = natsemi_nvo_fragments; } /** * Probe PCI device * * @v pci PCI device * @v id PCI ID * @ret rc Return status code */ static int natsemi_probe (struct pci_device *pci, const struct pci_device_id *id __unused) { struct net_device *netdev; struct natsemi_private *np = NULL; uint8_t ll_addr_encoded[MAX_LL_ADDR_LEN]; uint8_t last=0,last1=0; uint8_t prev_bytes[2]; int i; int rc; /* Allocate net device */ netdev = alloc_etherdev (sizeof (*np)); if (! netdev) return -ENOMEM; netdev_init (netdev, &natsemi_operations); np = netdev->priv; pci_set_drvdata (pci, netdev); netdev->dev = &pci->dev; memset (np, 0, sizeof (*np)); np->ioaddr = pci->ioaddr; adjust_pci_device (pci); natsemi_reset (netdev); natsemi_init_eeprom ( np ); nvs_read ( &np->eeprom.nvs, EE_MAC-1, prev_bytes, 1 ); nvs_read ( &np->eeprom.nvs, EE_MAC, ll_addr_encoded, ETH_ALEN ); /* decoding the MAC address read from NVS * and save it in netdev->ll_addr */ last = prev_bytes[1] >> 7; for ( i = 0 ; i < ETH_ALEN ; i++ ) { last1 = ll_addr_encoded[i] >> 7; netdev->hw_addr[i] = ll_addr_encoded[i] << 1 | last; last = last1; } /* Mark as link up; we don't yet handle link state */ netdev_link_up ( netdev ); if ((rc = register_netdev (netdev)) != 0) goto err_register_netdev; return 0; err_register_netdev: natsemi_reset (netdev); netdev_put (netdev); return rc; } /** * Remove PCI device * * @v pci PCI device */ static void natsemi_remove (struct pci_device *pci) { struct net_device *netdev = pci_get_drvdata (pci); unregister_netdev (netdev); natsemi_reset (netdev); netdev_nullify ( netdev ); netdev_put (netdev); } /** * Reset NIC * * @v NATSEMI NIC * * Issues a hardware reset and waits for the reset to complete. */ static void natsemi_reset (struct net_device *netdev) { struct natsemi_private *np = netdev->priv; int i; u32 cfg; u32 wcsr; u32 rfcr; u16 pmatch[3]; u16 sopass[3]; natsemi_irq (netdev, 0); /* * Resetting the chip causes some registers to be lost. * Natsemi suggests NOT reloading the EEPROM while live, so instead * we save the state that would have been loaded from EEPROM * on a normal power-up (see the spec EEPROM map). */ /* CFG */ cfg = inl (np->ioaddr + ChipConfig) & CFG_RESET_SAVE; /* WCSR */ wcsr = inl (np->ioaddr + WOLCmd) & WCSR_RESET_SAVE; /* RFCR */ rfcr = readl (np->ioaddr + RxFilterAddr) & RFCR_RESET_SAVE; /* PMATCH */ for (i = 0; i < 3; i++) { outl(i*2, np->ioaddr + RxFilterAddr); pmatch[i] = inw(np->ioaddr + RxFilterData); } /* SOPAS */ for (i = 0; i < 3; i++) { outl(0xa+(i*2), np->ioaddr + RxFilterAddr); sopass[i] = inw(np->ioaddr + RxFilterData); } /* now whack the chip */ outl(ChipReset, np->ioaddr + ChipCmd); for (i=0; iioaddr + ChipCmd) & ChipReset)) break; udelay(5); } if (i == NATSEMI_HW_TIMEOUT) { DBG ("natsemi_reset: reset did not complete in %d usec.\n", i*5); } /* restore CFG */ cfg |= inl(np->ioaddr + ChipConfig) & ~CFG_RESET_SAVE; cfg &= ~(CfgExtPhy | CfgPhyDis); outl (cfg, np->ioaddr + ChipConfig); /* restore WCSR */ wcsr |= inl (np->ioaddr + WOLCmd) & ~WCSR_RESET_SAVE; outl (wcsr, np->ioaddr + WOLCmd); /* read RFCR */ rfcr |= inl (np->ioaddr + RxFilterAddr) & ~RFCR_RESET_SAVE; /* restore PMATCH */ for (i = 0; i < 3; i++) { outl (i*2, np->ioaddr + RxFilterAddr); outw (pmatch[i], np->ioaddr + RxFilterData); } for (i = 0; i < 3; i++) { outl (0xa+(i*2), np->ioaddr + RxFilterAddr); outw (sopass[i], np->ioaddr + RxFilterData); } /* restore RFCR */ outl (rfcr, np->ioaddr + RxFilterAddr); } /** * Open NIC * * @v netdev Net device * @ret rc Return status code */ static int natsemi_open (struct net_device *netdev) { struct natsemi_private *np = netdev->priv; uint32_t tx_config, rx_config; int i; /* Disable PME: * The PME bit is initialized from the EEPROM contents. * PCI cards probably have PME disabled, but motherboard * implementations may have PME set to enable WakeOnLan. * With PME set the chip will scan incoming packets but * nothing will be written to memory. */ outl (inl (np->ioaddr + ClkRun) & ~0x100, np->ioaddr + ClkRun); /* Set MAC address in NIC */ for (i = 0 ; i < ETH_ALEN ; i+=2) { outl (i, np->ioaddr + RxFilterAddr); outw (netdev->ll_addr[i] + (netdev->ll_addr[i + 1] << 8), np->ioaddr + RxFilterData); } /* Setup Tx Ring */ np->tx_cur = 0; np->tx_dirty = 0; for (i = 0 ; i < TX_RING_SIZE ; i++) { np->tx[i].link = virt_to_bus ((i + 1 < TX_RING_SIZE) ? &np->tx[i + 1] : &np->tx[0]); np->tx[i].cmdsts = 0; np->tx[i].bufptr = 0; } outl (virt_to_bus (&np->tx[0]),np->ioaddr + TxRingPtr); DBG ("Natsemi Tx descriptor loaded with: %#08x\n", inl (np->ioaddr + TxRingPtr)); /* Setup RX ring */ np->rx_cur = 0; for (i = 0 ; i < NUM_RX_DESC ; i++) { np->iobuf[i] = alloc_iob (RX_BUF_SIZE); if (! np->iobuf[i]) goto memory_alloc_err; np->rx[i].link = virt_to_bus ((i + 1 < NUM_RX_DESC) ? &np->rx[i + 1] : &np->rx[0]); np->rx[i].cmdsts = RX_BUF_SIZE; np->rx[i].bufptr = virt_to_bus (np->iobuf[i]->data); DBG (" Address of iobuf [%d] = %p and iobuf->data = %p \n", i, &np->iobuf[i], &np->iobuf[i]->data); } outl (virt_to_bus (&np->rx[0]), np->ioaddr + RxRingPtr); DBG ("Natsemi Rx descriptor loaded with: %#08x\n", inl (np->ioaddr + RxRingPtr)); /* Setup RX Filter */ outl (RxFilterEnable | AcceptBroadcast | AcceptAllMulticast | AcceptMyPhys, np->ioaddr + RxFilterAddr); /* Initialize other registers. * Configure the PCI bus bursts and FIFO thresholds. * Configure for standard, in-spec Ethernet. */ if (inl (np->ioaddr + ChipConfig) & 0x20000000) { /* Full duplex */ DBG ("Full duplex\n"); tx_config = 0xD0801002 | 0xC0000000; rx_config = 0x10000020 | 0x10000000; } else { DBG ("Half duplex\n"); tx_config = 0x10801002 & ~0xC0000000; rx_config = 0x00000020 & ~0x10000000; } outl (tx_config, np->ioaddr + TxConfig); outl (rx_config, np->ioaddr + RxConfig); DBG ("Tx config register = %#08x Rx config register = %#08x\n", inl (np->ioaddr + TxConfig), inl (np->ioaddr + RxConfig)); /*Set the Interrupt Mask register */ outl((RxOk|RxErr|TxOk|TxErr),np->ioaddr + IntrMask); /*start the receiver */ outl (RxOn, np->ioaddr + ChipCmd); return 0; memory_alloc_err: /* Frees any allocated buffers when memory * for all buffers requested is not available */ i = 0; while (np->rx[i].cmdsts == RX_BUF_SIZE) { free_iob (np->iobuf[i]); i++; } return -ENOMEM; } /** * Close NIC * * @v netdev Net device */ static void natsemi_close (struct net_device *netdev) { struct natsemi_private *np = netdev->priv; int i; natsemi_reset (netdev); for (i = 0; i < NUM_RX_DESC ; i++) { free_iob (np->iobuf[i]); } } /** * Transmit packet * * @v netdev Network device * @v iobuf I/O buffer * @ret rc Return status code */ static int natsemi_transmit (struct net_device *netdev, struct io_buffer *iobuf) { struct natsemi_private *np = netdev->priv; if (np->tx[np->tx_cur].cmdsts != 0) { DBG ("TX overflow\n"); return -ENOBUFS; } /* Used by netdev_tx_complete () */ np->tx_iobuf[np->tx_cur] = iobuf; /* Pad and align packet has not been used because its not required * by the hardware. * iob_pad (iobuf, ETH_ZLEN); * can be used to achieve it, if required */ /* Add the packet to TX ring */ np->tx[np->tx_cur].bufptr = virt_to_bus (iobuf->data); np->tx[np->tx_cur].cmdsts = iob_len (iobuf) | OWN; DBG ("TX id %d at %#08lx + %#08zx\n", np->tx_cur, virt_to_bus (&iobuf->data), iob_len (iobuf)); /* increment the circular buffer pointer to the next buffer location */ np->tx_cur = (np->tx_cur + 1) % TX_RING_SIZE; /*start the transmitter */ outl (TxOn, np->ioaddr + ChipCmd); return 0; } /** * Poll for received packets * * @v netdev Network device */ static void natsemi_poll (struct net_device *netdev) { struct natsemi_private *np = netdev->priv; unsigned int tx_status; unsigned int rx_status; unsigned int intr_status; unsigned int rx_len; struct io_buffer *rx_iob; int i; /* read the interrupt register */ intr_status = inl (np->ioaddr + IntrStatus); if (!intr_status) goto end; DBG ("natsemi_poll: intr_status = %#08x\n", intr_status); /* Check status of transmitted packets */ i = np->tx_dirty; while (i != np->tx_cur) { tx_status = np->tx[np->tx_dirty].cmdsts; DBG ("tx_dirty = %d tx_cur=%d tx_status=%#08x\n", np->tx_dirty, np->tx_cur, tx_status); if (tx_status & OWN) break; if (! (tx_status & DescPktOK)) { netdev_tx_complete_err (netdev,np->tx_iobuf[np->tx_dirty],-EINVAL); DBG ("Error transmitting packet, tx_status: %#08x\n", tx_status); } else { netdev_tx_complete (netdev, np->tx_iobuf[np->tx_dirty]); DBG ("Success transmitting packet\n"); } np->tx[np->tx_dirty].cmdsts = 0; np->tx_dirty = (np->tx_dirty + 1) % TX_RING_SIZE; i = (i + 1) % TX_RING_SIZE; } /* Process received packets */ rx_status = (unsigned int) np->rx[np->rx_cur].cmdsts; while ((rx_status & OWN)) { rx_len = (rx_status & DSIZE) - CRC_SIZE; DBG ("Received packet, rx_curr = %d, rx_status = %#08x, rx_len = %d\n", np->rx_cur, rx_status, rx_len); if ((rx_status & (DescMore | DescPktOK | RxTooLong)) != DescPktOK) { netdev_rx_err (netdev, NULL, -EINVAL); DBG ("natsemi_poll: Corrupted packet received!" " Status = %#08x\n", np->rx[np->rx_cur].cmdsts); } else { /* If unable allocate space for this packet, * try again next poll */ rx_iob = alloc_iob (rx_len); if (! rx_iob) goto end; memcpy (iob_put (rx_iob, rx_len), np->iobuf[np->rx_cur]->data, rx_len); /* Add this packet to the receive queue. */ netdev_rx (netdev, rx_iob); } np->rx[np->rx_cur].cmdsts = RX_BUF_SIZE; np->rx_cur = (np->rx_cur + 1) % NUM_RX_DESC; rx_status = np->rx[np->rx_cur].cmdsts; } end: /* re-enable the potentially idle receive state machine */ outl (RxOn, np->ioaddr + ChipCmd); } /** * Enable/disable interrupts * * @v netdev Network device * @v enable Non-zero for enable, zero for disable */ static void natsemi_irq (struct net_device *netdev, int enable) { struct natsemi_private *np = netdev->priv; outl ((enable ? (RxOk | RxErr | TxOk|TxErr) : 0), np->ioaddr + IntrMask); outl ((enable ? 1 : 0), np->ioaddr + IntrEnable); } static struct pci_device_id natsemi_nics[] = { PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815", 0), }; struct pci_driver natsemi_driver __pci_driver = { .ids = natsemi_nics, .id_count = (sizeof (natsemi_nics) / sizeof (natsemi_nics[0])), .probe = natsemi_probe, .remove = natsemi_remove, }; debian/grub-extras/disabled/gpxe/src/drivers/net/3c509.c0000664000000000000000000002500312524662415020116 0ustar /* * Split out into 3c509.c and 3c5x9.c, to make it possible to build a * 3c529 module without including ISA, ISAPnP and EISA code. * */ FILE_LICENCE ( BSD2 ); #include #include #include #include #include #include #include #include #include "3c509.h" /* * 3c509 cards have their own method of contention resolution; this * effectively defines another bus type similar to ISAPnP. Even the * original ISA cards can be programatically mapped to any I/O address * in the range 0x200-0x3e0. * * However, there is a small problem: once you've activated a card, * the only ways to deactivate it will also wipe its tag, meaning that * you won't be able to subsequently reactivate it without going * through the whole ID sequence again. The solution we adopt is to * isolate and tag all cards at the start, and to immediately * re-isolate and re-tag a card after disabling it. * */ static void t509bus_remove ( struct root_device *rootdev ); static unsigned int t509_id_port = 0; static unsigned int t509_max_tag = 0; /** A 3c509 device */ struct t509_device { /** Generic device */ struct device dev; /** Tag */ unsigned int tag; /** I/O address */ uint16_t ioaddr; /** Driver-private data * * Use t509_set_drvdata() and t509_get_drvdata() to access * this field. */ void *priv; }; /** * Set 3c509 driver-private data * * @v t509 3c509 device * @v priv Private data */ static inline void t509_set_drvdata ( struct t509_device *t509, void *priv ) { t509->priv = priv; } /** * Get 3c509 driver-private data * * @v t509 3c509 device * @ret priv Private data */ static inline void * t509_get_drvdata ( struct t509_device *t509 ) { return t509->priv; } /* * t509 utility functions * */ static inline void t509_set_id_port ( void ) { outb ( 0x00, t509_id_port ); } static inline void t509_wait_for_id_sequence ( void ) { outb ( 0x00, t509_id_port ); } static inline void t509_global_reset ( void ) { outb ( 0xc0, t509_id_port ); } static inline void t509_reset_tag ( void ) { outb ( 0xd0, t509_id_port ); } static inline void t509_set_tag ( uint8_t tag ) { outb ( 0xd0 | tag, t509_id_port ); } static inline void t509_select_tag ( uint8_t tag ) { outb ( 0xd8 | tag, t509_id_port ); } static inline void t509_activate ( uint16_t ioaddr ) { outb ( 0xe0 | ( ioaddr >> 4 ), t509_id_port ); } static inline void t509_deactivate_and_reset_tag ( uint16_t ioaddr ) { outb ( GLOBAL_RESET, ioaddr + EP_COMMAND ); } static inline void t509_load_eeprom_word ( uint8_t offset ) { outb ( 0x80 | offset, t509_id_port ); } /* * Find a suitable ID port * */ static inline int t509_find_id_port ( void ) { for ( t509_id_port = EP_ID_PORT_START ; t509_id_port < EP_ID_PORT_END ; t509_id_port += EP_ID_PORT_INC ) { t509_set_id_port (); /* See if anything's listening */ outb ( 0xff, t509_id_port ); if ( inb ( t509_id_port ) & 0x01 ) { /* Found a suitable port */ DBG ( "T509 using ID port at %04x\n", t509_id_port ); return 0; } } /* No id port available */ DBG ( "T509 found no available ID port\n" ); return -ENOENT; } /* * Send ID sequence to the ID port * */ static void t509_send_id_sequence ( void ) { unsigned short lrs_state, i; t509_set_id_port (); /* Reset IDS on cards */ t509_wait_for_id_sequence (); lrs_state = 0xff; for ( i = 0; i < 255; i++ ) { outb ( lrs_state, t509_id_port ); lrs_state <<= 1; lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state; } } /* * We get eeprom data from the id_port given an offset into the eeprom. * Basically; after the ID_sequence is sent to all of the cards; they enter * the ID_CMD state where they will accept command requests. 0x80-0xbf loads * the eeprom data. We then read the port 16 times and with every read; the * cards check for contention (ie: if one card writes a 0 bit and another * writes a 1 bit then the host sees a 0. At the end of the cycle; each card * compares the data on the bus; if there is a difference then that card goes * into ID_WAIT state again). In the meantime; one bit of data is returned in * the AX register which is conveniently returned to us by inb(). Hence; we * read 16 times getting one bit of data with each read. */ static uint16_t t509_id_read_eeprom ( int offset ) { int i, data = 0; t509_load_eeprom_word ( offset ); /* Do we really need this wait? Won't be noticeable anyway */ udelay(10000); for ( i = 0; i < 16; i++ ) { data = ( data << 1 ) | ( inw ( t509_id_port ) & 1 ); } return data; } /* * Isolate and tag all t509 cards * */ static int t509_isolate ( void ) { unsigned int i; uint16_t contend[3]; int rc; /* Find a suitable ID port */ if ( ( rc = t509_find_id_port() ) != 0 ) return rc; while ( 1 ) { /* All cards are in ID_WAIT state each time we go * through this loop. */ /* Send the ID sequence */ t509_send_id_sequence(); /* First time through, reset all tags. On subsequent * iterations, kill off any already-tagged cards */ if ( t509_max_tag == 0 ) { t509_reset_tag(); } else { t509_select_tag ( 0 ); } /* Read the manufacturer ID, to see if there are any * more cards */ if ( t509_id_read_eeprom ( EEPROM_MFG_ID ) != MFG_ID ) { DBG ( "T509 saw %s signs of life\n", t509_max_tag ? "no further" : "no" ); break; } /* Perform contention selection on the MAC address */ for ( i = 0 ; i < 3 ; i++ ) { contend[i] = t509_id_read_eeprom ( i ); } /* Only one device will still be left alive. Tag it. */ ++t509_max_tag; DBG ( "T509 found card %04x%04x%04x, assigning tag %02x\n", contend[0], contend[1], contend[2], t509_max_tag ); t509_set_tag ( t509_max_tag ); /* Return all cards back to ID_WAIT state */ t509_wait_for_id_sequence(); } DBG ( "T509 found %d cards using ID port %04x\n", t509_max_tag, t509_id_port ); return 0; } /* * Activate a T509 device * * The device will be enabled at whatever ioaddr is specified in the * struct t509_device; there is no need to stick with the default * ioaddr read from the EEPROM. * */ static inline void activate_t509_device ( struct t509_device *t509 ) { t509_send_id_sequence (); t509_select_tag ( t509->tag ); t509_activate ( t509->ioaddr ); DBG ( "T509 activated device %02x at ioaddr %04x\n", t509->tag, t509->ioaddr ); } /* * Deactivate a T509 device * * Disabling also clears the tag, so we immediately isolate and re-tag * this card. * */ static inline void deactivate_t509_device ( struct t509_device *t509 ) { t509_deactivate_and_reset_tag ( t509->ioaddr ); udelay ( 1000 ); t509_send_id_sequence (); t509_select_tag ( 0 ); t509_set_tag ( t509->tag ); t509_wait_for_id_sequence (); DBG ( "T509 deactivated device at %04x and re-tagged as %02x\n", t509->ioaddr, t509->tag ); } /* * The ISA probe function * */ static int legacy_t509_probe ( struct nic *nic, void *hwdev ) { struct t509_device *t509 = hwdev; /* We could change t509->ioaddr if we wanted to */ activate_t509_device ( t509 ); nic->ioaddr = t509->ioaddr; /* Hand off to generic t5x9 probe routine */ return t5x9_probe ( nic, ISA_PROD_ID ( PROD_ID ), ISA_PROD_ID_MASK ); } static void legacy_t509_disable ( struct nic *nic, void *hwdev ) { struct t509_device *t509 = hwdev; t5x9_disable ( nic ); deactivate_t509_device ( t509 ); } static inline void legacy_t509_set_drvdata ( void *hwdev, void *priv ) { t509_set_drvdata ( hwdev, priv ); } static inline void * legacy_t509_get_drvdata ( void *hwdev ) { return t509_get_drvdata ( hwdev ); } /** * Probe a 3c509 device * * @v t509 3c509 device * @ret rc Return status code * * Searches for a driver for the 3c509 device. If a driver is found, * its probe() routine is called. */ static int t509_probe ( struct t509_device *t509 ) { DBG ( "Adding 3c509 device %02x (I/O %04x)\n", t509->tag, t509->ioaddr ); return legacy_probe ( t509, legacy_t509_set_drvdata, &t509->dev, legacy_t509_probe, legacy_t509_disable ); } /** * Remove a 3c509 device * * @v t509 3c509 device */ static void t509_remove ( struct t509_device *t509 ) { legacy_remove ( t509, legacy_t509_get_drvdata, legacy_t509_disable ); DBG ( "Removed 3c509 device %02x\n", t509->tag ); } /** * Probe 3c509 root bus * * @v rootdev 3c509 bus root device * * Scans the 3c509 bus for devices and registers all devices it can * find. */ static int t509bus_probe ( struct root_device *rootdev ) { struct t509_device *t509 = NULL; unsigned int tag; unsigned int iobase; int rc; /* Perform isolation and tagging */ if ( ( rc = t509_isolate() ) != 0 ) return rc; for ( tag = 1 ; tag <= t509_max_tag ; tag++ ) { /* Allocate struct t509_device */ if ( ! t509 ) t509 = malloc ( sizeof ( *t509 ) ); if ( ! t509 ) { rc = -ENOMEM; goto err; } memset ( t509, 0, sizeof ( *t509 ) ); t509->tag = tag; /* Send the ID sequence */ t509_send_id_sequence (); /* Select the specified tag */ t509_select_tag ( t509->tag ); /* Read the default I/O address */ iobase = t509_id_read_eeprom ( EEPROM_ADDR_CFG ); t509->ioaddr = 0x200 + ( ( iobase & 0x1f ) << 4 ); /* Send card back to ID_WAIT */ t509_wait_for_id_sequence(); /* Add to device hierarchy */ snprintf ( t509->dev.name, sizeof ( t509->dev.name ), "t509%02x", tag ); t509->dev.desc.bus_type = BUS_TYPE_ISA; t509->dev.desc.vendor = MFG_ID; t509->dev.desc.device = PROD_ID; t509->dev.parent = &rootdev->dev; list_add ( &t509->dev.siblings, &rootdev->dev.children ); INIT_LIST_HEAD ( &t509->dev.children ); /* Look for a driver */ if ( t509_probe ( t509 ) == 0 ) { /* t509dev registered, we can drop our ref */ t509 = NULL; } else { /* Not registered; re-use struct */ list_del ( &t509->dev.siblings ); } } free ( t509 ); return 0; err: free ( t509 ); t509bus_remove ( rootdev ); return rc; } /** * Remove 3c509 root bus * * @v rootdev 3c509 bus root device */ static void t509bus_remove ( struct root_device *rootdev ) { struct t509_device *t509; struct t509_device *tmp; list_for_each_entry_safe ( t509, tmp, &rootdev->dev.children, dev.siblings ) { t509_remove ( t509 ); list_del ( &t509->dev.siblings ); free ( t509 ); } } /** 3c509 bus root device driver */ static struct root_driver t509_root_driver = { .probe = t509bus_probe, .remove = t509bus_remove, }; /** 3c509 bus root device */ struct root_device t509_root_device __root_device = { .dev = { .name = "3c509" }, .driver = &t509_root_driver, }; ISA_ROM ( "3c509", "3c509" ); debian/grub-extras/disabled/gpxe/src/drivers/net/prism2_plx.c0000664000000000000000000001010112524662415021443 0ustar /************************************************************************** Etherboot - BOOTP/TFTP Bootstrap Program Prism2 NIC driver for Etherboot Wrapper for prism2_plx Written by Michael Brown of Fen Systems Ltd $Id$ ***************************************************************************/ /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #define WLAN_HOSTIF WLAN_PLX #include "prism2.c" /* * Find PLX card. Prints out information strings from PCMCIA CIS as visual * confirmation of presence of card. * * Arguments: * hw device structure to be filled in * p PCI device structure * * Returns: * 1 Success */ static int prism2_find_plx ( hfa384x_t *hw, struct pci_device *p ) { int found = 0; uint32_t plx_lcr = 0; /* PLX9052 Local Configuration Register Base (I/O) */ uint32_t attr_mem = 0; /* Prism2 Attribute Memory Base */ uint32_t iobase = 0; /* Prism2 I/O Base */ unsigned char *cis_tpl = NULL; unsigned char *cis_string; /* Obtain all memory and IO base addresses */ pci_read_config_dword( p, PLX_LOCAL_CONFIG_REGISTER_BASE, &plx_lcr); plx_lcr &= PCI_BASE_ADDRESS_IO_MASK; pci_read_config_dword( p, PRISM2_PLX_ATTR_MEM_BASE, &attr_mem); pci_read_config_dword( p, PRISM2_PLX_IO_BASE, &iobase); iobase &= PCI_BASE_ADDRESS_IO_MASK; /* Fill out hw structure */ hw->iobase = iobase; printf ( "PLX9052 has local config registers at %#x\n", plx_lcr ); printf ( "Prism2 has attribute memory at %#x and I/O base at %#x\n", attr_mem, iobase ); /* Search for CIS strings */ printf ( "Searching for PCMCIA card...\n" ); cis_tpl = bus_to_virt(attr_mem); while ( *cis_tpl != CISTPL_END ) { if ( *cis_tpl == CISTPL_VERS_1 ) { /* CISTPL_VERS_1 contains some nice text strings */ printf ( "...found " ); found = 1; cis_string = cis_tpl + CISTPL_VERS_1_STR_OFF; while ( ! ( ( *cis_string == 0 ) && ( *(cis_string+CIS_STEP) == 0 ) ) ) { printf ( "%c", *cis_string == 0 ? ' ' : *cis_string ); cis_string += CIS_STEP; } printf ( "\n" ); } /* printf ( "CIS tuple type %#hhx, length %#hhx\n", *cis_tpl, *(cis_tpl+CISTPL_LEN_OFF) ); */ cis_tpl += CISTPL_HEADER_LEN + CIS_STEP * ( *(cis_tpl+CISTPL_LEN_OFF) ); } if ( found == 0 ) { printf ( "...nothing found\n" ); } ((unsigned char *)bus_to_virt(attr_mem))[COR_OFFSET] = COR_VALUE; /* Write COR to enable PC card */ return found; } static int prism2_plx_probe ( struct nic *nic, struct pci_device *pci ) { hfa384x_t *hw = &hw_global; /* Find and intialise PLX Prism2 card */ if ( ! prism2_find_plx ( hw, pci ) ) return 0; nic->ioaddr = hw->iobase; nic->irqno = 0; return prism2_probe ( nic, hw ); } static void prism2_plx_disable ( struct nic *nic ) { prism2_disable ( nic ); } static struct pci_device_id prism2_plx_nics[] = { PCI_ROM(0x1385, 0x4100, "ma301", "Netgear MA301", 0), PCI_ROM(0x10b7, 0x7770, "3c-airconnect", "3Com AirConnect", 0), PCI_ROM(0x111a, 0x1023, "ss1023", "Siemens SpeedStream SS1023", 0), PCI_ROM(0x15e8, 0x0130, "correga", "Correga", 0), PCI_ROM(0x1638, 0x1100, "smc2602w", "SMC EZConnect SMC2602W", 0), /* or Eumitcom PCI WL11000, Addtron AWA-100 */ PCI_ROM(0x16ab, 0x1100, "gl24110p", "Global Sun Tech GL24110P", 0), PCI_ROM(0x16ab, 0x1101, "16ab-1101", "Unknown", 0), PCI_ROM(0x16ab, 0x1102, "wdt11", "Linksys WDT11", 0), PCI_ROM(0x16ec, 0x3685, "usr2415", "USR 2415", 0), PCI_ROM(0xec80, 0xec00, "f5d6000", "Belkin F5D6000", 0), PCI_ROM(0x126c, 0x8030, "emobility", "Nortel emobility", 0), }; PCI_DRIVER ( prism2_plx_driver, prism2_plx_nics, PCI_NO_CLASS ); DRIVER ( "Prism2/PLX", nic_driver, pci_driver, prism2_plx_driver, prism2_plx_probe, prism2_plx_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/bnx2.h0000664000000000000000000057411412524662415020245 0ustar /* bnx2.h: Broadcom NX2 network driver. * * Copyright (c) 2004, 2005, 2006 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * * Written by: Michael Chan (mchan@broadcom.com) */ FILE_LICENCE ( GPL_ANY ); #ifndef BNX2_H #define BNX2_H #define L1_CACHE_BYTES 128 /* Rough approximaition of the cache line size */ #define L1_CACHE_ALIGN(X) (((X) + L1_CACHE_BYTES-1)&~(L1_CACHE_BYTES -1)) typedef unsigned long dma_addr_t; /* From pci.h */ typedef int pci_power_t; #define PCI_D0 ((pci_power_t) 0) #define PCI_D1 ((pci_power_t) 1) #define PCI_D2 ((pci_power_t) 2) #define PCI_D3hot ((pci_power_t) 3) #define PCI_D3cold ((pci_power_t) 4) #define PCI_UNKNOWN ((pci_power_t) 5) #define PCI_POWER_ERROR ((pci_power_t) -1) /* From pci_regs.h */ #define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ #define PCI_X_CMD 2 /* Modes & Features */ #define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */ /* From mii.h */ /* Indicates what features are advertised by the interface. */ #define ADVERTISED_10baseT_Half (1 << 0) #define ADVERTISED_10baseT_Full (1 << 1) #define ADVERTISED_100baseT_Half (1 << 2) #define ADVERTISED_100baseT_Full (1 << 3) #define ADVERTISED_1000baseT_Half (1 << 4) #define ADVERTISED_1000baseT_Full (1 << 5) #define ADVERTISED_Autoneg (1 << 6) #define ADVERTISED_TP (1 << 7) #define ADVERTISED_AUI (1 << 8) #define ADVERTISED_MII (1 << 9) #define ADVERTISED_FIBRE (1 << 10) #define ADVERTISED_BNC (1 << 11) /* The following are all involved in forcing a particular link * mode for the device for setting things. When getting the * devices settings, these indicate the current mode and whether * it was foced up into this mode or autonegotiated. */ /* Duplex, half or full. */ #define DUPLEX_HALF 0x00 #define DUPLEX_FULL 0x01 #define DUPLEX_INVALID 0x02 /* Which connector port. */ #define PORT_TP 0x00 #define PORT_AUI 0x01 #define PORT_MII 0x02 #define PORT_FIBRE 0x03 #define PORT_BNC 0x04 /* Which tranceiver to use. */ #define XCVR_INTERNAL 0x00 #define XCVR_EXTERNAL 0x01 #define XCVR_DUMMY1 0x02 #define XCVR_DUMMY2 0x03 #define XCVR_DUMMY3 0x04 /* Enable or disable autonegotiation. If this is set to enable, * the forced link modes above are completely ignored. */ #define AUTONEG_DISABLE 0x00 #define AUTONEG_ENABLE 0x01 /* Wake-On-Lan options. */ #define WAKE_PHY (1 << 0) #define WAKE_UCAST (1 << 1) #define WAKE_MCAST (1 << 2) #define WAKE_BCAST (1 << 3) #define WAKE_ARP (1 << 4) #define WAKE_MAGIC (1 << 5) #define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */ /* The following are all involved in forcing a particular link * * mode for the device for setting things. When getting the * * devices settings, these indicate the current mode and whether * * it was foced up into this mode or autonegotiated. * */ /* The forced speed, 10Mb, 100Mb, gigabit. */ #define SPEED_10 10 #define SPEED_100 100 #define SPEED_1000 1000 #define SPEED_2500 2500 #define SPEED_INVALID 0 /* XXX was 3 */ /* Duplex, half or full. */ #define DUPLEX_HALF 0x00 #define DUPLEX_FULL 0x01 #define DUPLEX_INVALID 0x02 /* Which connector port. */ #define PORT_TP 0x00 #define PORT_AUI 0x01 #define PORT_MII 0x02 #define PORT_FIBRE 0x03 #define PORT_BNC 0x04 /* Which tranceiver to use. */ #define XCVR_INTERNAL 0x00 #define XCVR_EXTERNAL 0x01 #define XCVR_DUMMY1 0x02 #define XCVR_DUMMY2 0x03 #define XCVR_DUMMY3 0x04 /* Enable or disable autonegotiation. If this is set to enable, * * the forced link modes above are completely ignored. * */ #define AUTONEG_DISABLE 0x00 #define AUTONEG_ENABLE 0x01 /* Wake-On-Lan options. */ #define WAKE_PHY (1 << 0) #define WAKE_UCAST (1 << 1) #define WAKE_MCAST (1 << 2) #define WAKE_BCAST (1 << 3) #define WAKE_ARP (1 << 4) #define WAKE_MAGIC (1 << 5) #define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */ /* Hardware data structures and register definitions automatically * generated from RTL code. Do not modify. */ /* * tx_bd definition */ struct tx_bd { u32 tx_bd_haddr_hi; u32 tx_bd_haddr_lo; u32 tx_bd_mss_nbytes; u32 tx_bd_vlan_tag_flags; #define TX_BD_FLAGS_CONN_FAULT (1<<0) #define TX_BD_FLAGS_TCP_UDP_CKSUM (1<<1) #define TX_BD_FLAGS_IP_CKSUM (1<<2) #define TX_BD_FLAGS_VLAN_TAG (1<<3) #define TX_BD_FLAGS_COAL_NOW (1<<4) #define TX_BD_FLAGS_DONT_GEN_CRC (1<<5) #define TX_BD_FLAGS_END (1<<6) #define TX_BD_FLAGS_START (1<<7) #define TX_BD_FLAGS_SW_OPTION_WORD (0x1f<<8) #define TX_BD_FLAGS_SW_FLAGS (1<<13) #define TX_BD_FLAGS_SW_SNAP (1<<14) #define TX_BD_FLAGS_SW_LSO (1<<15) }; /* * rx_bd definition */ struct rx_bd { u32 rx_bd_haddr_hi; u32 rx_bd_haddr_lo; u32 rx_bd_len; u32 rx_bd_flags; #define RX_BD_FLAGS_NOPUSH (1<<0) #define RX_BD_FLAGS_DUMMY (1<<1) #define RX_BD_FLAGS_END (1<<2) #define RX_BD_FLAGS_START (1<<3) }; /* * status_block definition */ struct status_block { u32 status_attn_bits; #define STATUS_ATTN_BITS_LINK_STATE (1L<<0) #define STATUS_ATTN_BITS_TX_SCHEDULER_ABORT (1L<<1) #define STATUS_ATTN_BITS_TX_BD_READ_ABORT (1L<<2) #define STATUS_ATTN_BITS_TX_BD_CACHE_ABORT (1L<<3) #define STATUS_ATTN_BITS_TX_PROCESSOR_ABORT (1L<<4) #define STATUS_ATTN_BITS_TX_DMA_ABORT (1L<<5) #define STATUS_ATTN_BITS_TX_PATCHUP_ABORT (1L<<6) #define STATUS_ATTN_BITS_TX_ASSEMBLER_ABORT (1L<<7) #define STATUS_ATTN_BITS_RX_PARSER_MAC_ABORT (1L<<8) #define STATUS_ATTN_BITS_RX_PARSER_CATCHUP_ABORT (1L<<9) #define STATUS_ATTN_BITS_RX_MBUF_ABORT (1L<<10) #define STATUS_ATTN_BITS_RX_LOOKUP_ABORT (1L<<11) #define STATUS_ATTN_BITS_RX_PROCESSOR_ABORT (1L<<12) #define STATUS_ATTN_BITS_RX_V2P_ABORT (1L<<13) #define STATUS_ATTN_BITS_RX_BD_CACHE_ABORT (1L<<14) #define STATUS_ATTN_BITS_RX_DMA_ABORT (1L<<15) #define STATUS_ATTN_BITS_COMPLETION_ABORT (1L<<16) #define STATUS_ATTN_BITS_HOST_COALESCE_ABORT (1L<<17) #define STATUS_ATTN_BITS_MAILBOX_QUEUE_ABORT (1L<<18) #define STATUS_ATTN_BITS_CONTEXT_ABORT (1L<<19) #define STATUS_ATTN_BITS_CMD_SCHEDULER_ABORT (1L<<20) #define STATUS_ATTN_BITS_CMD_PROCESSOR_ABORT (1L<<21) #define STATUS_ATTN_BITS_MGMT_PROCESSOR_ABORT (1L<<22) #define STATUS_ATTN_BITS_MAC_ABORT (1L<<23) #define STATUS_ATTN_BITS_TIMER_ABORT (1L<<24) #define STATUS_ATTN_BITS_DMAE_ABORT (1L<<25) #define STATUS_ATTN_BITS_FLSH_ABORT (1L<<26) #define STATUS_ATTN_BITS_GRC_ABORT (1L<<27) #define STATUS_ATTN_BITS_PARITY_ERROR (1L<<31) u32 status_attn_bits_ack; #if __BYTE_ORDER == __BIG_ENDIAN u16 status_tx_quick_consumer_index0; u16 status_tx_quick_consumer_index1; u16 status_tx_quick_consumer_index2; u16 status_tx_quick_consumer_index3; u16 status_rx_quick_consumer_index0; u16 status_rx_quick_consumer_index1; u16 status_rx_quick_consumer_index2; u16 status_rx_quick_consumer_index3; u16 status_rx_quick_consumer_index4; u16 status_rx_quick_consumer_index5; u16 status_rx_quick_consumer_index6; u16 status_rx_quick_consumer_index7; u16 status_rx_quick_consumer_index8; u16 status_rx_quick_consumer_index9; u16 status_rx_quick_consumer_index10; u16 status_rx_quick_consumer_index11; u16 status_rx_quick_consumer_index12; u16 status_rx_quick_consumer_index13; u16 status_rx_quick_consumer_index14; u16 status_rx_quick_consumer_index15; u16 status_completion_producer_index; u16 status_cmd_consumer_index; u16 status_idx; u16 status_unused; #elif __BYTE_ORDER == __LITTLE_ENDIAN u16 status_tx_quick_consumer_index1; u16 status_tx_quick_consumer_index0; u16 status_tx_quick_consumer_index3; u16 status_tx_quick_consumer_index2; u16 status_rx_quick_consumer_index1; u16 status_rx_quick_consumer_index0; u16 status_rx_quick_consumer_index3; u16 status_rx_quick_consumer_index2; u16 status_rx_quick_consumer_index5; u16 status_rx_quick_consumer_index4; u16 status_rx_quick_consumer_index7; u16 status_rx_quick_consumer_index6; u16 status_rx_quick_consumer_index9; u16 status_rx_quick_consumer_index8; u16 status_rx_quick_consumer_index11; u16 status_rx_quick_consumer_index10; u16 status_rx_quick_consumer_index13; u16 status_rx_quick_consumer_index12; u16 status_rx_quick_consumer_index15; u16 status_rx_quick_consumer_index14; u16 status_cmd_consumer_index; u16 status_completion_producer_index; u16 status_unused; u16 status_idx; #endif }; /* * statistics_block definition */ struct statistics_block { u32 stat_IfHCInOctets_hi; u32 stat_IfHCInOctets_lo; u32 stat_IfHCInBadOctets_hi; u32 stat_IfHCInBadOctets_lo; u32 stat_IfHCOutOctets_hi; u32 stat_IfHCOutOctets_lo; u32 stat_IfHCOutBadOctets_hi; u32 stat_IfHCOutBadOctets_lo; u32 stat_IfHCInUcastPkts_hi; u32 stat_IfHCInUcastPkts_lo; u32 stat_IfHCInMulticastPkts_hi; u32 stat_IfHCInMulticastPkts_lo; u32 stat_IfHCInBroadcastPkts_hi; u32 stat_IfHCInBroadcastPkts_lo; u32 stat_IfHCOutUcastPkts_hi; u32 stat_IfHCOutUcastPkts_lo; u32 stat_IfHCOutMulticastPkts_hi; u32 stat_IfHCOutMulticastPkts_lo; u32 stat_IfHCOutBroadcastPkts_hi; u32 stat_IfHCOutBroadcastPkts_lo; u32 stat_emac_tx_stat_dot3statsinternalmactransmiterrors; u32 stat_Dot3StatsCarrierSenseErrors; u32 stat_Dot3StatsFCSErrors; u32 stat_Dot3StatsAlignmentErrors; u32 stat_Dot3StatsSingleCollisionFrames; u32 stat_Dot3StatsMultipleCollisionFrames; u32 stat_Dot3StatsDeferredTransmissions; u32 stat_Dot3StatsExcessiveCollisions; u32 stat_Dot3StatsLateCollisions; u32 stat_EtherStatsCollisions; u32 stat_EtherStatsFragments; u32 stat_EtherStatsJabbers; u32 stat_EtherStatsUndersizePkts; u32 stat_EtherStatsOverrsizePkts; u32 stat_EtherStatsPktsRx64Octets; u32 stat_EtherStatsPktsRx65Octetsto127Octets; u32 stat_EtherStatsPktsRx128Octetsto255Octets; u32 stat_EtherStatsPktsRx256Octetsto511Octets; u32 stat_EtherStatsPktsRx512Octetsto1023Octets; u32 stat_EtherStatsPktsRx1024Octetsto1522Octets; u32 stat_EtherStatsPktsRx1523Octetsto9022Octets; u32 stat_EtherStatsPktsTx64Octets; u32 stat_EtherStatsPktsTx65Octetsto127Octets; u32 stat_EtherStatsPktsTx128Octetsto255Octets; u32 stat_EtherStatsPktsTx256Octetsto511Octets; u32 stat_EtherStatsPktsTx512Octetsto1023Octets; u32 stat_EtherStatsPktsTx1024Octetsto1522Octets; u32 stat_EtherStatsPktsTx1523Octetsto9022Octets; u32 stat_XonPauseFramesReceived; u32 stat_XoffPauseFramesReceived; u32 stat_OutXonSent; u32 stat_OutXoffSent; u32 stat_FlowControlDone; u32 stat_MacControlFramesReceived; u32 stat_XoffStateEntered; u32 stat_IfInFramesL2FilterDiscards; u32 stat_IfInRuleCheckerDiscards; u32 stat_IfInFTQDiscards; u32 stat_IfInMBUFDiscards; u32 stat_IfInRuleCheckerP4Hit; u32 stat_CatchupInRuleCheckerDiscards; u32 stat_CatchupInFTQDiscards; u32 stat_CatchupInMBUFDiscards; u32 stat_CatchupInRuleCheckerP4Hit; u32 stat_GenStat00; u32 stat_GenStat01; u32 stat_GenStat02; u32 stat_GenStat03; u32 stat_GenStat04; u32 stat_GenStat05; u32 stat_GenStat06; u32 stat_GenStat07; u32 stat_GenStat08; u32 stat_GenStat09; u32 stat_GenStat10; u32 stat_GenStat11; u32 stat_GenStat12; u32 stat_GenStat13; u32 stat_GenStat14; u32 stat_GenStat15; }; /* * l2_fhdr definition */ struct l2_fhdr { u32 l2_fhdr_status; #define L2_FHDR_STATUS_RULE_CLASS (0x7<<0) #define L2_FHDR_STATUS_RULE_P2 (1<<3) #define L2_FHDR_STATUS_RULE_P3 (1<<4) #define L2_FHDR_STATUS_RULE_P4 (1<<5) #define L2_FHDR_STATUS_L2_VLAN_TAG (1<<6) #define L2_FHDR_STATUS_L2_LLC_SNAP (1<<7) #define L2_FHDR_STATUS_RSS_HASH (1<<8) #define L2_FHDR_STATUS_IP_DATAGRAM (1<<13) #define L2_FHDR_STATUS_TCP_SEGMENT (1<<14) #define L2_FHDR_STATUS_UDP_DATAGRAM (1<<15) #define L2_FHDR_ERRORS_BAD_CRC (1<<17) #define L2_FHDR_ERRORS_PHY_DECODE (1<<18) #define L2_FHDR_ERRORS_ALIGNMENT (1<<19) #define L2_FHDR_ERRORS_TOO_SHORT (1<<20) #define L2_FHDR_ERRORS_GIANT_FRAME (1<<21) #define L2_FHDR_ERRORS_TCP_XSUM (1<<28) #define L2_FHDR_ERRORS_UDP_XSUM (1<<31) u32 l2_fhdr_hash; #if __BYTE_ORDER == __BIG_ENDIAN u16 l2_fhdr_pkt_len; u16 l2_fhdr_vlan_tag; u16 l2_fhdr_ip_xsum; u16 l2_fhdr_tcp_udp_xsum; #elif __BYTE_ORDER == __LITTLE_ENDIAN u16 l2_fhdr_vlan_tag; u16 l2_fhdr_pkt_len; u16 l2_fhdr_tcp_udp_xsum; u16 l2_fhdr_ip_xsum; #endif }; /* * l2_context definition */ #define BNX2_L2CTX_TYPE 0x00000000 #define BNX2_L2CTX_TYPE_SIZE_L2 ((0xc0/0x20)<<16) #define BNX2_L2CTX_TYPE_TYPE (0xf<<28) #define BNX2_L2CTX_TYPE_TYPE_EMPTY (0<<28) #define BNX2_L2CTX_TYPE_TYPE_L2 (1<<28) #define BNX2_L2CTX_TX_HOST_BIDX 0x00000088 #define BNX2_L2CTX_EST_NBD 0x00000088 #define BNX2_L2CTX_CMD_TYPE 0x00000088 #define BNX2_L2CTX_CMD_TYPE_TYPE (0xf<<24) #define BNX2_L2CTX_CMD_TYPE_TYPE_L2 (0<<24) #define BNX2_L2CTX_CMD_TYPE_TYPE_TCP (1<<24) #define BNX2_L2CTX_TX_HOST_BSEQ 0x00000090 #define BNX2_L2CTX_TSCH_BSEQ 0x00000094 #define BNX2_L2CTX_TBDR_BSEQ 0x00000098 #define BNX2_L2CTX_TBDR_BOFF 0x0000009c #define BNX2_L2CTX_TBDR_BIDX 0x0000009c #define BNX2_L2CTX_TBDR_BHADDR_HI 0x000000a0 #define BNX2_L2CTX_TBDR_BHADDR_LO 0x000000a4 #define BNX2_L2CTX_TXP_BOFF 0x000000a8 #define BNX2_L2CTX_TXP_BIDX 0x000000a8 #define BNX2_L2CTX_TXP_BSEQ 0x000000ac /* * l2_bd_chain_context definition */ #define BNX2_L2CTX_BD_PRE_READ 0x00000000 #define BNX2_L2CTX_CTX_SIZE 0x00000000 #define BNX2_L2CTX_CTX_TYPE 0x00000000 #define BNX2_L2CTX_CTX_TYPE_SIZE_L2 ((0x20/20)<<16) #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE (0xf<<28) #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_UNDEFINED (0<<28) #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE (1<<28) #define BNX2_L2CTX_HOST_BDIDX 0x00000004 #define BNX2_L2CTX_HOST_BSEQ 0x00000008 #define BNX2_L2CTX_NX_BSEQ 0x0000000c #define BNX2_L2CTX_NX_BDHADDR_HI 0x00000010 #define BNX2_L2CTX_NX_BDHADDR_LO 0x00000014 #define BNX2_L2CTX_NX_BDIDX 0x00000018 /* * pci_config_l definition * offset: 0000 */ #define BNX2_PCICFG_MISC_CONFIG 0x00000068 #define BNX2_PCICFG_MISC_CONFIG_TARGET_BYTE_SWAP (1L<<2) #define BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP (1L<<3) #define BNX2_PCICFG_MISC_CONFIG_CLOCK_CTL_ENA (1L<<5) #define BNX2_PCICFG_MISC_CONFIG_TARGET_GRC_WORD_SWAP (1L<<6) #define BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA (1L<<7) #define BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ (1L<<8) #define BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY (1L<<9) #define BNX2_PCICFG_MISC_CONFIG_ASIC_METAL_REV (0xffL<<16) #define BNX2_PCICFG_MISC_CONFIG_ASIC_BASE_REV (0xfL<<24) #define BNX2_PCICFG_MISC_CONFIG_ASIC_ID (0xfL<<28) #define BNX2_PCICFG_MISC_STATUS 0x0000006c #define BNX2_PCICFG_MISC_STATUS_INTA_VALUE (1L<<0) #define BNX2_PCICFG_MISC_STATUS_32BIT_DET (1L<<1) #define BNX2_PCICFG_MISC_STATUS_M66EN (1L<<2) #define BNX2_PCICFG_MISC_STATUS_PCIX_DET (1L<<3) #define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED (0x3L<<4) #define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_66 (0L<<4) #define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_100 (1L<<4) #define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_133 (2L<<4) #define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_PCI_MODE (3L<<4) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS 0x00000070 #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET (0xfL<<0) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ (0L<<0) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ (1L<<0) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ (2L<<0) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ (3L<<0) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ (4L<<0) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ (5L<<0) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ (6L<<0) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ (7L<<0) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW (0xfL<<0) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE (1L<<6) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT (1L<<7) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC (0x7L<<8) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_UNDEF (0L<<8) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12 (1L<<8) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_6 (2L<<8) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_62 (4L<<8) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PLAY_DEAD (1L<<11) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED (0xfL<<12) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_100 (0L<<12) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_80 (1L<<12) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_50 (2L<<12) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_40 (4L<<12) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_25 (8L<<12) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_STOP (1L<<16) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_PLL_STOP (1L<<17) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED_18 (1L<<18) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_USE_SPD_DET (1L<<19) #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED (0xfffL<<20) #define BNX2_PCICFG_REG_WINDOW_ADDRESS 0x00000078 #define BNX2_PCICFG_REG_WINDOW 0x00000080 #define BNX2_PCICFG_INT_ACK_CMD 0x00000084 #define BNX2_PCICFG_INT_ACK_CMD_INDEX (0xffffL<<0) #define BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID (1L<<16) #define BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM (1L<<17) #define BNX2_PCICFG_INT_ACK_CMD_MASK_INT (1L<<18) #define BNX2_PCICFG_STATUS_BIT_SET_CMD 0x00000088 #define BNX2_PCICFG_STATUS_BIT_CLEAR_CMD 0x0000008c #define BNX2_PCICFG_MAILBOX_QUEUE_ADDR 0x00000090 #define BNX2_PCICFG_MAILBOX_QUEUE_DATA 0x00000094 /* * pci_reg definition * offset: 0x400 */ #define BNX2_PCI_GRC_WINDOW_ADDR 0x00000400 #define BNX2_PCI_GRC_WINDOW_ADDR_PCI_GRC_WINDOW_ADDR_VALUE (0x3ffffL<<8) #define BNX2_PCI_CONFIG_1 0x00000404 #define BNX2_PCI_CONFIG_1_READ_BOUNDARY (0x7L<<8) #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_OFF (0L<<8) #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_16 (1L<<8) #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_32 (2L<<8) #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_64 (3L<<8) #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_128 (4L<<8) #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_256 (5L<<8) #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_512 (6L<<8) #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_1024 (7L<<8) #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY (0x7L<<11) #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_OFF (0L<<11) #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_16 (1L<<11) #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_32 (2L<<11) #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_64 (3L<<11) #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_128 (4L<<11) #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_256 (5L<<11) #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_512 (6L<<11) #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_1024 (7L<<11) #define BNX2_PCI_CONFIG_2 0x00000408 #define BNX2_PCI_CONFIG_2_BAR1_SIZE (0xfL<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_DISABLED (0L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_64K (1L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_128K (2L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_256K (3L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_512K (4L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_1M (5L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_2M (6L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_4M (7L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_8M (8L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_16M (9L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_32M (10L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_64M (11L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_128M (12L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_256M (13L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_512M (14L<<0) #define BNX2_PCI_CONFIG_2_BAR1_SIZE_1G (15L<<0) #define BNX2_PCI_CONFIG_2_BAR1_64ENA (1L<<4) #define BNX2_PCI_CONFIG_2_EXP_ROM_RETRY (1L<<5) #define BNX2_PCI_CONFIG_2_CFG_CYCLE_RETRY (1L<<6) #define BNX2_PCI_CONFIG_2_FIRST_CFG_DONE (1L<<7) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE (0xffL<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_DISABLED (0L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_1K (1L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_2K (2L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_4K (3L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_8K (4L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_16K (5L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_32K (6L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_64K (7L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_128K (8L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_256K (9L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_512K (10L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_1M (11L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_2M (12L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_4M (13L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_8M (14L<<8) #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_16M (15L<<8) #define BNX2_PCI_CONFIG_2_MAX_SPLIT_LIMIT (0x1fL<<16) #define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT (0x3L<<21) #define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_512 (0L<<21) #define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_1K (1L<<21) #define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_2K (2L<<21) #define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_4K (3L<<21) #define BNX2_PCI_CONFIG_2_FORCE_32_BIT_MSTR (1L<<23) #define BNX2_PCI_CONFIG_2_FORCE_32_BIT_TGT (1L<<24) #define BNX2_PCI_CONFIG_2_KEEP_REQ_ASSERT (1L<<25) #define BNX2_PCI_CONFIG_3 0x0000040c #define BNX2_PCI_CONFIG_3_STICKY_BYTE (0xffL<<0) #define BNX2_PCI_CONFIG_3_FORCE_PME (1L<<24) #define BNX2_PCI_CONFIG_3_PME_STATUS (1L<<25) #define BNX2_PCI_CONFIG_3_PME_ENABLE (1L<<26) #define BNX2_PCI_CONFIG_3_PM_STATE (0x3L<<27) #define BNX2_PCI_CONFIG_3_VAUX_PRESET (1L<<30) #define BNX2_PCI_CONFIG_3_PCI_POWER (1L<<31) #define BNX2_PCI_PM_DATA_A 0x00000410 #define BNX2_PCI_PM_DATA_A_PM_DATA_0_PRG (0xffL<<0) #define BNX2_PCI_PM_DATA_A_PM_DATA_1_PRG (0xffL<<8) #define BNX2_PCI_PM_DATA_A_PM_DATA_2_PRG (0xffL<<16) #define BNX2_PCI_PM_DATA_A_PM_DATA_3_PRG (0xffL<<24) #define BNX2_PCI_PM_DATA_B 0x00000414 #define BNX2_PCI_PM_DATA_B_PM_DATA_4_PRG (0xffL<<0) #define BNX2_PCI_PM_DATA_B_PM_DATA_5_PRG (0xffL<<8) #define BNX2_PCI_PM_DATA_B_PM_DATA_6_PRG (0xffL<<16) #define BNX2_PCI_PM_DATA_B_PM_DATA_7_PRG (0xffL<<24) #define BNX2_PCI_SWAP_DIAG0 0x00000418 #define BNX2_PCI_SWAP_DIAG1 0x0000041c #define BNX2_PCI_EXP_ROM_ADDR 0x00000420 #define BNX2_PCI_EXP_ROM_ADDR_ADDRESS (0x3fffffL<<2) #define BNX2_PCI_EXP_ROM_ADDR_REQ (1L<<31) #define BNX2_PCI_EXP_ROM_DATA 0x00000424 #define BNX2_PCI_VPD_INTF 0x00000428 #define BNX2_PCI_VPD_INTF_INTF_REQ (1L<<0) #define BNX2_PCI_VPD_ADDR_FLAG 0x0000042c #define BNX2_PCI_VPD_ADDR_FLAG_ADDRESS (0x1fff<<2) #define BNX2_PCI_VPD_ADDR_FLAG_WR (1<<15) #define BNX2_PCI_VPD_DATA 0x00000430 #define BNX2_PCI_ID_VAL1 0x00000434 #define BNX2_PCI_ID_VAL1_DEVICE_ID (0xffffL<<0) #define BNX2_PCI_ID_VAL1_VENDOR_ID (0xffffL<<16) #define BNX2_PCI_ID_VAL2 0x00000438 #define BNX2_PCI_ID_VAL2_SUBSYSTEM_VENDOR_ID (0xffffL<<0) #define BNX2_PCI_ID_VAL2_SUBSYSTEM_ID (0xffffL<<16) #define BNX2_PCI_ID_VAL3 0x0000043c #define BNX2_PCI_ID_VAL3_CLASS_CODE (0xffffffL<<0) #define BNX2_PCI_ID_VAL3_REVISION_ID (0xffL<<24) #define BNX2_PCI_ID_VAL4 0x00000440 #define BNX2_PCI_ID_VAL4_CAP_ENA (0xfL<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_0 (0L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_1 (1L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_2 (2L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_3 (3L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_4 (4L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_5 (5L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_6 (6L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_7 (7L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_8 (8L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_9 (9L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_10 (10L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_11 (11L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_12 (12L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_13 (13L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_14 (14L<<0) #define BNX2_PCI_ID_VAL4_CAP_ENA_15 (15L<<0) #define BNX2_PCI_ID_VAL4_PM_SCALE_PRG (0x3L<<6) #define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_0 (0L<<6) #define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_1 (1L<<6) #define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_2 (2L<<6) #define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_3 (3L<<6) #define BNX2_PCI_ID_VAL4_MSI_LIMIT (0x7L<<9) #define BNX2_PCI_ID_VAL4_MSI_ADVERTIZE (0x7L<<12) #define BNX2_PCI_ID_VAL4_MSI_ENABLE (1L<<15) #define BNX2_PCI_ID_VAL4_MAX_64_ADVERTIZE (1L<<16) #define BNX2_PCI_ID_VAL4_MAX_133_ADVERTIZE (1L<<17) #define BNX2_PCI_ID_VAL4_MAX_MEM_READ_SIZE (0x3L<<21) #define BNX2_PCI_ID_VAL4_MAX_SPLIT_SIZE (0x7L<<23) #define BNX2_PCI_ID_VAL4_MAX_CUMULATIVE_SIZE (0x7L<<26) #define BNX2_PCI_ID_VAL5 0x00000444 #define BNX2_PCI_ID_VAL5_D1_SUPPORT (1L<<0) #define BNX2_PCI_ID_VAL5_D2_SUPPORT (1L<<1) #define BNX2_PCI_ID_VAL5_PME_IN_D0 (1L<<2) #define BNX2_PCI_ID_VAL5_PME_IN_D1 (1L<<3) #define BNX2_PCI_ID_VAL5_PME_IN_D2 (1L<<4) #define BNX2_PCI_ID_VAL5_PME_IN_D3_HOT (1L<<5) #define BNX2_PCI_PCIX_EXTENDED_STATUS 0x00000448 #define BNX2_PCI_PCIX_EXTENDED_STATUS_NO_SNOOP (1L<<8) #define BNX2_PCI_PCIX_EXTENDED_STATUS_LONG_BURST (1L<<9) #define BNX2_PCI_PCIX_EXTENDED_STATUS_SPLIT_COMP_MSG_CLASS (0xfL<<16) #define BNX2_PCI_PCIX_EXTENDED_STATUS_SPLIT_COMP_MSG_IDX (0xffL<<24) #define BNX2_PCI_ID_VAL6 0x0000044c #define BNX2_PCI_ID_VAL6_MAX_LAT (0xffL<<0) #define BNX2_PCI_ID_VAL6_MIN_GNT (0xffL<<8) #define BNX2_PCI_ID_VAL6_BIST (0xffL<<16) #define BNX2_PCI_MSI_DATA 0x00000450 #define BNX2_PCI_MSI_DATA_PCI_MSI_DATA (0xffffL<<0) #define BNX2_PCI_MSI_ADDR_H 0x00000454 #define BNX2_PCI_MSI_ADDR_L 0x00000458 /* * misc_reg definition * offset: 0x800 */ #define BNX2_MISC_COMMAND 0x00000800 #define BNX2_MISC_COMMAND_ENABLE_ALL (1L<<0) #define BNX2_MISC_COMMAND_DISABLE_ALL (1L<<1) #define BNX2_MISC_COMMAND_CORE_RESET (1L<<4) #define BNX2_MISC_COMMAND_HARD_RESET (1L<<5) #define BNX2_MISC_COMMAND_PAR_ERROR (1L<<8) #define BNX2_MISC_COMMAND_PAR_ERR_RAM (0x7fL<<16) #define BNX2_MISC_CFG 0x00000804 #define BNX2_MISC_CFG_PCI_GRC_TMOUT (1L<<0) #define BNX2_MISC_CFG_NVM_WR_EN (0x3L<<1) #define BNX2_MISC_CFG_NVM_WR_EN_PROTECT (0L<<1) #define BNX2_MISC_CFG_NVM_WR_EN_PCI (1L<<1) #define BNX2_MISC_CFG_NVM_WR_EN_ALLOW (2L<<1) #define BNX2_MISC_CFG_NVM_WR_EN_ALLOW2 (3L<<1) #define BNX2_MISC_CFG_BIST_EN (1L<<3) #define BNX2_MISC_CFG_CK25_OUT_ALT_SRC (1L<<4) #define BNX2_MISC_CFG_BYPASS_BSCAN (1L<<5) #define BNX2_MISC_CFG_BYPASS_EJTAG (1L<<6) #define BNX2_MISC_CFG_CLK_CTL_OVERRIDE (1L<<7) #define BNX2_MISC_CFG_LEDMODE (0x3L<<8) #define BNX2_MISC_CFG_LEDMODE_MAC (0L<<8) #define BNX2_MISC_CFG_LEDMODE_GPHY1 (1L<<8) #define BNX2_MISC_CFG_LEDMODE_GPHY2 (2L<<8) #define BNX2_MISC_ID 0x00000808 #define BNX2_MISC_ID_BOND_ID (0xfL<<0) #define BNX2_MISC_ID_CHIP_METAL (0xffL<<4) #define BNX2_MISC_ID_CHIP_REV (0xfL<<12) #define BNX2_MISC_ID_CHIP_NUM (0xffffL<<16) #define BNX2_MISC_ENABLE_STATUS_BITS 0x0000080c #define BNX2_MISC_ENABLE_STATUS_BITS_TX_SCHEDULER_ENABLE (1L<<0) #define BNX2_MISC_ENABLE_STATUS_BITS_TX_BD_READ_ENABLE (1L<<1) #define BNX2_MISC_ENABLE_STATUS_BITS_TX_BD_CACHE_ENABLE (1L<<2) #define BNX2_MISC_ENABLE_STATUS_BITS_TX_PROCESSOR_ENABLE (1L<<3) #define BNX2_MISC_ENABLE_STATUS_BITS_TX_DMA_ENABLE (1L<<4) #define BNX2_MISC_ENABLE_STATUS_BITS_TX_PATCHUP_ENABLE (1L<<5) #define BNX2_MISC_ENABLE_STATUS_BITS_TX_PAYLOAD_Q_ENABLE (1L<<6) #define BNX2_MISC_ENABLE_STATUS_BITS_TX_HEADER_Q_ENABLE (1L<<7) #define BNX2_MISC_ENABLE_STATUS_BITS_TX_ASSEMBLER_ENABLE (1L<<8) #define BNX2_MISC_ENABLE_STATUS_BITS_EMAC_ENABLE (1L<<9) #define BNX2_MISC_ENABLE_STATUS_BITS_RX_PARSER_MAC_ENABLE (1L<<10) #define BNX2_MISC_ENABLE_STATUS_BITS_RX_PARSER_CATCHUP_ENABLE (1L<<11) #define BNX2_MISC_ENABLE_STATUS_BITS_RX_MBUF_ENABLE (1L<<12) #define BNX2_MISC_ENABLE_STATUS_BITS_RX_LOOKUP_ENABLE (1L<<13) #define BNX2_MISC_ENABLE_STATUS_BITS_RX_PROCESSOR_ENABLE (1L<<14) #define BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE (1L<<15) #define BNX2_MISC_ENABLE_STATUS_BITS_RX_BD_CACHE_ENABLE (1L<<16) #define BNX2_MISC_ENABLE_STATUS_BITS_RX_DMA_ENABLE (1L<<17) #define BNX2_MISC_ENABLE_STATUS_BITS_COMPLETION_ENABLE (1L<<18) #define BNX2_MISC_ENABLE_STATUS_BITS_HOST_COALESCE_ENABLE (1L<<19) #define BNX2_MISC_ENABLE_STATUS_BITS_MAILBOX_QUEUE_ENABLE (1L<<20) #define BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE (1L<<21) #define BNX2_MISC_ENABLE_STATUS_BITS_CMD_SCHEDULER_ENABLE (1L<<22) #define BNX2_MISC_ENABLE_STATUS_BITS_CMD_PROCESSOR_ENABLE (1L<<23) #define BNX2_MISC_ENABLE_STATUS_BITS_MGMT_PROCESSOR_ENABLE (1L<<24) #define BNX2_MISC_ENABLE_STATUS_BITS_TIMER_ENABLE (1L<<25) #define BNX2_MISC_ENABLE_STATUS_BITS_DMA_ENGINE_ENABLE (1L<<26) #define BNX2_MISC_ENABLE_STATUS_BITS_UMP_ENABLE (1L<<27) #define BNX2_MISC_ENABLE_SET_BITS 0x00000810 #define BNX2_MISC_ENABLE_SET_BITS_TX_SCHEDULER_ENABLE (1L<<0) #define BNX2_MISC_ENABLE_SET_BITS_TX_BD_READ_ENABLE (1L<<1) #define BNX2_MISC_ENABLE_SET_BITS_TX_BD_CACHE_ENABLE (1L<<2) #define BNX2_MISC_ENABLE_SET_BITS_TX_PROCESSOR_ENABLE (1L<<3) #define BNX2_MISC_ENABLE_SET_BITS_TX_DMA_ENABLE (1L<<4) #define BNX2_MISC_ENABLE_SET_BITS_TX_PATCHUP_ENABLE (1L<<5) #define BNX2_MISC_ENABLE_SET_BITS_TX_PAYLOAD_Q_ENABLE (1L<<6) #define BNX2_MISC_ENABLE_SET_BITS_TX_HEADER_Q_ENABLE (1L<<7) #define BNX2_MISC_ENABLE_SET_BITS_TX_ASSEMBLER_ENABLE (1L<<8) #define BNX2_MISC_ENABLE_SET_BITS_EMAC_ENABLE (1L<<9) #define BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_MAC_ENABLE (1L<<10) #define BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_CATCHUP_ENABLE (1L<<11) #define BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE (1L<<12) #define BNX2_MISC_ENABLE_SET_BITS_RX_LOOKUP_ENABLE (1L<<13) #define BNX2_MISC_ENABLE_SET_BITS_RX_PROCESSOR_ENABLE (1L<<14) #define BNX2_MISC_ENABLE_SET_BITS_RX_V2P_ENABLE (1L<<15) #define BNX2_MISC_ENABLE_SET_BITS_RX_BD_CACHE_ENABLE (1L<<16) #define BNX2_MISC_ENABLE_SET_BITS_RX_DMA_ENABLE (1L<<17) #define BNX2_MISC_ENABLE_SET_BITS_COMPLETION_ENABLE (1L<<18) #define BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE (1L<<19) #define BNX2_MISC_ENABLE_SET_BITS_MAILBOX_QUEUE_ENABLE (1L<<20) #define BNX2_MISC_ENABLE_SET_BITS_CONTEXT_ENABLE (1L<<21) #define BNX2_MISC_ENABLE_SET_BITS_CMD_SCHEDULER_ENABLE (1L<<22) #define BNX2_MISC_ENABLE_SET_BITS_CMD_PROCESSOR_ENABLE (1L<<23) #define BNX2_MISC_ENABLE_SET_BITS_MGMT_PROCESSOR_ENABLE (1L<<24) #define BNX2_MISC_ENABLE_SET_BITS_TIMER_ENABLE (1L<<25) #define BNX2_MISC_ENABLE_SET_BITS_DMA_ENGINE_ENABLE (1L<<26) #define BNX2_MISC_ENABLE_SET_BITS_UMP_ENABLE (1L<<27) #define BNX2_MISC_ENABLE_CLR_BITS 0x00000814 #define BNX2_MISC_ENABLE_CLR_BITS_TX_SCHEDULER_ENABLE (1L<<0) #define BNX2_MISC_ENABLE_CLR_BITS_TX_BD_READ_ENABLE (1L<<1) #define BNX2_MISC_ENABLE_CLR_BITS_TX_BD_CACHE_ENABLE (1L<<2) #define BNX2_MISC_ENABLE_CLR_BITS_TX_PROCESSOR_ENABLE (1L<<3) #define BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE (1L<<4) #define BNX2_MISC_ENABLE_CLR_BITS_TX_PATCHUP_ENABLE (1L<<5) #define BNX2_MISC_ENABLE_CLR_BITS_TX_PAYLOAD_Q_ENABLE (1L<<6) #define BNX2_MISC_ENABLE_CLR_BITS_TX_HEADER_Q_ENABLE (1L<<7) #define BNX2_MISC_ENABLE_CLR_BITS_TX_ASSEMBLER_ENABLE (1L<<8) #define BNX2_MISC_ENABLE_CLR_BITS_EMAC_ENABLE (1L<<9) #define BNX2_MISC_ENABLE_CLR_BITS_RX_PARSER_MAC_ENABLE (1L<<10) #define BNX2_MISC_ENABLE_CLR_BITS_RX_PARSER_CATCHUP_ENABLE (1L<<11) #define BNX2_MISC_ENABLE_CLR_BITS_RX_MBUF_ENABLE (1L<<12) #define BNX2_MISC_ENABLE_CLR_BITS_RX_LOOKUP_ENABLE (1L<<13) #define BNX2_MISC_ENABLE_CLR_BITS_RX_PROCESSOR_ENABLE (1L<<14) #define BNX2_MISC_ENABLE_CLR_BITS_RX_V2P_ENABLE (1L<<15) #define BNX2_MISC_ENABLE_CLR_BITS_RX_BD_CACHE_ENABLE (1L<<16) #define BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE (1L<<17) #define BNX2_MISC_ENABLE_CLR_BITS_COMPLETION_ENABLE (1L<<18) #define BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE (1L<<19) #define BNX2_MISC_ENABLE_CLR_BITS_MAILBOX_QUEUE_ENABLE (1L<<20) #define BNX2_MISC_ENABLE_CLR_BITS_CONTEXT_ENABLE (1L<<21) #define BNX2_MISC_ENABLE_CLR_BITS_CMD_SCHEDULER_ENABLE (1L<<22) #define BNX2_MISC_ENABLE_CLR_BITS_CMD_PROCESSOR_ENABLE (1L<<23) #define BNX2_MISC_ENABLE_CLR_BITS_MGMT_PROCESSOR_ENABLE (1L<<24) #define BNX2_MISC_ENABLE_CLR_BITS_TIMER_ENABLE (1L<<25) #define BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE (1L<<26) #define BNX2_MISC_ENABLE_CLR_BITS_UMP_ENABLE (1L<<27) #define BNX2_MISC_CLOCK_CONTROL_BITS 0x00000818 #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET (0xfL<<0) #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ (0L<<0) #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ (1L<<0) #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ (2L<<0) #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ (3L<<0) #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ (4L<<0) #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ (5L<<0) #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ (6L<<0) #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ (7L<<0) #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW (0xfL<<0) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE (1L<<6) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT (1L<<7) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC (0x7L<<8) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_UNDEF (0L<<8) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12 (1L<<8) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_6 (2L<<8) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_62 (4L<<8) #define BNX2_MISC_CLOCK_CONTROL_BITS_PLAY_DEAD (1L<<11) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED (0xfL<<12) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_100 (0L<<12) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_80 (1L<<12) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_50 (2L<<12) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_40 (4L<<12) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_25 (8L<<12) #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_STOP (1L<<16) #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_PLL_STOP (1L<<17) #define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_18 (1L<<18) #define BNX2_MISC_CLOCK_CONTROL_BITS_USE_SPD_DET (1L<<19) #define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED (0xfffL<<20) #define BNX2_MISC_GPIO 0x0000081c #define BNX2_MISC_GPIO_VALUE (0xffL<<0) #define BNX2_MISC_GPIO_SET (0xffL<<8) #define BNX2_MISC_GPIO_CLR (0xffL<<16) #define BNX2_MISC_GPIO_FLOAT (0xffL<<24) #define BNX2_MISC_GPIO_INT 0x00000820 #define BNX2_MISC_GPIO_INT_INT_STATE (0xfL<<0) #define BNX2_MISC_GPIO_INT_OLD_VALUE (0xfL<<8) #define BNX2_MISC_GPIO_INT_OLD_SET (0xfL<<16) #define BNX2_MISC_GPIO_INT_OLD_CLR (0xfL<<24) #define BNX2_MISC_CONFIG_LFSR 0x00000824 #define BNX2_MISC_CONFIG_LFSR_DIV (0xffffL<<0) #define BNX2_MISC_LFSR_MASK_BITS 0x00000828 #define BNX2_MISC_LFSR_MASK_BITS_TX_SCHEDULER_ENABLE (1L<<0) #define BNX2_MISC_LFSR_MASK_BITS_TX_BD_READ_ENABLE (1L<<1) #define BNX2_MISC_LFSR_MASK_BITS_TX_BD_CACHE_ENABLE (1L<<2) #define BNX2_MISC_LFSR_MASK_BITS_TX_PROCESSOR_ENABLE (1L<<3) #define BNX2_MISC_LFSR_MASK_BITS_TX_DMA_ENABLE (1L<<4) #define BNX2_MISC_LFSR_MASK_BITS_TX_PATCHUP_ENABLE (1L<<5) #define BNX2_MISC_LFSR_MASK_BITS_TX_PAYLOAD_Q_ENABLE (1L<<6) #define BNX2_MISC_LFSR_MASK_BITS_TX_HEADER_Q_ENABLE (1L<<7) #define BNX2_MISC_LFSR_MASK_BITS_TX_ASSEMBLER_ENABLE (1L<<8) #define BNX2_MISC_LFSR_MASK_BITS_EMAC_ENABLE (1L<<9) #define BNX2_MISC_LFSR_MASK_BITS_RX_PARSER_MAC_ENABLE (1L<<10) #define BNX2_MISC_LFSR_MASK_BITS_RX_PARSER_CATCHUP_ENABLE (1L<<11) #define BNX2_MISC_LFSR_MASK_BITS_RX_MBUF_ENABLE (1L<<12) #define BNX2_MISC_LFSR_MASK_BITS_RX_LOOKUP_ENABLE (1L<<13) #define BNX2_MISC_LFSR_MASK_BITS_RX_PROCESSOR_ENABLE (1L<<14) #define BNX2_MISC_LFSR_MASK_BITS_RX_V2P_ENABLE (1L<<15) #define BNX2_MISC_LFSR_MASK_BITS_RX_BD_CACHE_ENABLE (1L<<16) #define BNX2_MISC_LFSR_MASK_BITS_RX_DMA_ENABLE (1L<<17) #define BNX2_MISC_LFSR_MASK_BITS_COMPLETION_ENABLE (1L<<18) #define BNX2_MISC_LFSR_MASK_BITS_HOST_COALESCE_ENABLE (1L<<19) #define BNX2_MISC_LFSR_MASK_BITS_MAILBOX_QUEUE_ENABLE (1L<<20) #define BNX2_MISC_LFSR_MASK_BITS_CONTEXT_ENABLE (1L<<21) #define BNX2_MISC_LFSR_MASK_BITS_CMD_SCHEDULER_ENABLE (1L<<22) #define BNX2_MISC_LFSR_MASK_BITS_CMD_PROCESSOR_ENABLE (1L<<23) #define BNX2_MISC_LFSR_MASK_BITS_MGMT_PROCESSOR_ENABLE (1L<<24) #define BNX2_MISC_LFSR_MASK_BITS_TIMER_ENABLE (1L<<25) #define BNX2_MISC_LFSR_MASK_BITS_DMA_ENGINE_ENABLE (1L<<26) #define BNX2_MISC_LFSR_MASK_BITS_UMP_ENABLE (1L<<27) #define BNX2_MISC_ARB_REQ0 0x0000082c #define BNX2_MISC_ARB_REQ1 0x00000830 #define BNX2_MISC_ARB_REQ2 0x00000834 #define BNX2_MISC_ARB_REQ3 0x00000838 #define BNX2_MISC_ARB_REQ4 0x0000083c #define BNX2_MISC_ARB_FREE0 0x00000840 #define BNX2_MISC_ARB_FREE1 0x00000844 #define BNX2_MISC_ARB_FREE2 0x00000848 #define BNX2_MISC_ARB_FREE3 0x0000084c #define BNX2_MISC_ARB_FREE4 0x00000850 #define BNX2_MISC_ARB_REQ_STATUS0 0x00000854 #define BNX2_MISC_ARB_REQ_STATUS1 0x00000858 #define BNX2_MISC_ARB_REQ_STATUS2 0x0000085c #define BNX2_MISC_ARB_REQ_STATUS3 0x00000860 #define BNX2_MISC_ARB_REQ_STATUS4 0x00000864 #define BNX2_MISC_ARB_GNT0 0x00000868 #define BNX2_MISC_ARB_GNT0_0 (0x7L<<0) #define BNX2_MISC_ARB_GNT0_1 (0x7L<<4) #define BNX2_MISC_ARB_GNT0_2 (0x7L<<8) #define BNX2_MISC_ARB_GNT0_3 (0x7L<<12) #define BNX2_MISC_ARB_GNT0_4 (0x7L<<16) #define BNX2_MISC_ARB_GNT0_5 (0x7L<<20) #define BNX2_MISC_ARB_GNT0_6 (0x7L<<24) #define BNX2_MISC_ARB_GNT0_7 (0x7L<<28) #define BNX2_MISC_ARB_GNT1 0x0000086c #define BNX2_MISC_ARB_GNT1_8 (0x7L<<0) #define BNX2_MISC_ARB_GNT1_9 (0x7L<<4) #define BNX2_MISC_ARB_GNT1_10 (0x7L<<8) #define BNX2_MISC_ARB_GNT1_11 (0x7L<<12) #define BNX2_MISC_ARB_GNT1_12 (0x7L<<16) #define BNX2_MISC_ARB_GNT1_13 (0x7L<<20) #define BNX2_MISC_ARB_GNT1_14 (0x7L<<24) #define BNX2_MISC_ARB_GNT1_15 (0x7L<<28) #define BNX2_MISC_ARB_GNT2 0x00000870 #define BNX2_MISC_ARB_GNT2_16 (0x7L<<0) #define BNX2_MISC_ARB_GNT2_17 (0x7L<<4) #define BNX2_MISC_ARB_GNT2_18 (0x7L<<8) #define BNX2_MISC_ARB_GNT2_19 (0x7L<<12) #define BNX2_MISC_ARB_GNT2_20 (0x7L<<16) #define BNX2_MISC_ARB_GNT2_21 (0x7L<<20) #define BNX2_MISC_ARB_GNT2_22 (0x7L<<24) #define BNX2_MISC_ARB_GNT2_23 (0x7L<<28) #define BNX2_MISC_ARB_GNT3 0x00000874 #define BNX2_MISC_ARB_GNT3_24 (0x7L<<0) #define BNX2_MISC_ARB_GNT3_25 (0x7L<<4) #define BNX2_MISC_ARB_GNT3_26 (0x7L<<8) #define BNX2_MISC_ARB_GNT3_27 (0x7L<<12) #define BNX2_MISC_ARB_GNT3_28 (0x7L<<16) #define BNX2_MISC_ARB_GNT3_29 (0x7L<<20) #define BNX2_MISC_ARB_GNT3_30 (0x7L<<24) #define BNX2_MISC_ARB_GNT3_31 (0x7L<<28) #define BNX2_MISC_PRBS_CONTROL 0x00000878 #define BNX2_MISC_PRBS_CONTROL_EN (1L<<0) #define BNX2_MISC_PRBS_CONTROL_RSTB (1L<<1) #define BNX2_MISC_PRBS_CONTROL_INV (1L<<2) #define BNX2_MISC_PRBS_CONTROL_ERR_CLR (1L<<3) #define BNX2_MISC_PRBS_CONTROL_ORDER (0x3L<<4) #define BNX2_MISC_PRBS_CONTROL_ORDER_7TH (0L<<4) #define BNX2_MISC_PRBS_CONTROL_ORDER_15TH (1L<<4) #define BNX2_MISC_PRBS_CONTROL_ORDER_23RD (2L<<4) #define BNX2_MISC_PRBS_CONTROL_ORDER_31ST (3L<<4) #define BNX2_MISC_PRBS_STATUS 0x0000087c #define BNX2_MISC_PRBS_STATUS_LOCK (1L<<0) #define BNX2_MISC_PRBS_STATUS_STKY (1L<<1) #define BNX2_MISC_PRBS_STATUS_ERRORS (0x3fffL<<2) #define BNX2_MISC_PRBS_STATUS_STATE (0xfL<<16) #define BNX2_MISC_SM_ASF_CONTROL 0x00000880 #define BNX2_MISC_SM_ASF_CONTROL_ASF_RST (1L<<0) #define BNX2_MISC_SM_ASF_CONTROL_TSC_EN (1L<<1) #define BNX2_MISC_SM_ASF_CONTROL_WG_TO (1L<<2) #define BNX2_MISC_SM_ASF_CONTROL_HB_TO (1L<<3) #define BNX2_MISC_SM_ASF_CONTROL_PA_TO (1L<<4) #define BNX2_MISC_SM_ASF_CONTROL_PL_TO (1L<<5) #define BNX2_MISC_SM_ASF_CONTROL_RT_TO (1L<<6) #define BNX2_MISC_SM_ASF_CONTROL_SMB_EVENT (1L<<7) #define BNX2_MISC_SM_ASF_CONTROL_RES (0xfL<<8) #define BNX2_MISC_SM_ASF_CONTROL_SMB_EN (1L<<12) #define BNX2_MISC_SM_ASF_CONTROL_SMB_BB_EN (1L<<13) #define BNX2_MISC_SM_ASF_CONTROL_SMB_NO_ADDR_FILT (1L<<14) #define BNX2_MISC_SM_ASF_CONTROL_SMB_AUTOREAD (1L<<15) #define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR1 (0x3fL<<16) #define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR2 (0x3fL<<24) #define BNX2_MISC_SM_ASF_CONTROL_EN_NIC_SMB_ADDR_0 (1L<<30) #define BNX2_MISC_SM_ASF_CONTROL_SMB_EARLY_ATTN (1L<<31) #define BNX2_MISC_SMB_IN 0x00000884 #define BNX2_MISC_SMB_IN_DAT_IN (0xffL<<0) #define BNX2_MISC_SMB_IN_RDY (1L<<8) #define BNX2_MISC_SMB_IN_DONE (1L<<9) #define BNX2_MISC_SMB_IN_FIRSTBYTE (1L<<10) #define BNX2_MISC_SMB_IN_STATUS (0x7L<<11) #define BNX2_MISC_SMB_IN_STATUS_OK (0x0L<<11) #define BNX2_MISC_SMB_IN_STATUS_PEC (0x1L<<11) #define BNX2_MISC_SMB_IN_STATUS_OFLOW (0x2L<<11) #define BNX2_MISC_SMB_IN_STATUS_STOP (0x3L<<11) #define BNX2_MISC_SMB_IN_STATUS_TIMEOUT (0x4L<<11) #define BNX2_MISC_SMB_OUT 0x00000888 #define BNX2_MISC_SMB_OUT_DAT_OUT (0xffL<<0) #define BNX2_MISC_SMB_OUT_RDY (1L<<8) #define BNX2_MISC_SMB_OUT_START (1L<<9) #define BNX2_MISC_SMB_OUT_LAST (1L<<10) #define BNX2_MISC_SMB_OUT_ACC_TYPE (1L<<11) #define BNX2_MISC_SMB_OUT_ENB_PEC (1L<<12) #define BNX2_MISC_SMB_OUT_GET_RX_LEN (1L<<13) #define BNX2_MISC_SMB_OUT_SMB_READ_LEN (0x3fL<<14) #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS (0xfL<<20) #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_OK (0L<<20) #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_FIRST_NACK (1L<<20) #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_SUB_NACK (9L<<20) #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_UFLOW (2L<<20) #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_STOP (3L<<20) #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_TIMEOUT (4L<<20) #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_FIRST_LOST (5L<<20) #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_SUB_LOST (0xdL<<20) #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_BADACK (0x6L<<20) #define BNX2_MISC_SMB_OUT_SMB_OUT_SLAVEMODE (1L<<24) #define BNX2_MISC_SMB_OUT_SMB_OUT_DAT_EN (1L<<25) #define BNX2_MISC_SMB_OUT_SMB_OUT_DAT_IN (1L<<26) #define BNX2_MISC_SMB_OUT_SMB_OUT_CLK_EN (1L<<27) #define BNX2_MISC_SMB_OUT_SMB_OUT_CLK_IN (1L<<28) #define BNX2_MISC_SMB_WATCHDOG 0x0000088c #define BNX2_MISC_SMB_WATCHDOG_WATCHDOG (0xffffL<<0) #define BNX2_MISC_SMB_HEARTBEAT 0x00000890 #define BNX2_MISC_SMB_HEARTBEAT_HEARTBEAT (0xffffL<<0) #define BNX2_MISC_SMB_POLL_ASF 0x00000894 #define BNX2_MISC_SMB_POLL_ASF_POLL_ASF (0xffffL<<0) #define BNX2_MISC_SMB_POLL_LEGACY 0x00000898 #define BNX2_MISC_SMB_POLL_LEGACY_POLL_LEGACY (0xffffL<<0) #define BNX2_MISC_SMB_RETRAN 0x0000089c #define BNX2_MISC_SMB_RETRAN_RETRAN (0xffL<<0) #define BNX2_MISC_SMB_TIMESTAMP 0x000008a0 #define BNX2_MISC_SMB_TIMESTAMP_TIMESTAMP (0xffffffffL<<0) #define BNX2_MISC_PERR_ENA0 0x000008a4 #define BNX2_MISC_PERR_ENA0_COM_MISC_CTXC (1L<<0) #define BNX2_MISC_PERR_ENA0_COM_MISC_REGF (1L<<1) #define BNX2_MISC_PERR_ENA0_COM_MISC_SCPAD (1L<<2) #define BNX2_MISC_PERR_ENA0_CP_MISC_CTXC (1L<<3) #define BNX2_MISC_PERR_ENA0_CP_MISC_REGF (1L<<4) #define BNX2_MISC_PERR_ENA0_CP_MISC_SCPAD (1L<<5) #define BNX2_MISC_PERR_ENA0_CS_MISC_TMEM (1L<<6) #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM0 (1L<<7) #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM1 (1L<<8) #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM2 (1L<<9) #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM3 (1L<<10) #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM4 (1L<<11) #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM5 (1L<<12) #define BNX2_MISC_PERR_ENA0_CTX_MISC_PGTBL (1L<<13) #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR0 (1L<<14) #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR1 (1L<<15) #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR2 (1L<<16) #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR3 (1L<<17) #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR4 (1L<<18) #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW0 (1L<<19) #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW1 (1L<<20) #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW2 (1L<<21) #define BNX2_MISC_PERR_ENA0_HC_MISC_DMA (1L<<22) #define BNX2_MISC_PERR_ENA0_MCP_MISC_REGF (1L<<23) #define BNX2_MISC_PERR_ENA0_MCP_MISC_SCPAD (1L<<24) #define BNX2_MISC_PERR_ENA0_MQ_MISC_CTX (1L<<25) #define BNX2_MISC_PERR_ENA0_RBDC_MISC (1L<<26) #define BNX2_MISC_PERR_ENA0_RBUF_MISC_MB (1L<<27) #define BNX2_MISC_PERR_ENA0_RBUF_MISC_PTR (1L<<28) #define BNX2_MISC_PERR_ENA0_RDE_MISC_RPC (1L<<29) #define BNX2_MISC_PERR_ENA0_RDE_MISC_RPM (1L<<30) #define BNX2_MISC_PERR_ENA0_RV2P_MISC_CB0REGS (1L<<31) #define BNX2_MISC_PERR_ENA1 0x000008a8 #define BNX2_MISC_PERR_ENA1_RV2P_MISC_CB1REGS (1L<<0) #define BNX2_MISC_PERR_ENA1_RV2P_MISC_P1IRAM (1L<<1) #define BNX2_MISC_PERR_ENA1_RV2P_MISC_P2IRAM (1L<<2) #define BNX2_MISC_PERR_ENA1_RXP_MISC_CTXC (1L<<3) #define BNX2_MISC_PERR_ENA1_RXP_MISC_REGF (1L<<4) #define BNX2_MISC_PERR_ENA1_RXP_MISC_SCPAD (1L<<5) #define BNX2_MISC_PERR_ENA1_RXP_MISC_RBUFC (1L<<6) #define BNX2_MISC_PERR_ENA1_TBDC_MISC (1L<<7) #define BNX2_MISC_PERR_ENA1_TDMA_MISC (1L<<8) #define BNX2_MISC_PERR_ENA1_THBUF_MISC_MB0 (1L<<9) #define BNX2_MISC_PERR_ENA1_THBUF_MISC_MB1 (1L<<10) #define BNX2_MISC_PERR_ENA1_TPAT_MISC_REGF (1L<<11) #define BNX2_MISC_PERR_ENA1_TPAT_MISC_SCPAD (1L<<12) #define BNX2_MISC_PERR_ENA1_TPBUF_MISC_MB (1L<<13) #define BNX2_MISC_PERR_ENA1_TSCH_MISC_LR (1L<<14) #define BNX2_MISC_PERR_ENA1_TXP_MISC_CTXC (1L<<15) #define BNX2_MISC_PERR_ENA1_TXP_MISC_REGF (1L<<16) #define BNX2_MISC_PERR_ENA1_TXP_MISC_SCPAD (1L<<17) #define BNX2_MISC_PERR_ENA1_UMP_MISC_FIORX (1L<<18) #define BNX2_MISC_PERR_ENA1_UMP_MISC_FIOTX (1L<<19) #define BNX2_MISC_PERR_ENA1_UMP_MISC_RX (1L<<20) #define BNX2_MISC_PERR_ENA1_UMP_MISC_TX (1L<<21) #define BNX2_MISC_PERR_ENA1_RDMAQ_MISC (1L<<22) #define BNX2_MISC_PERR_ENA1_CSQ_MISC (1L<<23) #define BNX2_MISC_PERR_ENA1_CPQ_MISC (1L<<24) #define BNX2_MISC_PERR_ENA1_MCPQ_MISC (1L<<25) #define BNX2_MISC_PERR_ENA1_RV2PMQ_MISC (1L<<26) #define BNX2_MISC_PERR_ENA1_RV2PPQ_MISC (1L<<27) #define BNX2_MISC_PERR_ENA1_RV2PTQ_MISC (1L<<28) #define BNX2_MISC_PERR_ENA1_RXPQ_MISC (1L<<29) #define BNX2_MISC_PERR_ENA1_RXPCQ_MISC (1L<<30) #define BNX2_MISC_PERR_ENA1_RLUPQ_MISC (1L<<31) #define BNX2_MISC_PERR_ENA2 0x000008ac #define BNX2_MISC_PERR_ENA2_COMQ_MISC (1L<<0) #define BNX2_MISC_PERR_ENA2_COMXQ_MISC (1L<<1) #define BNX2_MISC_PERR_ENA2_COMTQ_MISC (1L<<2) #define BNX2_MISC_PERR_ENA2_TSCHQ_MISC (1L<<3) #define BNX2_MISC_PERR_ENA2_TBDRQ_MISC (1L<<4) #define BNX2_MISC_PERR_ENA2_TXPQ_MISC (1L<<5) #define BNX2_MISC_PERR_ENA2_TDMAQ_MISC (1L<<6) #define BNX2_MISC_PERR_ENA2_TPATQ_MISC (1L<<7) #define BNX2_MISC_PERR_ENA2_TASQ_MISC (1L<<8) #define BNX2_MISC_DEBUG_VECTOR_SEL 0x000008b0 #define BNX2_MISC_DEBUG_VECTOR_SEL_0 (0xfffL<<0) #define BNX2_MISC_DEBUG_VECTOR_SEL_1 (0xfffL<<12) #define BNX2_MISC_VREG_CONTROL 0x000008b4 #define BNX2_MISC_VREG_CONTROL_1_2 (0xfL<<0) #define BNX2_MISC_VREG_CONTROL_2_5 (0xfL<<4) #define BNX2_MISC_FINAL_CLK_CTL_VAL 0x000008b8 #define BNX2_MISC_FINAL_CLK_CTL_VAL_MISC_FINAL_CLK_CTL_VAL (0x3ffffffL<<6) #define BNX2_MISC_UNUSED0 0x000008bc /* * nvm_reg definition * offset: 0x6400 */ #define BNX2_NVM_COMMAND 0x00006400 #define BNX2_NVM_COMMAND_RST (1L<<0) #define BNX2_NVM_COMMAND_DONE (1L<<3) #define BNX2_NVM_COMMAND_DOIT (1L<<4) #define BNX2_NVM_COMMAND_WR (1L<<5) #define BNX2_NVM_COMMAND_ERASE (1L<<6) #define BNX2_NVM_COMMAND_FIRST (1L<<7) #define BNX2_NVM_COMMAND_LAST (1L<<8) #define BNX2_NVM_COMMAND_WREN (1L<<16) #define BNX2_NVM_COMMAND_WRDI (1L<<17) #define BNX2_NVM_COMMAND_EWSR (1L<<18) #define BNX2_NVM_COMMAND_WRSR (1L<<19) #define BNX2_NVM_STATUS 0x00006404 #define BNX2_NVM_STATUS_PI_FSM_STATE (0xfL<<0) #define BNX2_NVM_STATUS_EE_FSM_STATE (0xfL<<4) #define BNX2_NVM_STATUS_EQ_FSM_STATE (0xfL<<8) #define BNX2_NVM_WRITE 0x00006408 #define BNX2_NVM_WRITE_NVM_WRITE_VALUE (0xffffffffL<<0) #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_BIT_BANG (0L<<0) #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_EECLK (1L<<0) #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_EEDATA (2L<<0) #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SCLK (4L<<0) #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_CS_B (8L<<0) #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SO (16L<<0) #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SI (32L<<0) #define BNX2_NVM_ADDR 0x0000640c #define BNX2_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0) #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_BIT_BANG (0L<<0) #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_EECLK (1L<<0) #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_EEDATA (2L<<0) #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SCLK (4L<<0) #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_CS_B (8L<<0) #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SO (16L<<0) #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SI (32L<<0) #define BNX2_NVM_READ 0x00006410 #define BNX2_NVM_READ_NVM_READ_VALUE (0xffffffffL<<0) #define BNX2_NVM_READ_NVM_READ_VALUE_BIT_BANG (0L<<0) #define BNX2_NVM_READ_NVM_READ_VALUE_EECLK (1L<<0) #define BNX2_NVM_READ_NVM_READ_VALUE_EEDATA (2L<<0) #define BNX2_NVM_READ_NVM_READ_VALUE_SCLK (4L<<0) #define BNX2_NVM_READ_NVM_READ_VALUE_CS_B (8L<<0) #define BNX2_NVM_READ_NVM_READ_VALUE_SO (16L<<0) #define BNX2_NVM_READ_NVM_READ_VALUE_SI (32L<<0) #define BNX2_NVM_CFG1 0x00006414 #define BNX2_NVM_CFG1_FLASH_MODE (1L<<0) #define BNX2_NVM_CFG1_BUFFER_MODE (1L<<1) #define BNX2_NVM_CFG1_PASS_MODE (1L<<2) #define BNX2_NVM_CFG1_BITBANG_MODE (1L<<3) #define BNX2_NVM_CFG1_STATUS_BIT (0x7L<<4) #define BNX2_NVM_CFG1_STATUS_BIT_FLASH_RDY (0L<<4) #define BNX2_NVM_CFG1_STATUS_BIT_BUFFER_RDY (7L<<4) #define BNX2_NVM_CFG1_SPI_CLK_DIV (0xfL<<7) #define BNX2_NVM_CFG1_SEE_CLK_DIV (0x7ffL<<11) #define BNX2_NVM_CFG1_PROTECT_MODE (1L<<24) #define BNX2_NVM_CFG1_FLASH_SIZE (1L<<25) #define BNX2_NVM_CFG1_COMPAT_BYPASSS (1L<<31) #define BNX2_NVM_CFG2 0x00006418 #define BNX2_NVM_CFG2_ERASE_CMD (0xffL<<0) #define BNX2_NVM_CFG2_DUMMY (0xffL<<8) #define BNX2_NVM_CFG2_STATUS_CMD (0xffL<<16) #define BNX2_NVM_CFG3 0x0000641c #define BNX2_NVM_CFG3_BUFFER_RD_CMD (0xffL<<0) #define BNX2_NVM_CFG3_WRITE_CMD (0xffL<<8) #define BNX2_NVM_CFG3_BUFFER_WRITE_CMD (0xffL<<16) #define BNX2_NVM_CFG3_READ_CMD (0xffL<<24) #define BNX2_NVM_SW_ARB 0x00006420 #define BNX2_NVM_SW_ARB_ARB_REQ_SET0 (1L<<0) #define BNX2_NVM_SW_ARB_ARB_REQ_SET1 (1L<<1) #define BNX2_NVM_SW_ARB_ARB_REQ_SET2 (1L<<2) #define BNX2_NVM_SW_ARB_ARB_REQ_SET3 (1L<<3) #define BNX2_NVM_SW_ARB_ARB_REQ_CLR0 (1L<<4) #define BNX2_NVM_SW_ARB_ARB_REQ_CLR1 (1L<<5) #define BNX2_NVM_SW_ARB_ARB_REQ_CLR2 (1L<<6) #define BNX2_NVM_SW_ARB_ARB_REQ_CLR3 (1L<<7) #define BNX2_NVM_SW_ARB_ARB_ARB0 (1L<<8) #define BNX2_NVM_SW_ARB_ARB_ARB1 (1L<<9) #define BNX2_NVM_SW_ARB_ARB_ARB2 (1L<<10) #define BNX2_NVM_SW_ARB_ARB_ARB3 (1L<<11) #define BNX2_NVM_SW_ARB_REQ0 (1L<<12) #define BNX2_NVM_SW_ARB_REQ1 (1L<<13) #define BNX2_NVM_SW_ARB_REQ2 (1L<<14) #define BNX2_NVM_SW_ARB_REQ3 (1L<<15) #define BNX2_NVM_ACCESS_ENABLE 0x00006424 #define BNX2_NVM_ACCESS_ENABLE_EN (1L<<0) #define BNX2_NVM_ACCESS_ENABLE_WR_EN (1L<<1) #define BNX2_NVM_WRITE1 0x00006428 #define BNX2_NVM_WRITE1_WREN_CMD (0xffL<<0) #define BNX2_NVM_WRITE1_WRDI_CMD (0xffL<<8) #define BNX2_NVM_WRITE1_SR_DATA (0xffL<<16) /* * dma_reg definition * offset: 0xc00 */ #define BNX2_DMA_COMMAND 0x00000c00 #define BNX2_DMA_COMMAND_ENABLE (1L<<0) #define BNX2_DMA_STATUS 0x00000c04 #define BNX2_DMA_STATUS_PAR_ERROR_STATE (1L<<0) #define BNX2_DMA_STATUS_READ_TRANSFERS_STAT (1L<<16) #define BNX2_DMA_STATUS_READ_DELAY_PCI_CLKS_STAT (1L<<17) #define BNX2_DMA_STATUS_BIG_READ_TRANSFERS_STAT (1L<<18) #define BNX2_DMA_STATUS_BIG_READ_DELAY_PCI_CLKS_STAT (1L<<19) #define BNX2_DMA_STATUS_BIG_READ_RETRY_AFTER_DATA_STAT (1L<<20) #define BNX2_DMA_STATUS_WRITE_TRANSFERS_STAT (1L<<21) #define BNX2_DMA_STATUS_WRITE_DELAY_PCI_CLKS_STAT (1L<<22) #define BNX2_DMA_STATUS_BIG_WRITE_TRANSFERS_STAT (1L<<23) #define BNX2_DMA_STATUS_BIG_WRITE_DELAY_PCI_CLKS_STAT (1L<<24) #define BNX2_DMA_STATUS_BIG_WRITE_RETRY_AFTER_DATA_STAT (1L<<25) #define BNX2_DMA_CONFIG 0x00000c08 #define BNX2_DMA_CONFIG_DATA_BYTE_SWAP (1L<<0) #define BNX2_DMA_CONFIG_DATA_WORD_SWAP (1L<<1) #define BNX2_DMA_CONFIG_CNTL_BYTE_SWAP (1L<<4) #define BNX2_DMA_CONFIG_CNTL_WORD_SWAP (1L<<5) #define BNX2_DMA_CONFIG_ONE_DMA (1L<<6) #define BNX2_DMA_CONFIG_CNTL_TWO_DMA (1L<<7) #define BNX2_DMA_CONFIG_CNTL_FPGA_MODE (1L<<8) #define BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA (1L<<10) #define BNX2_DMA_CONFIG_CNTL_PCI_COMP_DLY (1L<<11) #define BNX2_DMA_CONFIG_NO_RCHANS_IN_USE (0xfL<<12) #define BNX2_DMA_CONFIG_NO_WCHANS_IN_USE (0xfL<<16) #define BNX2_DMA_CONFIG_PCI_CLK_CMP_BITS (0x7L<<20) #define BNX2_DMA_CONFIG_PCI_FAST_CLK_CMP (1L<<23) #define BNX2_DMA_CONFIG_BIG_SIZE (0xfL<<24) #define BNX2_DMA_CONFIG_BIG_SIZE_NONE (0x0L<<24) #define BNX2_DMA_CONFIG_BIG_SIZE_64 (0x1L<<24) #define BNX2_DMA_CONFIG_BIG_SIZE_128 (0x2L<<24) #define BNX2_DMA_CONFIG_BIG_SIZE_256 (0x4L<<24) #define BNX2_DMA_CONFIG_BIG_SIZE_512 (0x8L<<24) #define BNX2_DMA_BLACKOUT 0x00000c0c #define BNX2_DMA_BLACKOUT_RD_RETRY_BLACKOUT (0xffL<<0) #define BNX2_DMA_BLACKOUT_2ND_RD_RETRY_BLACKOUT (0xffL<<8) #define BNX2_DMA_BLACKOUT_WR_RETRY_BLACKOUT (0xffL<<16) #define BNX2_DMA_RCHAN_STAT 0x00000c30 #define BNX2_DMA_RCHAN_STAT_COMP_CODE_0 (0x7L<<0) #define BNX2_DMA_RCHAN_STAT_PAR_ERR_0 (1L<<3) #define BNX2_DMA_RCHAN_STAT_COMP_CODE_1 (0x7L<<4) #define BNX2_DMA_RCHAN_STAT_PAR_ERR_1 (1L<<7) #define BNX2_DMA_RCHAN_STAT_COMP_CODE_2 (0x7L<<8) #define BNX2_DMA_RCHAN_STAT_PAR_ERR_2 (1L<<11) #define BNX2_DMA_RCHAN_STAT_COMP_CODE_3 (0x7L<<12) #define BNX2_DMA_RCHAN_STAT_PAR_ERR_3 (1L<<15) #define BNX2_DMA_RCHAN_STAT_COMP_CODE_4 (0x7L<<16) #define BNX2_DMA_RCHAN_STAT_PAR_ERR_4 (1L<<19) #define BNX2_DMA_RCHAN_STAT_COMP_CODE_5 (0x7L<<20) #define BNX2_DMA_RCHAN_STAT_PAR_ERR_5 (1L<<23) #define BNX2_DMA_RCHAN_STAT_COMP_CODE_6 (0x7L<<24) #define BNX2_DMA_RCHAN_STAT_PAR_ERR_6 (1L<<27) #define BNX2_DMA_RCHAN_STAT_COMP_CODE_7 (0x7L<<28) #define BNX2_DMA_RCHAN_STAT_PAR_ERR_7 (1L<<31) #define BNX2_DMA_WCHAN_STAT 0x00000c34 #define BNX2_DMA_WCHAN_STAT_COMP_CODE_0 (0x7L<<0) #define BNX2_DMA_WCHAN_STAT_PAR_ERR_0 (1L<<3) #define BNX2_DMA_WCHAN_STAT_COMP_CODE_1 (0x7L<<4) #define BNX2_DMA_WCHAN_STAT_PAR_ERR_1 (1L<<7) #define BNX2_DMA_WCHAN_STAT_COMP_CODE_2 (0x7L<<8) #define BNX2_DMA_WCHAN_STAT_PAR_ERR_2 (1L<<11) #define BNX2_DMA_WCHAN_STAT_COMP_CODE_3 (0x7L<<12) #define BNX2_DMA_WCHAN_STAT_PAR_ERR_3 (1L<<15) #define BNX2_DMA_WCHAN_STAT_COMP_CODE_4 (0x7L<<16) #define BNX2_DMA_WCHAN_STAT_PAR_ERR_4 (1L<<19) #define BNX2_DMA_WCHAN_STAT_COMP_CODE_5 (0x7L<<20) #define BNX2_DMA_WCHAN_STAT_PAR_ERR_5 (1L<<23) #define BNX2_DMA_WCHAN_STAT_COMP_CODE_6 (0x7L<<24) #define BNX2_DMA_WCHAN_STAT_PAR_ERR_6 (1L<<27) #define BNX2_DMA_WCHAN_STAT_COMP_CODE_7 (0x7L<<28) #define BNX2_DMA_WCHAN_STAT_PAR_ERR_7 (1L<<31) #define BNX2_DMA_RCHAN_ASSIGNMENT 0x00000c38 #define BNX2_DMA_RCHAN_ASSIGNMENT_0 (0xfL<<0) #define BNX2_DMA_RCHAN_ASSIGNMENT_1 (0xfL<<4) #define BNX2_DMA_RCHAN_ASSIGNMENT_2 (0xfL<<8) #define BNX2_DMA_RCHAN_ASSIGNMENT_3 (0xfL<<12) #define BNX2_DMA_RCHAN_ASSIGNMENT_4 (0xfL<<16) #define BNX2_DMA_RCHAN_ASSIGNMENT_5 (0xfL<<20) #define BNX2_DMA_RCHAN_ASSIGNMENT_6 (0xfL<<24) #define BNX2_DMA_RCHAN_ASSIGNMENT_7 (0xfL<<28) #define BNX2_DMA_WCHAN_ASSIGNMENT 0x00000c3c #define BNX2_DMA_WCHAN_ASSIGNMENT_0 (0xfL<<0) #define BNX2_DMA_WCHAN_ASSIGNMENT_1 (0xfL<<4) #define BNX2_DMA_WCHAN_ASSIGNMENT_2 (0xfL<<8) #define BNX2_DMA_WCHAN_ASSIGNMENT_3 (0xfL<<12) #define BNX2_DMA_WCHAN_ASSIGNMENT_4 (0xfL<<16) #define BNX2_DMA_WCHAN_ASSIGNMENT_5 (0xfL<<20) #define BNX2_DMA_WCHAN_ASSIGNMENT_6 (0xfL<<24) #define BNX2_DMA_WCHAN_ASSIGNMENT_7 (0xfL<<28) #define BNX2_DMA_RCHAN_STAT_00 0x00000c40 #define BNX2_DMA_RCHAN_STAT_00_RCHAN_STA_HOST_ADDR_LOW (0xffffffffL<<0) #define BNX2_DMA_RCHAN_STAT_01 0x00000c44 #define BNX2_DMA_RCHAN_STAT_01_RCHAN_STA_HOST_ADDR_HIGH (0xffffffffL<<0) #define BNX2_DMA_RCHAN_STAT_02 0x00000c48 #define BNX2_DMA_RCHAN_STAT_02_LENGTH (0xffffL<<0) #define BNX2_DMA_RCHAN_STAT_02_WORD_SWAP (1L<<16) #define BNX2_DMA_RCHAN_STAT_02_BYTE_SWAP (1L<<17) #define BNX2_DMA_RCHAN_STAT_02_PRIORITY_LVL (1L<<18) #define BNX2_DMA_RCHAN_STAT_10 0x00000c4c #define BNX2_DMA_RCHAN_STAT_11 0x00000c50 #define BNX2_DMA_RCHAN_STAT_12 0x00000c54 #define BNX2_DMA_RCHAN_STAT_20 0x00000c58 #define BNX2_DMA_RCHAN_STAT_21 0x00000c5c #define BNX2_DMA_RCHAN_STAT_22 0x00000c60 #define BNX2_DMA_RCHAN_STAT_30 0x00000c64 #define BNX2_DMA_RCHAN_STAT_31 0x00000c68 #define BNX2_DMA_RCHAN_STAT_32 0x00000c6c #define BNX2_DMA_RCHAN_STAT_40 0x00000c70 #define BNX2_DMA_RCHAN_STAT_41 0x00000c74 #define BNX2_DMA_RCHAN_STAT_42 0x00000c78 #define BNX2_DMA_RCHAN_STAT_50 0x00000c7c #define BNX2_DMA_RCHAN_STAT_51 0x00000c80 #define BNX2_DMA_RCHAN_STAT_52 0x00000c84 #define BNX2_DMA_RCHAN_STAT_60 0x00000c88 #define BNX2_DMA_RCHAN_STAT_61 0x00000c8c #define BNX2_DMA_RCHAN_STAT_62 0x00000c90 #define BNX2_DMA_RCHAN_STAT_70 0x00000c94 #define BNX2_DMA_RCHAN_STAT_71 0x00000c98 #define BNX2_DMA_RCHAN_STAT_72 0x00000c9c #define BNX2_DMA_WCHAN_STAT_00 0x00000ca0 #define BNX2_DMA_WCHAN_STAT_00_WCHAN_STA_HOST_ADDR_LOW (0xffffffffL<<0) #define BNX2_DMA_WCHAN_STAT_01 0x00000ca4 #define BNX2_DMA_WCHAN_STAT_01_WCHAN_STA_HOST_ADDR_HIGH (0xffffffffL<<0) #define BNX2_DMA_WCHAN_STAT_02 0x00000ca8 #define BNX2_DMA_WCHAN_STAT_02_LENGTH (0xffffL<<0) #define BNX2_DMA_WCHAN_STAT_02_WORD_SWAP (1L<<16) #define BNX2_DMA_WCHAN_STAT_02_BYTE_SWAP (1L<<17) #define BNX2_DMA_WCHAN_STAT_02_PRIORITY_LVL (1L<<18) #define BNX2_DMA_WCHAN_STAT_10 0x00000cac #define BNX2_DMA_WCHAN_STAT_11 0x00000cb0 #define BNX2_DMA_WCHAN_STAT_12 0x00000cb4 #define BNX2_DMA_WCHAN_STAT_20 0x00000cb8 #define BNX2_DMA_WCHAN_STAT_21 0x00000cbc #define BNX2_DMA_WCHAN_STAT_22 0x00000cc0 #define BNX2_DMA_WCHAN_STAT_30 0x00000cc4 #define BNX2_DMA_WCHAN_STAT_31 0x00000cc8 #define BNX2_DMA_WCHAN_STAT_32 0x00000ccc #define BNX2_DMA_WCHAN_STAT_40 0x00000cd0 #define BNX2_DMA_WCHAN_STAT_41 0x00000cd4 #define BNX2_DMA_WCHAN_STAT_42 0x00000cd8 #define BNX2_DMA_WCHAN_STAT_50 0x00000cdc #define BNX2_DMA_WCHAN_STAT_51 0x00000ce0 #define BNX2_DMA_WCHAN_STAT_52 0x00000ce4 #define BNX2_DMA_WCHAN_STAT_60 0x00000ce8 #define BNX2_DMA_WCHAN_STAT_61 0x00000cec #define BNX2_DMA_WCHAN_STAT_62 0x00000cf0 #define BNX2_DMA_WCHAN_STAT_70 0x00000cf4 #define BNX2_DMA_WCHAN_STAT_71 0x00000cf8 #define BNX2_DMA_WCHAN_STAT_72 0x00000cfc #define BNX2_DMA_ARB_STAT_00 0x00000d00 #define BNX2_DMA_ARB_STAT_00_MASTER (0xffffL<<0) #define BNX2_DMA_ARB_STAT_00_MASTER_ENC (0xffL<<16) #define BNX2_DMA_ARB_STAT_00_CUR_BINMSTR (0xffL<<24) #define BNX2_DMA_ARB_STAT_01 0x00000d04 #define BNX2_DMA_ARB_STAT_01_LPR_RPTR (0xfL<<0) #define BNX2_DMA_ARB_STAT_01_LPR_WPTR (0xfL<<4) #define BNX2_DMA_ARB_STAT_01_LPB_RPTR (0xfL<<8) #define BNX2_DMA_ARB_STAT_01_LPB_WPTR (0xfL<<12) #define BNX2_DMA_ARB_STAT_01_HPR_RPTR (0xfL<<16) #define BNX2_DMA_ARB_STAT_01_HPR_WPTR (0xfL<<20) #define BNX2_DMA_ARB_STAT_01_HPB_RPTR (0xfL<<24) #define BNX2_DMA_ARB_STAT_01_HPB_WPTR (0xfL<<28) #define BNX2_DMA_FUSE_CTRL0_CMD 0x00000f00 #define BNX2_DMA_FUSE_CTRL0_CMD_PWRUP_DONE (1L<<0) #define BNX2_DMA_FUSE_CTRL0_CMD_SHIFT_DONE (1L<<1) #define BNX2_DMA_FUSE_CTRL0_CMD_SHIFT (1L<<2) #define BNX2_DMA_FUSE_CTRL0_CMD_LOAD (1L<<3) #define BNX2_DMA_FUSE_CTRL0_CMD_SEL (0xfL<<8) #define BNX2_DMA_FUSE_CTRL0_DATA 0x00000f04 #define BNX2_DMA_FUSE_CTRL1_CMD 0x00000f08 #define BNX2_DMA_FUSE_CTRL1_CMD_PWRUP_DONE (1L<<0) #define BNX2_DMA_FUSE_CTRL1_CMD_SHIFT_DONE (1L<<1) #define BNX2_DMA_FUSE_CTRL1_CMD_SHIFT (1L<<2) #define BNX2_DMA_FUSE_CTRL1_CMD_LOAD (1L<<3) #define BNX2_DMA_FUSE_CTRL1_CMD_SEL (0xfL<<8) #define BNX2_DMA_FUSE_CTRL1_DATA 0x00000f0c #define BNX2_DMA_FUSE_CTRL2_CMD 0x00000f10 #define BNX2_DMA_FUSE_CTRL2_CMD_PWRUP_DONE (1L<<0) #define BNX2_DMA_FUSE_CTRL2_CMD_SHIFT_DONE (1L<<1) #define BNX2_DMA_FUSE_CTRL2_CMD_SHIFT (1L<<2) #define BNX2_DMA_FUSE_CTRL2_CMD_LOAD (1L<<3) #define BNX2_DMA_FUSE_CTRL2_CMD_SEL (0xfL<<8) #define BNX2_DMA_FUSE_CTRL2_DATA 0x00000f14 /* * context_reg definition * offset: 0x1000 */ #define BNX2_CTX_COMMAND 0x00001000 #define BNX2_CTX_COMMAND_ENABLED (1L<<0) #define BNX2_CTX_STATUS 0x00001004 #define BNX2_CTX_STATUS_LOCK_WAIT (1L<<0) #define BNX2_CTX_STATUS_READ_STAT (1L<<16) #define BNX2_CTX_STATUS_WRITE_STAT (1L<<17) #define BNX2_CTX_STATUS_ACC_STALL_STAT (1L<<18) #define BNX2_CTX_STATUS_LOCK_STALL_STAT (1L<<19) #define BNX2_CTX_VIRT_ADDR 0x00001008 #define BNX2_CTX_VIRT_ADDR_VIRT_ADDR (0x7fffL<<6) #define BNX2_CTX_PAGE_TBL 0x0000100c #define BNX2_CTX_PAGE_TBL_PAGE_TBL (0x3fffL<<6) #define BNX2_CTX_DATA_ADR 0x00001010 #define BNX2_CTX_DATA_ADR_DATA_ADR (0x7ffffL<<2) #define BNX2_CTX_DATA 0x00001014 #define BNX2_CTX_LOCK 0x00001018 #define BNX2_CTX_LOCK_TYPE (0x7L<<0) #define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_VOID (0x0L<<0) #define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_COMPLETE (0x7L<<0) #define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_PROTOCOL (0x1L<<0) #define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_TX (0x2L<<0) #define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_TIMER (0x4L<<0) #define BNX2_CTX_LOCK_CID_VALUE (0x3fffL<<7) #define BNX2_CTX_LOCK_GRANTED (1L<<26) #define BNX2_CTX_LOCK_MODE (0x7L<<27) #define BNX2_CTX_LOCK_MODE_UNLOCK (0x0L<<27) #define BNX2_CTX_LOCK_MODE_IMMEDIATE (0x1L<<27) #define BNX2_CTX_LOCK_MODE_SURE (0x2L<<27) #define BNX2_CTX_LOCK_STATUS (1L<<30) #define BNX2_CTX_LOCK_REQ (1L<<31) #define BNX2_CTX_ACCESS_STATUS 0x00001040 #define BNX2_CTX_ACCESS_STATUS_MASTERENCODED (0xfL<<0) #define BNX2_CTX_ACCESS_STATUS_ACCESSMEMORYSM (0x3L<<10) #define BNX2_CTX_ACCESS_STATUS_PAGETABLEINITSM (0x3L<<12) #define BNX2_CTX_ACCESS_STATUS_ACCESSMEMORYINITSM (0x3L<<14) #define BNX2_CTX_ACCESS_STATUS_QUALIFIED_REQUEST (0x7ffL<<17) #define BNX2_CTX_DBG_LOCK_STATUS 0x00001044 #define BNX2_CTX_DBG_LOCK_STATUS_SM (0x3ffL<<0) #define BNX2_CTX_DBG_LOCK_STATUS_MATCH (0x3ffL<<22) #define BNX2_CTX_CHNL_LOCK_STATUS_0 0x00001080 #define BNX2_CTX_CHNL_LOCK_STATUS_0_CID (0x3fffL<<0) #define BNX2_CTX_CHNL_LOCK_STATUS_0_TYPE (0x3L<<14) #define BNX2_CTX_CHNL_LOCK_STATUS_0_MODE (1L<<16) #define BNX2_CTX_CHNL_LOCK_STATUS_1 0x00001084 #define BNX2_CTX_CHNL_LOCK_STATUS_2 0x00001088 #define BNX2_CTX_CHNL_LOCK_STATUS_3 0x0000108c #define BNX2_CTX_CHNL_LOCK_STATUS_4 0x00001090 #define BNX2_CTX_CHNL_LOCK_STATUS_5 0x00001094 #define BNX2_CTX_CHNL_LOCK_STATUS_6 0x00001098 #define BNX2_CTX_CHNL_LOCK_STATUS_7 0x0000109c #define BNX2_CTX_CHNL_LOCK_STATUS_8 0x000010a0 /* * emac_reg definition * offset: 0x1400 */ #define BNX2_EMAC_MODE 0x00001400 #define BNX2_EMAC_MODE_RESET (1L<<0) #define BNX2_EMAC_MODE_HALF_DUPLEX (1L<<1) #define BNX2_EMAC_MODE_PORT (0x3L<<2) #define BNX2_EMAC_MODE_PORT_NONE (0L<<2) #define BNX2_EMAC_MODE_PORT_MII (1L<<2) #define BNX2_EMAC_MODE_PORT_GMII (2L<<2) #define BNX2_EMAC_MODE_PORT_MII_10 (3L<<2) #define BNX2_EMAC_MODE_MAC_LOOP (1L<<4) #define BNX2_EMAC_MODE_25G (1L<<5) #define BNX2_EMAC_MODE_TAGGED_MAC_CTL (1L<<7) #define BNX2_EMAC_MODE_TX_BURST (1L<<8) #define BNX2_EMAC_MODE_MAX_DEFER_DROP_ENA (1L<<9) #define BNX2_EMAC_MODE_EXT_LINK_POL (1L<<10) #define BNX2_EMAC_MODE_FORCE_LINK (1L<<11) #define BNX2_EMAC_MODE_MPKT (1L<<18) #define BNX2_EMAC_MODE_MPKT_RCVD (1L<<19) #define BNX2_EMAC_MODE_ACPI_RCVD (1L<<20) #define BNX2_EMAC_STATUS 0x00001404 #define BNX2_EMAC_STATUS_LINK (1L<<11) #define BNX2_EMAC_STATUS_LINK_CHANGE (1L<<12) #define BNX2_EMAC_STATUS_MI_COMPLETE (1L<<22) #define BNX2_EMAC_STATUS_MI_INT (1L<<23) #define BNX2_EMAC_STATUS_AP_ERROR (1L<<24) #define BNX2_EMAC_STATUS_PARITY_ERROR_STATE (1L<<31) #define BNX2_EMAC_ATTENTION_ENA 0x00001408 #define BNX2_EMAC_ATTENTION_ENA_LINK (1L<<11) #define BNX2_EMAC_ATTENTION_ENA_MI_COMPLETE (1L<<22) #define BNX2_EMAC_ATTENTION_ENA_MI_INT (1L<<23) #define BNX2_EMAC_ATTENTION_ENA_AP_ERROR (1L<<24) #define BNX2_EMAC_LED 0x0000140c #define BNX2_EMAC_LED_OVERRIDE (1L<<0) #define BNX2_EMAC_LED_1000MB_OVERRIDE (1L<<1) #define BNX2_EMAC_LED_100MB_OVERRIDE (1L<<2) #define BNX2_EMAC_LED_10MB_OVERRIDE (1L<<3) #define BNX2_EMAC_LED_TRAFFIC_OVERRIDE (1L<<4) #define BNX2_EMAC_LED_BLNK_TRAFFIC (1L<<5) #define BNX2_EMAC_LED_TRAFFIC (1L<<6) #define BNX2_EMAC_LED_1000MB (1L<<7) #define BNX2_EMAC_LED_100MB (1L<<8) #define BNX2_EMAC_LED_10MB (1L<<9) #define BNX2_EMAC_LED_TRAFFIC_STAT (1L<<10) #define BNX2_EMAC_LED_BLNK_RATE (0xfffL<<19) #define BNX2_EMAC_LED_BLNK_RATE_ENA (1L<<31) #define BNX2_EMAC_MAC_MATCH0 0x00001410 #define BNX2_EMAC_MAC_MATCH1 0x00001414 #define BNX2_EMAC_MAC_MATCH2 0x00001418 #define BNX2_EMAC_MAC_MATCH3 0x0000141c #define BNX2_EMAC_MAC_MATCH4 0x00001420 #define BNX2_EMAC_MAC_MATCH5 0x00001424 #define BNX2_EMAC_MAC_MATCH6 0x00001428 #define BNX2_EMAC_MAC_MATCH7 0x0000142c #define BNX2_EMAC_MAC_MATCH8 0x00001430 #define BNX2_EMAC_MAC_MATCH9 0x00001434 #define BNX2_EMAC_MAC_MATCH10 0x00001438 #define BNX2_EMAC_MAC_MATCH11 0x0000143c #define BNX2_EMAC_MAC_MATCH12 0x00001440 #define BNX2_EMAC_MAC_MATCH13 0x00001444 #define BNX2_EMAC_MAC_MATCH14 0x00001448 #define BNX2_EMAC_MAC_MATCH15 0x0000144c #define BNX2_EMAC_MAC_MATCH16 0x00001450 #define BNX2_EMAC_MAC_MATCH17 0x00001454 #define BNX2_EMAC_MAC_MATCH18 0x00001458 #define BNX2_EMAC_MAC_MATCH19 0x0000145c #define BNX2_EMAC_MAC_MATCH20 0x00001460 #define BNX2_EMAC_MAC_MATCH21 0x00001464 #define BNX2_EMAC_MAC_MATCH22 0x00001468 #define BNX2_EMAC_MAC_MATCH23 0x0000146c #define BNX2_EMAC_MAC_MATCH24 0x00001470 #define BNX2_EMAC_MAC_MATCH25 0x00001474 #define BNX2_EMAC_MAC_MATCH26 0x00001478 #define BNX2_EMAC_MAC_MATCH27 0x0000147c #define BNX2_EMAC_MAC_MATCH28 0x00001480 #define BNX2_EMAC_MAC_MATCH29 0x00001484 #define BNX2_EMAC_MAC_MATCH30 0x00001488 #define BNX2_EMAC_MAC_MATCH31 0x0000148c #define BNX2_EMAC_BACKOFF_SEED 0x00001498 #define BNX2_EMAC_BACKOFF_SEED_EMAC_BACKOFF_SEED (0x3ffL<<0) #define BNX2_EMAC_RX_MTU_SIZE 0x0000149c #define BNX2_EMAC_RX_MTU_SIZE_MTU_SIZE (0xffffL<<0) #define BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31) #define BNX2_EMAC_SERDES_CNTL 0x000014a4 #define BNX2_EMAC_SERDES_CNTL_RXR (0x7L<<0) #define BNX2_EMAC_SERDES_CNTL_RXG (0x3L<<3) #define BNX2_EMAC_SERDES_CNTL_RXCKSEL (1L<<6) #define BNX2_EMAC_SERDES_CNTL_TXBIAS (0x7L<<7) #define BNX2_EMAC_SERDES_CNTL_BGMAX (1L<<10) #define BNX2_EMAC_SERDES_CNTL_BGMIN (1L<<11) #define BNX2_EMAC_SERDES_CNTL_TXMODE (1L<<12) #define BNX2_EMAC_SERDES_CNTL_TXEDGE (1L<<13) #define BNX2_EMAC_SERDES_CNTL_SERDES_MODE (1L<<14) #define BNX2_EMAC_SERDES_CNTL_PLLTEST (1L<<15) #define BNX2_EMAC_SERDES_CNTL_CDET_EN (1L<<16) #define BNX2_EMAC_SERDES_CNTL_TBI_LBK (1L<<17) #define BNX2_EMAC_SERDES_CNTL_REMOTE_LBK (1L<<18) #define BNX2_EMAC_SERDES_CNTL_REV_PHASE (1L<<19) #define BNX2_EMAC_SERDES_CNTL_REGCTL12 (0x3L<<20) #define BNX2_EMAC_SERDES_CNTL_REGCTL25 (0x3L<<22) #define BNX2_EMAC_SERDES_STATUS 0x000014a8 #define BNX2_EMAC_SERDES_STATUS_RX_STAT (0xffL<<0) #define BNX2_EMAC_SERDES_STATUS_COMMA_DET (1L<<8) #define BNX2_EMAC_MDIO_COMM 0x000014ac #define BNX2_EMAC_MDIO_COMM_DATA (0xffffL<<0) #define BNX2_EMAC_MDIO_COMM_REG_ADDR (0x1fL<<16) #define BNX2_EMAC_MDIO_COMM_PHY_ADDR (0x1fL<<21) #define BNX2_EMAC_MDIO_COMM_COMMAND (0x3L<<26) #define BNX2_EMAC_MDIO_COMM_COMMAND_UNDEFINED_0 (0L<<26) #define BNX2_EMAC_MDIO_COMM_COMMAND_WRITE (1L<<26) #define BNX2_EMAC_MDIO_COMM_COMMAND_READ (2L<<26) #define BNX2_EMAC_MDIO_COMM_COMMAND_UNDEFINED_3 (3L<<26) #define BNX2_EMAC_MDIO_COMM_FAIL (1L<<28) #define BNX2_EMAC_MDIO_COMM_START_BUSY (1L<<29) #define BNX2_EMAC_MDIO_COMM_DISEXT (1L<<30) #define BNX2_EMAC_MDIO_STATUS 0x000014b0 #define BNX2_EMAC_MDIO_STATUS_LINK (1L<<0) #define BNX2_EMAC_MDIO_STATUS_10MB (1L<<1) #define BNX2_EMAC_MDIO_MODE 0x000014b4 #define BNX2_EMAC_MDIO_MODE_SHORT_PREAMBLE (1L<<1) #define BNX2_EMAC_MDIO_MODE_AUTO_POLL (1L<<4) #define BNX2_EMAC_MDIO_MODE_BIT_BANG (1L<<8) #define BNX2_EMAC_MDIO_MODE_MDIO (1L<<9) #define BNX2_EMAC_MDIO_MODE_MDIO_OE (1L<<10) #define BNX2_EMAC_MDIO_MODE_MDC (1L<<11) #define BNX2_EMAC_MDIO_MODE_MDINT (1L<<12) #define BNX2_EMAC_MDIO_MODE_CLOCK_CNT (0x1fL<<16) #define BNX2_EMAC_MDIO_AUTO_STATUS 0x000014b8 #define BNX2_EMAC_MDIO_AUTO_STATUS_AUTO_ERR (1L<<0) #define BNX2_EMAC_TX_MODE 0x000014bc #define BNX2_EMAC_TX_MODE_RESET (1L<<0) #define BNX2_EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3) #define BNX2_EMAC_TX_MODE_FLOW_EN (1L<<4) #define BNX2_EMAC_TX_MODE_BIG_BACKOFF (1L<<5) #define BNX2_EMAC_TX_MODE_LONG_PAUSE (1L<<6) #define BNX2_EMAC_TX_MODE_LINK_AWARE (1L<<7) #define BNX2_EMAC_TX_STATUS 0x000014c0 #define BNX2_EMAC_TX_STATUS_XOFFED (1L<<0) #define BNX2_EMAC_TX_STATUS_XOFF_SENT (1L<<1) #define BNX2_EMAC_TX_STATUS_XON_SENT (1L<<2) #define BNX2_EMAC_TX_STATUS_LINK_UP (1L<<3) #define BNX2_EMAC_TX_STATUS_UNDERRUN (1L<<4) #define BNX2_EMAC_TX_LENGTHS 0x000014c4 #define BNX2_EMAC_TX_LENGTHS_SLOT (0xffL<<0) #define BNX2_EMAC_TX_LENGTHS_IPG (0xfL<<8) #define BNX2_EMAC_TX_LENGTHS_IPG_CRS (0x3L<<12) #define BNX2_EMAC_RX_MODE 0x000014c8 #define BNX2_EMAC_RX_MODE_RESET (1L<<0) #define BNX2_EMAC_RX_MODE_FLOW_EN (1L<<2) #define BNX2_EMAC_RX_MODE_KEEP_MAC_CONTROL (1L<<3) #define BNX2_EMAC_RX_MODE_KEEP_PAUSE (1L<<4) #define BNX2_EMAC_RX_MODE_ACCEPT_OVERSIZE (1L<<5) #define BNX2_EMAC_RX_MODE_ACCEPT_RUNTS (1L<<6) #define BNX2_EMAC_RX_MODE_LLC_CHK (1L<<7) #define BNX2_EMAC_RX_MODE_PROMISCUOUS (1L<<8) #define BNX2_EMAC_RX_MODE_NO_CRC_CHK (1L<<9) #define BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG (1L<<10) #define BNX2_EMAC_RX_MODE_FILT_BROADCAST (1L<<11) #define BNX2_EMAC_RX_MODE_SORT_MODE (1L<<12) #define BNX2_EMAC_RX_STATUS 0x000014cc #define BNX2_EMAC_RX_STATUS_FFED (1L<<0) #define BNX2_EMAC_RX_STATUS_FF_RECEIVED (1L<<1) #define BNX2_EMAC_RX_STATUS_N_RECEIVED (1L<<2) #define BNX2_EMAC_MULTICAST_HASH0 0x000014d0 #define BNX2_EMAC_MULTICAST_HASH1 0x000014d4 #define BNX2_EMAC_MULTICAST_HASH2 0x000014d8 #define BNX2_EMAC_MULTICAST_HASH3 0x000014dc #define BNX2_EMAC_MULTICAST_HASH4 0x000014e0 #define BNX2_EMAC_MULTICAST_HASH5 0x000014e4 #define BNX2_EMAC_MULTICAST_HASH6 0x000014e8 #define BNX2_EMAC_MULTICAST_HASH7 0x000014ec #define BNX2_EMAC_RX_STAT_IFHCINOCTETS 0x00001500 #define BNX2_EMAC_RX_STAT_IFHCINBADOCTETS 0x00001504 #define BNX2_EMAC_RX_STAT_ETHERSTATSFRAGMENTS 0x00001508 #define BNX2_EMAC_RX_STAT_IFHCINUCASTPKTS 0x0000150c #define BNX2_EMAC_RX_STAT_IFHCINMULTICASTPKTS 0x00001510 #define BNX2_EMAC_RX_STAT_IFHCINBROADCASTPKTS 0x00001514 #define BNX2_EMAC_RX_STAT_DOT3STATSFCSERRORS 0x00001518 #define BNX2_EMAC_RX_STAT_DOT3STATSALIGNMENTERRORS 0x0000151c #define BNX2_EMAC_RX_STAT_DOT3STATSCARRIERSENSEERRORS 0x00001520 #define BNX2_EMAC_RX_STAT_XONPAUSEFRAMESRECEIVED 0x00001524 #define BNX2_EMAC_RX_STAT_XOFFPAUSEFRAMESRECEIVED 0x00001528 #define BNX2_EMAC_RX_STAT_MACCONTROLFRAMESRECEIVED 0x0000152c #define BNX2_EMAC_RX_STAT_XOFFSTATEENTERED 0x00001530 #define BNX2_EMAC_RX_STAT_DOT3STATSFRAMESTOOLONG 0x00001534 #define BNX2_EMAC_RX_STAT_ETHERSTATSJABBERS 0x00001538 #define BNX2_EMAC_RX_STAT_ETHERSTATSUNDERSIZEPKTS 0x0000153c #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS64OCTETS 0x00001540 #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS65OCTETSTO127OCTETS 0x00001544 #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS128OCTETSTO255OCTETS 0x00001548 #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS256OCTETSTO511OCTETS 0x0000154c #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS512OCTETSTO1023OCTETS 0x00001550 #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS1024OCTETSTO1522OCTETS 0x00001554 #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS1523OCTETSTO9022OCTETS 0x00001558 #define BNX2_EMAC_RXMAC_DEBUG0 0x0000155c #define BNX2_EMAC_RXMAC_DEBUG1 0x00001560 #define BNX2_EMAC_RXMAC_DEBUG1_LENGTH_NE_BYTE_COUNT (1L<<0) #define BNX2_EMAC_RXMAC_DEBUG1_LENGTH_OUT_RANGE (1L<<1) #define BNX2_EMAC_RXMAC_DEBUG1_BAD_CRC (1L<<2) #define BNX2_EMAC_RXMAC_DEBUG1_RX_ERROR (1L<<3) #define BNX2_EMAC_RXMAC_DEBUG1_ALIGN_ERROR (1L<<4) #define BNX2_EMAC_RXMAC_DEBUG1_LAST_DATA (1L<<5) #define BNX2_EMAC_RXMAC_DEBUG1_ODD_BYTE_START (1L<<6) #define BNX2_EMAC_RXMAC_DEBUG1_BYTE_COUNT (0xffffL<<7) #define BNX2_EMAC_RXMAC_DEBUG1_SLOT_TIME (0xffL<<23) #define BNX2_EMAC_RXMAC_DEBUG2 0x00001564 #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE (0x7L<<0) #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_IDLE (0x0L<<0) #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SFD (0x1L<<0) #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_DATA (0x2L<<0) #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SKEEP (0x3L<<0) #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_EXT (0x4L<<0) #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_DROP (0x5L<<0) #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SDROP (0x6L<<0) #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_FC (0x7L<<0) #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE (0xfL<<3) #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_IDLE (0x0L<<3) #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA0 (0x1L<<3) #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA1 (0x2L<<3) #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA2 (0x3L<<3) #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA3 (0x4L<<3) #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_ABORT (0x5L<<3) #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_WAIT (0x6L<<3) #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_STATUS (0x7L<<3) #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_LAST (0x8L<<3) #define BNX2_EMAC_RXMAC_DEBUG2_BYTE_IN (0xffL<<7) #define BNX2_EMAC_RXMAC_DEBUG2_FALSEC (1L<<15) #define BNX2_EMAC_RXMAC_DEBUG2_TAGGED (1L<<16) #define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE (1L<<18) #define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE_IDLE (0L<<18) #define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE_PAUSED (1L<<18) #define BNX2_EMAC_RXMAC_DEBUG2_SE_COUNTER (0xfL<<19) #define BNX2_EMAC_RXMAC_DEBUG2_QUANTA (0x1fL<<23) #define BNX2_EMAC_RXMAC_DEBUG3 0x00001568 #define BNX2_EMAC_RXMAC_DEBUG3_PAUSE_CTR (0xffffL<<0) #define BNX2_EMAC_RXMAC_DEBUG3_TMP_PAUSE_CTR (0xffffL<<16) #define BNX2_EMAC_RXMAC_DEBUG4 0x0000156c #define BNX2_EMAC_RXMAC_DEBUG4_TYPE_FIELD (0xffffL<<0) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE (0x3fL<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_IDLE (0x0L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UMAC2 (0x1L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UMAC3 (0x2L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UNI (0x3L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MMAC2 (0x7L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MMAC3 (0x5L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA1 (0x6L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA2 (0x7L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA3 (0x8L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC2 (0x9L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC3 (0xaL<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MWAIT1 (0xeL<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MWAIT2 (0xfL<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MCHECK (0x10L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC (0x11L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC2 (0x12L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC3 (0x13L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA1 (0x14L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA2 (0x15L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA3 (0x16L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BTYPE (0x17L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC (0x18L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PTYPE (0x19L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_CMD (0x1aL<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MAC (0x1bL<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_LATCH (0x1cL<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_XOFF (0x1dL<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_XON (0x1eL<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PAUSED (0x1fL<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_NPAUSED (0x20L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_TTYPE (0x21L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_TVAL (0x22L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA1 (0x23L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA2 (0x24L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA3 (0x25L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTYPE (0x26L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTTYPE (0x27L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTVAL (0x28L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MTYPE (0x29L<<16) #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_DROP (0x2aL<<16) #define BNX2_EMAC_RXMAC_DEBUG4_DROP_PKT (1L<<22) #define BNX2_EMAC_RXMAC_DEBUG4_SLOT_FILLED (1L<<23) #define BNX2_EMAC_RXMAC_DEBUG4_FALSE_CARRIER (1L<<24) #define BNX2_EMAC_RXMAC_DEBUG4_LAST_DATA (1L<<25) #define BNX2_EMAC_RXMAC_DEBUG4_sfd_FOUND (1L<<26) #define BNX2_EMAC_RXMAC_DEBUG4_ADVANCE (1L<<27) #define BNX2_EMAC_RXMAC_DEBUG4_START (1L<<28) #define BNX2_EMAC_RXMAC_DEBUG5 0x00001570 #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM (0x7L<<0) #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_IDLE (0L<<0) #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_WAIT_EOF (1L<<0) #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_WAIT_STAT (2L<<0) #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4FCRC (3L<<0) #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4RDE (4L<<0) #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4ALL (5L<<0) #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_1WD_WAIT_STAT (6L<<0) #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1 (0x7L<<4) #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_VDW (0x0L<<4) #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_STAT (0x1L<<4) #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_AEOF (0x2L<<4) #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_NEOF (0x3L<<4) #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SOF (0x4L<<4) #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SAEOF (0x6L<<4) #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SNEOF (0x7L<<4) #define BNX2_EMAC_RXMAC_DEBUG5_EOF_DETECTED (1L<<7) #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF0 (0x7L<<8) #define BNX2_EMAC_RXMAC_DEBUG5_RPM_IDI_FIFO_FULL (1L<<11) #define BNX2_EMAC_RXMAC_DEBUG5_LOAD_CCODE (1L<<12) #define BNX2_EMAC_RXMAC_DEBUG5_LOAD_DATA (1L<<13) #define BNX2_EMAC_RXMAC_DEBUG5_LOAD_STAT (1L<<14) #define BNX2_EMAC_RXMAC_DEBUG5_CLR_STAT (1L<<15) #define BNX2_EMAC_RXMAC_DEBUG5_IDI_RPM_CCODE (0x3L<<16) #define BNX2_EMAC_RXMAC_DEBUG5_IDI_RPM_ACCEPT (1L<<19) #define BNX2_EMAC_RXMAC_DEBUG5_FMLEN (0xfffL<<20) #define BNX2_EMAC_RX_STAT_AC0 0x00001580 #define BNX2_EMAC_RX_STAT_AC1 0x00001584 #define BNX2_EMAC_RX_STAT_AC2 0x00001588 #define BNX2_EMAC_RX_STAT_AC3 0x0000158c #define BNX2_EMAC_RX_STAT_AC4 0x00001590 #define BNX2_EMAC_RX_STAT_AC5 0x00001594 #define BNX2_EMAC_RX_STAT_AC6 0x00001598 #define BNX2_EMAC_RX_STAT_AC7 0x0000159c #define BNX2_EMAC_RX_STAT_AC8 0x000015a0 #define BNX2_EMAC_RX_STAT_AC9 0x000015a4 #define BNX2_EMAC_RX_STAT_AC10 0x000015a8 #define BNX2_EMAC_RX_STAT_AC11 0x000015ac #define BNX2_EMAC_RX_STAT_AC12 0x000015b0 #define BNX2_EMAC_RX_STAT_AC13 0x000015b4 #define BNX2_EMAC_RX_STAT_AC14 0x000015b8 #define BNX2_EMAC_RX_STAT_AC15 0x000015bc #define BNX2_EMAC_RX_STAT_AC16 0x000015c0 #define BNX2_EMAC_RX_STAT_AC17 0x000015c4 #define BNX2_EMAC_RX_STAT_AC18 0x000015c8 #define BNX2_EMAC_RX_STAT_AC19 0x000015cc #define BNX2_EMAC_RX_STAT_AC20 0x000015d0 #define BNX2_EMAC_RX_STAT_AC21 0x000015d4 #define BNX2_EMAC_RX_STAT_AC22 0x000015d8 #define BNX2_EMAC_RXMAC_SUC_DBG_OVERRUNVEC 0x000015dc #define BNX2_EMAC_TX_STAT_IFHCOUTOCTETS 0x00001600 #define BNX2_EMAC_TX_STAT_IFHCOUTBADOCTETS 0x00001604 #define BNX2_EMAC_TX_STAT_ETHERSTATSCOLLISIONS 0x00001608 #define BNX2_EMAC_TX_STAT_OUTXONSENT 0x0000160c #define BNX2_EMAC_TX_STAT_OUTXOFFSENT 0x00001610 #define BNX2_EMAC_TX_STAT_FLOWCONTROLDONE 0x00001614 #define BNX2_EMAC_TX_STAT_DOT3STATSSINGLECOLLISIONFRAMES 0x00001618 #define BNX2_EMAC_TX_STAT_DOT3STATSMULTIPLECOLLISIONFRAMES 0x0000161c #define BNX2_EMAC_TX_STAT_DOT3STATSDEFERREDTRANSMISSIONS 0x00001620 #define BNX2_EMAC_TX_STAT_DOT3STATSEXCESSIVECOLLISIONS 0x00001624 #define BNX2_EMAC_TX_STAT_DOT3STATSLATECOLLISIONS 0x00001628 #define BNX2_EMAC_TX_STAT_IFHCOUTUCASTPKTS 0x0000162c #define BNX2_EMAC_TX_STAT_IFHCOUTMULTICASTPKTS 0x00001630 #define BNX2_EMAC_TX_STAT_IFHCOUTBROADCASTPKTS 0x00001634 #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS64OCTETS 0x00001638 #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS65OCTETSTO127OCTETS 0x0000163c #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS128OCTETSTO255OCTETS 0x00001640 #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS256OCTETSTO511OCTETS 0x00001644 #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS512OCTETSTO1023OCTETS 0x00001648 #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS1024OCTETSTO1522OCTETS 0x0000164c #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS1523OCTETSTO9022OCTETS 0x00001650 #define BNX2_EMAC_TX_STAT_DOT3STATSINTERNALMACTRANSMITERRORS 0x00001654 #define BNX2_EMAC_TXMAC_DEBUG0 0x00001658 #define BNX2_EMAC_TXMAC_DEBUG1 0x0000165c #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE (0xfL<<0) #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_IDLE (0x0L<<0) #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_START0 (0x1L<<0) #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA0 (0x4L<<0) #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA1 (0x5L<<0) #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA2 (0x6L<<0) #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA3 (0x7L<<0) #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_WAIT0 (0x8L<<0) #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_WAIT1 (0x9L<<0) #define BNX2_EMAC_TXMAC_DEBUG1_CRS_ENABLE (1L<<4) #define BNX2_EMAC_TXMAC_DEBUG1_BAD_CRC (1L<<5) #define BNX2_EMAC_TXMAC_DEBUG1_SE_COUNTER (0xfL<<6) #define BNX2_EMAC_TXMAC_DEBUG1_SEND_PAUSE (1L<<10) #define BNX2_EMAC_TXMAC_DEBUG1_LATE_COLLISION (1L<<11) #define BNX2_EMAC_TXMAC_DEBUG1_MAX_DEFER (1L<<12) #define BNX2_EMAC_TXMAC_DEBUG1_DEFERRED (1L<<13) #define BNX2_EMAC_TXMAC_DEBUG1_ONE_BYTE (1L<<14) #define BNX2_EMAC_TXMAC_DEBUG1_IPG_TIME (0xfL<<15) #define BNX2_EMAC_TXMAC_DEBUG1_SLOT_TIME (0xffL<<19) #define BNX2_EMAC_TXMAC_DEBUG2 0x00001660 #define BNX2_EMAC_TXMAC_DEBUG2_BACK_OFF (0x3ffL<<0) #define BNX2_EMAC_TXMAC_DEBUG2_BYTE_COUNT (0xffffL<<10) #define BNX2_EMAC_TXMAC_DEBUG2_COL_COUNT (0x1fL<<26) #define BNX2_EMAC_TXMAC_DEBUG2_COL_BIT (1L<<31) #define BNX2_EMAC_TXMAC_DEBUG3 0x00001664 #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE (0xfL<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_IDLE (0x0L<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_PRE1 (0x1L<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_PRE2 (0x2L<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_SFD (0x3L<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_DATA (0x4L<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_CRC1 (0x5L<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_CRC2 (0x6L<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_EXT (0x7L<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_STATB (0x8L<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_STATG (0x9L<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_JAM (0xaL<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_EJAM (0xbL<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_BJAM (0xcL<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_SWAIT (0xdL<<0) #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_BACKOFF (0xeL<<0) #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE (0x7L<<4) #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_IDLE (0x0L<<4) #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_WAIT (0x1L<<4) #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_UNI (0x2L<<4) #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_MC (0x3L<<4) #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC2 (0x4L<<4) #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC3 (0x5L<<4) #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC (0x6L<<4) #define BNX2_EMAC_TXMAC_DEBUG3_CRS_DONE (1L<<7) #define BNX2_EMAC_TXMAC_DEBUG3_XOFF (1L<<8) #define BNX2_EMAC_TXMAC_DEBUG3_SE_COUNTER (0xfL<<9) #define BNX2_EMAC_TXMAC_DEBUG3_QUANTA_COUNTER (0x1fL<<13) #define BNX2_EMAC_TXMAC_DEBUG4 0x00001668 #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_COUNTER (0xffffL<<0) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE (0xfL<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_IDLE (0x0L<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA1 (0x2L<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA2 (0x3L<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA3 (0x6L<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC1 (0x7L<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC2 (0x5L<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC3 (0x4L<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TYPE (0xcL<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CMD (0xeL<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TIME (0xaL<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CRC1 (0x8L<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CRC2 (0x9L<<16) #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_WAIT (0xdL<<16) #define BNX2_EMAC_TXMAC_DEBUG4_STATS0_VALID (1L<<20) #define BNX2_EMAC_TXMAC_DEBUG4_APPEND_CRC (1L<<21) #define BNX2_EMAC_TXMAC_DEBUG4_SLOT_FILLED (1L<<22) #define BNX2_EMAC_TXMAC_DEBUG4_MAX_DEFER (1L<<23) #define BNX2_EMAC_TXMAC_DEBUG4_SEND_EXTEND (1L<<24) #define BNX2_EMAC_TXMAC_DEBUG4_SEND_PADDING (1L<<25) #define BNX2_EMAC_TXMAC_DEBUG4_EOF_LOC (1L<<26) #define BNX2_EMAC_TXMAC_DEBUG4_COLLIDING (1L<<27) #define BNX2_EMAC_TXMAC_DEBUG4_COL_IN (1L<<28) #define BNX2_EMAC_TXMAC_DEBUG4_BURSTING (1L<<29) #define BNX2_EMAC_TXMAC_DEBUG4_ADVANCE (1L<<30) #define BNX2_EMAC_TXMAC_DEBUG4_GO (1L<<31) #define BNX2_EMAC_TX_STAT_AC0 0x00001680 #define BNX2_EMAC_TX_STAT_AC1 0x00001684 #define BNX2_EMAC_TX_STAT_AC2 0x00001688 #define BNX2_EMAC_TX_STAT_AC3 0x0000168c #define BNX2_EMAC_TX_STAT_AC4 0x00001690 #define BNX2_EMAC_TX_STAT_AC5 0x00001694 #define BNX2_EMAC_TX_STAT_AC6 0x00001698 #define BNX2_EMAC_TX_STAT_AC7 0x0000169c #define BNX2_EMAC_TX_STAT_AC8 0x000016a0 #define BNX2_EMAC_TX_STAT_AC9 0x000016a4 #define BNX2_EMAC_TX_STAT_AC10 0x000016a8 #define BNX2_EMAC_TX_STAT_AC11 0x000016ac #define BNX2_EMAC_TX_STAT_AC12 0x000016b0 #define BNX2_EMAC_TX_STAT_AC13 0x000016b4 #define BNX2_EMAC_TX_STAT_AC14 0x000016b8 #define BNX2_EMAC_TX_STAT_AC15 0x000016bc #define BNX2_EMAC_TX_STAT_AC16 0x000016c0 #define BNX2_EMAC_TX_STAT_AC17 0x000016c4 #define BNX2_EMAC_TX_STAT_AC18 0x000016c8 #define BNX2_EMAC_TX_STAT_AC19 0x000016cc #define BNX2_EMAC_TX_STAT_AC20 0x000016d0 #define BNX2_EMAC_TX_STAT_AC21 0x000016d4 #define BNX2_EMAC_TXMAC_SUC_DBG_OVERRUNVEC 0x000016d8 /* * rpm_reg definition * offset: 0x1800 */ #define BNX2_RPM_COMMAND 0x00001800 #define BNX2_RPM_COMMAND_ENABLED (1L<<0) #define BNX2_RPM_COMMAND_OVERRUN_ABORT (1L<<4) #define BNX2_RPM_STATUS 0x00001804 #define BNX2_RPM_STATUS_MBUF_WAIT (1L<<0) #define BNX2_RPM_STATUS_FREE_WAIT (1L<<1) #define BNX2_RPM_CONFIG 0x00001808 #define BNX2_RPM_CONFIG_NO_PSD_HDR_CKSUM (1L<<0) #define BNX2_RPM_CONFIG_ACPI_ENA (1L<<1) #define BNX2_RPM_CONFIG_ACPI_KEEP (1L<<2) #define BNX2_RPM_CONFIG_MP_KEEP (1L<<3) #define BNX2_RPM_CONFIG_SORT_VECT_VAL (0xfL<<4) #define BNX2_RPM_CONFIG_IGNORE_VLAN (1L<<31) #define BNX2_RPM_VLAN_MATCH0 0x00001810 #define BNX2_RPM_VLAN_MATCH0_RPM_VLAN_MTCH0_VALUE (0xfffL<<0) #define BNX2_RPM_VLAN_MATCH1 0x00001814 #define BNX2_RPM_VLAN_MATCH1_RPM_VLAN_MTCH1_VALUE (0xfffL<<0) #define BNX2_RPM_VLAN_MATCH2 0x00001818 #define BNX2_RPM_VLAN_MATCH2_RPM_VLAN_MTCH2_VALUE (0xfffL<<0) #define BNX2_RPM_VLAN_MATCH3 0x0000181c #define BNX2_RPM_VLAN_MATCH3_RPM_VLAN_MTCH3_VALUE (0xfffL<<0) #define BNX2_RPM_SORT_USER0 0x00001820 #define BNX2_RPM_SORT_USER0_PM_EN (0xffffL<<0) #define BNX2_RPM_SORT_USER0_BC_EN (1L<<16) #define BNX2_RPM_SORT_USER0_MC_EN (1L<<17) #define BNX2_RPM_SORT_USER0_MC_HSH_EN (1L<<18) #define BNX2_RPM_SORT_USER0_PROM_EN (1L<<19) #define BNX2_RPM_SORT_USER0_VLAN_EN (0xfL<<20) #define BNX2_RPM_SORT_USER0_PROM_VLAN (1L<<24) #define BNX2_RPM_SORT_USER0_ENA (1L<<31) #define BNX2_RPM_SORT_USER1 0x00001824 #define BNX2_RPM_SORT_USER1_PM_EN (0xffffL<<0) #define BNX2_RPM_SORT_USER1_BC_EN (1L<<16) #define BNX2_RPM_SORT_USER1_MC_EN (1L<<17) #define BNX2_RPM_SORT_USER1_MC_HSH_EN (1L<<18) #define BNX2_RPM_SORT_USER1_PROM_EN (1L<<19) #define BNX2_RPM_SORT_USER1_VLAN_EN (0xfL<<20) #define BNX2_RPM_SORT_USER1_PROM_VLAN (1L<<24) #define BNX2_RPM_SORT_USER1_ENA (1L<<31) #define BNX2_RPM_SORT_USER2 0x00001828 #define BNX2_RPM_SORT_USER2_PM_EN (0xffffL<<0) #define BNX2_RPM_SORT_USER2_BC_EN (1L<<16) #define BNX2_RPM_SORT_USER2_MC_EN (1L<<17) #define BNX2_RPM_SORT_USER2_MC_HSH_EN (1L<<18) #define BNX2_RPM_SORT_USER2_PROM_EN (1L<<19) #define BNX2_RPM_SORT_USER2_VLAN_EN (0xfL<<20) #define BNX2_RPM_SORT_USER2_PROM_VLAN (1L<<24) #define BNX2_RPM_SORT_USER2_ENA (1L<<31) #define BNX2_RPM_SORT_USER3 0x0000182c #define BNX2_RPM_SORT_USER3_PM_EN (0xffffL<<0) #define BNX2_RPM_SORT_USER3_BC_EN (1L<<16) #define BNX2_RPM_SORT_USER3_MC_EN (1L<<17) #define BNX2_RPM_SORT_USER3_MC_HSH_EN (1L<<18) #define BNX2_RPM_SORT_USER3_PROM_EN (1L<<19) #define BNX2_RPM_SORT_USER3_VLAN_EN (0xfL<<20) #define BNX2_RPM_SORT_USER3_PROM_VLAN (1L<<24) #define BNX2_RPM_SORT_USER3_ENA (1L<<31) #define BNX2_RPM_STAT_L2_FILTER_DISCARDS 0x00001840 #define BNX2_RPM_STAT_RULE_CHECKER_DISCARDS 0x00001844 #define BNX2_RPM_STAT_IFINFTQDISCARDS 0x00001848 #define BNX2_RPM_STAT_IFINMBUFDISCARD 0x0000184c #define BNX2_RPM_STAT_RULE_CHECKER_P4_HIT 0x00001850 #define BNX2_RPM_STAT_AC0 0x00001880 #define BNX2_RPM_STAT_AC1 0x00001884 #define BNX2_RPM_STAT_AC2 0x00001888 #define BNX2_RPM_STAT_AC3 0x0000188c #define BNX2_RPM_STAT_AC4 0x00001890 #define BNX2_RPM_RC_CNTL_0 0x00001900 #define BNX2_RPM_RC_CNTL_0_OFFSET (0xffL<<0) #define BNX2_RPM_RC_CNTL_0_CLASS (0x7L<<8) #define BNX2_RPM_RC_CNTL_0_PRIORITY (1L<<11) #define BNX2_RPM_RC_CNTL_0_P4 (1L<<12) #define BNX2_RPM_RC_CNTL_0_HDR_TYPE (0x7L<<13) #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_START (0L<<13) #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_IP (1L<<13) #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_TCP (2L<<13) #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_UDP (3L<<13) #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_DATA (4L<<13) #define BNX2_RPM_RC_CNTL_0_COMP (0x3L<<16) #define BNX2_RPM_RC_CNTL_0_COMP_EQUAL (0L<<16) #define BNX2_RPM_RC_CNTL_0_COMP_NEQUAL (1L<<16) #define BNX2_RPM_RC_CNTL_0_COMP_GREATER (2L<<16) #define BNX2_RPM_RC_CNTL_0_COMP_LESS (3L<<16) #define BNX2_RPM_RC_CNTL_0_SBIT (1L<<19) #define BNX2_RPM_RC_CNTL_0_CMDSEL (0xfL<<20) #define BNX2_RPM_RC_CNTL_0_MAP (1L<<24) #define BNX2_RPM_RC_CNTL_0_DISCARD (1L<<25) #define BNX2_RPM_RC_CNTL_0_MASK (1L<<26) #define BNX2_RPM_RC_CNTL_0_P1 (1L<<27) #define BNX2_RPM_RC_CNTL_0_P2 (1L<<28) #define BNX2_RPM_RC_CNTL_0_P3 (1L<<29) #define BNX2_RPM_RC_CNTL_0_NBIT (1L<<30) #define BNX2_RPM_RC_VALUE_MASK_0 0x00001904 #define BNX2_RPM_RC_VALUE_MASK_0_VALUE (0xffffL<<0) #define BNX2_RPM_RC_VALUE_MASK_0_MASK (0xffffL<<16) #define BNX2_RPM_RC_CNTL_1 0x00001908 #define BNX2_RPM_RC_CNTL_1_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_1_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_1 0x0000190c #define BNX2_RPM_RC_CNTL_2 0x00001910 #define BNX2_RPM_RC_CNTL_2_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_2_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_2 0x00001914 #define BNX2_RPM_RC_CNTL_3 0x00001918 #define BNX2_RPM_RC_CNTL_3_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_3_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_3 0x0000191c #define BNX2_RPM_RC_CNTL_4 0x00001920 #define BNX2_RPM_RC_CNTL_4_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_4_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_4 0x00001924 #define BNX2_RPM_RC_CNTL_5 0x00001928 #define BNX2_RPM_RC_CNTL_5_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_5_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_5 0x0000192c #define BNX2_RPM_RC_CNTL_6 0x00001930 #define BNX2_RPM_RC_CNTL_6_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_6_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_6 0x00001934 #define BNX2_RPM_RC_CNTL_7 0x00001938 #define BNX2_RPM_RC_CNTL_7_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_7_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_7 0x0000193c #define BNX2_RPM_RC_CNTL_8 0x00001940 #define BNX2_RPM_RC_CNTL_8_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_8_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_8 0x00001944 #define BNX2_RPM_RC_CNTL_9 0x00001948 #define BNX2_RPM_RC_CNTL_9_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_9_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_9 0x0000194c #define BNX2_RPM_RC_CNTL_10 0x00001950 #define BNX2_RPM_RC_CNTL_10_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_10_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_10 0x00001954 #define BNX2_RPM_RC_CNTL_11 0x00001958 #define BNX2_RPM_RC_CNTL_11_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_11_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_11 0x0000195c #define BNX2_RPM_RC_CNTL_12 0x00001960 #define BNX2_RPM_RC_CNTL_12_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_12_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_12 0x00001964 #define BNX2_RPM_RC_CNTL_13 0x00001968 #define BNX2_RPM_RC_CNTL_13_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_13_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_13 0x0000196c #define BNX2_RPM_RC_CNTL_14 0x00001970 #define BNX2_RPM_RC_CNTL_14_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_14_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_14 0x00001974 #define BNX2_RPM_RC_CNTL_15 0x00001978 #define BNX2_RPM_RC_CNTL_15_A (0x3ffffL<<0) #define BNX2_RPM_RC_CNTL_15_B (0xfffL<<19) #define BNX2_RPM_RC_VALUE_MASK_15 0x0000197c #define BNX2_RPM_RC_CONFIG 0x00001980 #define BNX2_RPM_RC_CONFIG_RULE_ENABLE (0xffffL<<0) #define BNX2_RPM_RC_CONFIG_DEF_CLASS (0x7L<<24) #define BNX2_RPM_DEBUG0 0x00001984 #define BNX2_RPM_DEBUG0_FM_BCNT (0xffffL<<0) #define BNX2_RPM_DEBUG0_T_DATA_OFST_VLD (1L<<16) #define BNX2_RPM_DEBUG0_T_UDP_OFST_VLD (1L<<17) #define BNX2_RPM_DEBUG0_T_TCP_OFST_VLD (1L<<18) #define BNX2_RPM_DEBUG0_T_IP_OFST_VLD (1L<<19) #define BNX2_RPM_DEBUG0_IP_MORE_FRGMT (1L<<20) #define BNX2_RPM_DEBUG0_T_IP_NO_TCP_UDP_HDR (1L<<21) #define BNX2_RPM_DEBUG0_LLC_SNAP (1L<<22) #define BNX2_RPM_DEBUG0_FM_STARTED (1L<<23) #define BNX2_RPM_DEBUG0_DONE (1L<<24) #define BNX2_RPM_DEBUG0_WAIT_4_DONE (1L<<25) #define BNX2_RPM_DEBUG0_USE_TPBUF_CKSUM (1L<<26) #define BNX2_RPM_DEBUG0_RX_NO_PSD_HDR_CKSUM (1L<<27) #define BNX2_RPM_DEBUG0_IGNORE_VLAN (1L<<28) #define BNX2_RPM_DEBUG0_RP_ENA_ACTIVE (1L<<31) #define BNX2_RPM_DEBUG1 0x00001988 #define BNX2_RPM_DEBUG1_FSM_CUR_ST (0xffffL<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_IDLE (0L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B6_ALL (1L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B2_IPLLC (2L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B6_IP (4L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B2_IP (8L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_IP_START (16L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_IP (32L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_TCP (64L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_UDP (128L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_AH (256L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ESP (512L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ESP_PAYLOAD (1024L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_DATA (2048L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ADD_CARRY (0x2000L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ADD_CARRYOUT (0x4000L<<0) #define BNX2_RPM_DEBUG1_FSM_CUR_ST_LATCH_RESULT (0x8000L<<0) #define BNX2_RPM_DEBUG1_HDR_BCNT (0x7ffL<<16) #define BNX2_RPM_DEBUG1_UNKNOWN_ETYPE_D (1L<<28) #define BNX2_RPM_DEBUG1_VLAN_REMOVED_D2 (1L<<29) #define BNX2_RPM_DEBUG1_VLAN_REMOVED_D1 (1L<<30) #define BNX2_RPM_DEBUG1_EOF_0XTRA_WD (1L<<31) #define BNX2_RPM_DEBUG2 0x0000198c #define BNX2_RPM_DEBUG2_CMD_HIT_VEC (0xffffL<<0) #define BNX2_RPM_DEBUG2_IP_BCNT (0xffL<<16) #define BNX2_RPM_DEBUG2_THIS_CMD_M4 (1L<<24) #define BNX2_RPM_DEBUG2_THIS_CMD_M3 (1L<<25) #define BNX2_RPM_DEBUG2_THIS_CMD_M2 (1L<<26) #define BNX2_RPM_DEBUG2_THIS_CMD_M1 (1L<<27) #define BNX2_RPM_DEBUG2_IPIPE_EMPTY (1L<<28) #define BNX2_RPM_DEBUG2_FM_DISCARD (1L<<29) #define BNX2_RPM_DEBUG2_LAST_RULE_IN_FM_D2 (1L<<30) #define BNX2_RPM_DEBUG2_LAST_RULE_IN_FM_D1 (1L<<31) #define BNX2_RPM_DEBUG3 0x00001990 #define BNX2_RPM_DEBUG3_AVAIL_MBUF_PTR (0x1ffL<<0) #define BNX2_RPM_DEBUG3_RDE_RLUPQ_WR_REQ_INT (1L<<9) #define BNX2_RPM_DEBUG3_RDE_RBUF_WR_LAST_INT (1L<<10) #define BNX2_RPM_DEBUG3_RDE_RBUF_WR_REQ_INT (1L<<11) #define BNX2_RPM_DEBUG3_RDE_RBUF_FREE_REQ (1L<<12) #define BNX2_RPM_DEBUG3_RDE_RBUF_ALLOC_REQ (1L<<13) #define BNX2_RPM_DEBUG3_DFSM_MBUF_NOTAVAIL (1L<<14) #define BNX2_RPM_DEBUG3_RBUF_RDE_SOF_DROP (1L<<15) #define BNX2_RPM_DEBUG3_DFIFO_VLD_ENTRY_CT (0xfL<<16) #define BNX2_RPM_DEBUG3_RDE_SRC_FIFO_ALMFULL (1L<<21) #define BNX2_RPM_DEBUG3_DROP_NXT_VLD (1L<<22) #define BNX2_RPM_DEBUG3_DROP_NXT (1L<<23) #define BNX2_RPM_DEBUG3_FTQ_FSM (0x3L<<24) #define BNX2_RPM_DEBUG3_FTQ_FSM_IDLE (0x0L<<24) #define BNX2_RPM_DEBUG3_FTQ_FSM_WAIT_ACK (0x1L<<24) #define BNX2_RPM_DEBUG3_FTQ_FSM_WAIT_FREE (0x2L<<24) #define BNX2_RPM_DEBUG3_MBWRITE_FSM (0x3L<<26) #define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_SOF (0x0L<<26) #define BNX2_RPM_DEBUG3_MBWRITE_FSM_GET_MBUF (0x1L<<26) #define BNX2_RPM_DEBUG3_MBWRITE_FSM_DMA_DATA (0x2L<<26) #define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_DATA (0x3L<<26) #define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_EOF (0x4L<<26) #define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_MF_ACK (0x5L<<26) #define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_DROP_NXT_VLD (0x6L<<26) #define BNX2_RPM_DEBUG3_MBWRITE_FSM_DONE (0x7L<<26) #define BNX2_RPM_DEBUG3_MBFREE_FSM (1L<<29) #define BNX2_RPM_DEBUG3_MBFREE_FSM_IDLE (0L<<29) #define BNX2_RPM_DEBUG3_MBFREE_FSM_WAIT_ACK (1L<<29) #define BNX2_RPM_DEBUG3_MBALLOC_FSM (1L<<30) #define BNX2_RPM_DEBUG3_MBALLOC_FSM_ET_MBUF (0x0L<<30) #define BNX2_RPM_DEBUG3_MBALLOC_FSM_IVE_MBUF (0x1L<<30) #define BNX2_RPM_DEBUG3_CCODE_EOF_ERROR (1L<<31) #define BNX2_RPM_DEBUG4 0x00001994 #define BNX2_RPM_DEBUG4_DFSM_MBUF_CLUSTER (0x1ffffffL<<0) #define BNX2_RPM_DEBUG4_DFIFO_CUR_CCODE (0x7L<<25) #define BNX2_RPM_DEBUG4_MBWRITE_FSM (0x7L<<28) #define BNX2_RPM_DEBUG4_DFIFO_EMPTY (1L<<31) #define BNX2_RPM_DEBUG5 0x00001998 #define BNX2_RPM_DEBUG5_RDROP_WPTR (0x1fL<<0) #define BNX2_RPM_DEBUG5_RDROP_ACPI_RPTR (0x1fL<<5) #define BNX2_RPM_DEBUG5_RDROP_MC_RPTR (0x1fL<<10) #define BNX2_RPM_DEBUG5_RDROP_RC_RPTR (0x1fL<<15) #define BNX2_RPM_DEBUG5_RDROP_ACPI_EMPTY (1L<<20) #define BNX2_RPM_DEBUG5_RDROP_MC_EMPTY (1L<<21) #define BNX2_RPM_DEBUG5_RDROP_AEOF_VEC_AT_RDROP_MC_RPTR (1L<<22) #define BNX2_RPM_DEBUG5_HOLDREG_WOL_DROP_INT (1L<<23) #define BNX2_RPM_DEBUG5_HOLDREG_DISCARD (1L<<24) #define BNX2_RPM_DEBUG5_HOLDREG_MBUF_NOTAVAIL (1L<<25) #define BNX2_RPM_DEBUG5_HOLDREG_MC_EMPTY (1L<<26) #define BNX2_RPM_DEBUG5_HOLDREG_RC_EMPTY (1L<<27) #define BNX2_RPM_DEBUG5_HOLDREG_FC_EMPTY (1L<<28) #define BNX2_RPM_DEBUG5_HOLDREG_ACPI_EMPTY (1L<<29) #define BNX2_RPM_DEBUG5_HOLDREG_FULL_T (1L<<30) #define BNX2_RPM_DEBUG5_HOLDREG_RD (1L<<31) #define BNX2_RPM_DEBUG6 0x0000199c #define BNX2_RPM_DEBUG6_ACPI_VEC (0xffffL<<0) #define BNX2_RPM_DEBUG6_VEC (0xffffL<<16) #define BNX2_RPM_DEBUG7 0x000019a0 #define BNX2_RPM_DEBUG7_RPM_DBG7_LAST_CRC (0xffffffffL<<0) #define BNX2_RPM_DEBUG8 0x000019a4 #define BNX2_RPM_DEBUG8_PS_ACPI_FSM (0xfL<<0) #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_IDLE (0L<<0) #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W1_ADDR (1L<<0) #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W2_ADDR (2L<<0) #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W3_ADDR (3L<<0) #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_WAIT_THBUF (4L<<0) #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W3_DATA (5L<<0) #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W0_ADDR (6L<<0) #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W1_ADDR (7L<<0) #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W2_ADDR (8L<<0) #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W3_ADDR (9L<<0) #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_WAIT_THBUF (10L<<0) #define BNX2_RPM_DEBUG8_COMPARE_AT_W0 (1L<<4) #define BNX2_RPM_DEBUG8_COMPARE_AT_W3_DATA (1L<<5) #define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_WAIT (1L<<6) #define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_W3 (1L<<7) #define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_W2 (1L<<8) #define BNX2_RPM_DEBUG8_EOF_W_LTEQ6_VLDBYTES (1L<<9) #define BNX2_RPM_DEBUG8_EOF_W_LTEQ4_VLDBYTES (1L<<10) #define BNX2_RPM_DEBUG8_NXT_EOF_W_12_VLDBYTES (1L<<11) #define BNX2_RPM_DEBUG8_EOF_DET (1L<<12) #define BNX2_RPM_DEBUG8_SOF_DET (1L<<13) #define BNX2_RPM_DEBUG8_WAIT_4_SOF (1L<<14) #define BNX2_RPM_DEBUG8_ALL_DONE (1L<<15) #define BNX2_RPM_DEBUG8_THBUF_ADDR (0x7fL<<16) #define BNX2_RPM_DEBUG8_BYTE_CTR (0xffL<<24) #define BNX2_RPM_DEBUG9 0x000019a8 #define BNX2_RPM_DEBUG9_OUTFIFO_COUNT (0x7L<<0) #define BNX2_RPM_DEBUG9_RDE_ACPI_RDY (1L<<3) #define BNX2_RPM_DEBUG9_VLD_RD_ENTRY_CT (0x7L<<4) #define BNX2_RPM_DEBUG9_OUTFIFO_OVERRUN_OCCURRED (1L<<28) #define BNX2_RPM_DEBUG9_INFIFO_OVERRUN_OCCURRED (1L<<29) #define BNX2_RPM_DEBUG9_ACPI_MATCH_INT (1L<<30) #define BNX2_RPM_DEBUG9_ACPI_ENABLE_SYN (1L<<31) #define BNX2_RPM_ACPI_DBG_BUF_W00 0x000019c0 #define BNX2_RPM_ACPI_DBG_BUF_W01 0x000019c4 #define BNX2_RPM_ACPI_DBG_BUF_W02 0x000019c8 #define BNX2_RPM_ACPI_DBG_BUF_W03 0x000019cc #define BNX2_RPM_ACPI_DBG_BUF_W10 0x000019d0 #define BNX2_RPM_ACPI_DBG_BUF_W11 0x000019d4 #define BNX2_RPM_ACPI_DBG_BUF_W12 0x000019d8 #define BNX2_RPM_ACPI_DBG_BUF_W13 0x000019dc #define BNX2_RPM_ACPI_DBG_BUF_W20 0x000019e0 #define BNX2_RPM_ACPI_DBG_BUF_W21 0x000019e4 #define BNX2_RPM_ACPI_DBG_BUF_W22 0x000019e8 #define BNX2_RPM_ACPI_DBG_BUF_W23 0x000019ec #define BNX2_RPM_ACPI_DBG_BUF_W30 0x000019f0 #define BNX2_RPM_ACPI_DBG_BUF_W31 0x000019f4 #define BNX2_RPM_ACPI_DBG_BUF_W32 0x000019f8 #define BNX2_RPM_ACPI_DBG_BUF_W33 0x000019fc /* * rbuf_reg definition * offset: 0x200000 */ #define BNX2_RBUF_COMMAND 0x00200000 #define BNX2_RBUF_COMMAND_ENABLED (1L<<0) #define BNX2_RBUF_COMMAND_FREE_INIT (1L<<1) #define BNX2_RBUF_COMMAND_RAM_INIT (1L<<2) #define BNX2_RBUF_COMMAND_OVER_FREE (1L<<4) #define BNX2_RBUF_COMMAND_ALLOC_REQ (1L<<5) #define BNX2_RBUF_STATUS1 0x00200004 #define BNX2_RBUF_STATUS1_FREE_COUNT (0x3ffL<<0) #define BNX2_RBUF_STATUS2 0x00200008 #define BNX2_RBUF_STATUS2_FREE_TAIL (0x3ffL<<0) #define BNX2_RBUF_STATUS2_FREE_HEAD (0x3ffL<<16) #define BNX2_RBUF_CONFIG 0x0020000c #define BNX2_RBUF_CONFIG_XOFF_TRIP (0x3ffL<<0) #define BNX2_RBUF_CONFIG_XON_TRIP (0x3ffL<<16) #define BNX2_RBUF_FW_BUF_ALLOC 0x00200010 #define BNX2_RBUF_FW_BUF_ALLOC_VALUE (0x1ffL<<7) #define BNX2_RBUF_FW_BUF_FREE 0x00200014 #define BNX2_RBUF_FW_BUF_FREE_COUNT (0x7fL<<0) #define BNX2_RBUF_FW_BUF_FREE_TAIL (0x1ffL<<7) #define BNX2_RBUF_FW_BUF_FREE_HEAD (0x1ffL<<16) #define BNX2_RBUF_FW_BUF_SEL 0x00200018 #define BNX2_RBUF_FW_BUF_SEL_COUNT (0x7fL<<0) #define BNX2_RBUF_FW_BUF_SEL_TAIL (0x1ffL<<7) #define BNX2_RBUF_FW_BUF_SEL_HEAD (0x1ffL<<16) #define BNX2_RBUF_CONFIG2 0x0020001c #define BNX2_RBUF_CONFIG2_MAC_DROP_TRIP (0x3ffL<<0) #define BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP (0x3ffL<<16) #define BNX2_RBUF_CONFIG3 0x00200020 #define BNX2_RBUF_CONFIG3_CU_DROP_TRIP (0x3ffL<<0) #define BNX2_RBUF_CONFIG3_CU_KEEP_TRIP (0x3ffL<<16) #define BNX2_RBUF_PKT_DATA 0x00208000 #define BNX2_RBUF_CLIST_DATA 0x00210000 #define BNX2_RBUF_BUF_DATA 0x00220000 /* * rv2p_reg definition * offset: 0x2800 */ #define BNX2_RV2P_COMMAND 0x00002800 #define BNX2_RV2P_COMMAND_ENABLED (1L<<0) #define BNX2_RV2P_COMMAND_PROC1_INTRPT (1L<<1) #define BNX2_RV2P_COMMAND_PROC2_INTRPT (1L<<2) #define BNX2_RV2P_COMMAND_ABORT0 (1L<<4) #define BNX2_RV2P_COMMAND_ABORT1 (1L<<5) #define BNX2_RV2P_COMMAND_ABORT2 (1L<<6) #define BNX2_RV2P_COMMAND_ABORT3 (1L<<7) #define BNX2_RV2P_COMMAND_ABORT4 (1L<<8) #define BNX2_RV2P_COMMAND_ABORT5 (1L<<9) #define BNX2_RV2P_COMMAND_PROC1_RESET (1L<<16) #define BNX2_RV2P_COMMAND_PROC2_RESET (1L<<17) #define BNX2_RV2P_COMMAND_CTXIF_RESET (1L<<18) #define BNX2_RV2P_STATUS 0x00002804 #define BNX2_RV2P_STATUS_ALWAYS_0 (1L<<0) #define BNX2_RV2P_STATUS_RV2P_GEN_STAT0_CNT (1L<<8) #define BNX2_RV2P_STATUS_RV2P_GEN_STAT1_CNT (1L<<9) #define BNX2_RV2P_STATUS_RV2P_GEN_STAT2_CNT (1L<<10) #define BNX2_RV2P_STATUS_RV2P_GEN_STAT3_CNT (1L<<11) #define BNX2_RV2P_STATUS_RV2P_GEN_STAT4_CNT (1L<<12) #define BNX2_RV2P_STATUS_RV2P_GEN_STAT5_CNT (1L<<13) #define BNX2_RV2P_CONFIG 0x00002808 #define BNX2_RV2P_CONFIG_STALL_PROC1 (1L<<0) #define BNX2_RV2P_CONFIG_STALL_PROC2 (1L<<1) #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT0 (1L<<8) #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT1 (1L<<9) #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT2 (1L<<10) #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT3 (1L<<11) #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT4 (1L<<12) #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT5 (1L<<13) #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT0 (1L<<16) #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT1 (1L<<17) #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT2 (1L<<18) #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT3 (1L<<19) #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT4 (1L<<20) #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT5 (1L<<21) #define BNX2_RV2P_CONFIG_PAGE_SIZE (0xfL<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_256 (0L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_512 (1L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_1K (2L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_2K (3L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_4K (4L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_8K (5L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_16K (6L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_32K (7L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_64K (8L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_128K (9L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_256K (10L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_512K (11L<<24) #define BNX2_RV2P_CONFIG_PAGE_SIZE_1M (12L<<24) #define BNX2_RV2P_GEN_BFR_ADDR_0 0x00002810 #define BNX2_RV2P_GEN_BFR_ADDR_0_VALUE (0xffffL<<16) #define BNX2_RV2P_GEN_BFR_ADDR_1 0x00002814 #define BNX2_RV2P_GEN_BFR_ADDR_1_VALUE (0xffffL<<16) #define BNX2_RV2P_GEN_BFR_ADDR_2 0x00002818 #define BNX2_RV2P_GEN_BFR_ADDR_2_VALUE (0xffffL<<16) #define BNX2_RV2P_GEN_BFR_ADDR_3 0x0000281c #define BNX2_RV2P_GEN_BFR_ADDR_3_VALUE (0xffffL<<16) #define BNX2_RV2P_INSTR_HIGH 0x00002830 #define BNX2_RV2P_INSTR_HIGH_HIGH (0x1fL<<0) #define BNX2_RV2P_INSTR_LOW 0x00002834 #define BNX2_RV2P_PROC1_ADDR_CMD 0x00002838 #define BNX2_RV2P_PROC1_ADDR_CMD_ADD (0x3ffL<<0) #define BNX2_RV2P_PROC1_ADDR_CMD_RDWR (1L<<31) #define BNX2_RV2P_PROC2_ADDR_CMD 0x0000283c #define BNX2_RV2P_PROC2_ADDR_CMD_ADD (0x3ffL<<0) #define BNX2_RV2P_PROC2_ADDR_CMD_RDWR (1L<<31) #define BNX2_RV2P_PROC1_GRC_DEBUG 0x00002840 #define BNX2_RV2P_PROC2_GRC_DEBUG 0x00002844 #define BNX2_RV2P_GRC_PROC_DEBUG 0x00002848 #define BNX2_RV2P_DEBUG_VECT_PEEK 0x0000284c #define BNX2_RV2P_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) #define BNX2_RV2P_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) #define BNX2_RV2P_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) #define BNX2_RV2P_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) #define BNX2_RV2P_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) #define BNX2_RV2P_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) #define BNX2_RV2P_PFTQ_DATA 0x00002b40 #define BNX2_RV2P_PFTQ_CMD 0x00002b78 #define BNX2_RV2P_PFTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_RV2P_PFTQ_CMD_WR_TOP (1L<<10) #define BNX2_RV2P_PFTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_RV2P_PFTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_RV2P_PFTQ_CMD_SFT_RESET (1L<<25) #define BNX2_RV2P_PFTQ_CMD_RD_DATA (1L<<26) #define BNX2_RV2P_PFTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_RV2P_PFTQ_CMD_ADD_DATA (1L<<28) #define BNX2_RV2P_PFTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_RV2P_PFTQ_CMD_POP (1L<<30) #define BNX2_RV2P_PFTQ_CMD_BUSY (1L<<31) #define BNX2_RV2P_PFTQ_CTL 0x00002b7c #define BNX2_RV2P_PFTQ_CTL_INTERVENE (1L<<0) #define BNX2_RV2P_PFTQ_CTL_OVERFLOW (1L<<1) #define BNX2_RV2P_PFTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_RV2P_PFTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_RV2P_PFTQ_CTL_CUR_DEPTH (0x3ffL<<22) #define BNX2_RV2P_TFTQ_DATA 0x00002b80 #define BNX2_RV2P_TFTQ_CMD 0x00002bb8 #define BNX2_RV2P_TFTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_RV2P_TFTQ_CMD_WR_TOP (1L<<10) #define BNX2_RV2P_TFTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_RV2P_TFTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_RV2P_TFTQ_CMD_SFT_RESET (1L<<25) #define BNX2_RV2P_TFTQ_CMD_RD_DATA (1L<<26) #define BNX2_RV2P_TFTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_RV2P_TFTQ_CMD_ADD_DATA (1L<<28) #define BNX2_RV2P_TFTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_RV2P_TFTQ_CMD_POP (1L<<30) #define BNX2_RV2P_TFTQ_CMD_BUSY (1L<<31) #define BNX2_RV2P_TFTQ_CTL 0x00002bbc #define BNX2_RV2P_TFTQ_CTL_INTERVENE (1L<<0) #define BNX2_RV2P_TFTQ_CTL_OVERFLOW (1L<<1) #define BNX2_RV2P_TFTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_RV2P_TFTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_RV2P_TFTQ_CTL_CUR_DEPTH (0x3ffL<<22) #define BNX2_RV2P_MFTQ_DATA 0x00002bc0 #define BNX2_RV2P_MFTQ_CMD 0x00002bf8 #define BNX2_RV2P_MFTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_RV2P_MFTQ_CMD_WR_TOP (1L<<10) #define BNX2_RV2P_MFTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_RV2P_MFTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_RV2P_MFTQ_CMD_SFT_RESET (1L<<25) #define BNX2_RV2P_MFTQ_CMD_RD_DATA (1L<<26) #define BNX2_RV2P_MFTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_RV2P_MFTQ_CMD_ADD_DATA (1L<<28) #define BNX2_RV2P_MFTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_RV2P_MFTQ_CMD_POP (1L<<30) #define BNX2_RV2P_MFTQ_CMD_BUSY (1L<<31) #define BNX2_RV2P_MFTQ_CTL 0x00002bfc #define BNX2_RV2P_MFTQ_CTL_INTERVENE (1L<<0) #define BNX2_RV2P_MFTQ_CTL_OVERFLOW (1L<<1) #define BNX2_RV2P_MFTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_RV2P_MFTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_RV2P_MFTQ_CTL_CUR_DEPTH (0x3ffL<<22) /* * mq_reg definition * offset: 0x3c00 */ #define BNX2_MQ_COMMAND 0x00003c00 #define BNX2_MQ_COMMAND_ENABLED (1L<<0) #define BNX2_MQ_COMMAND_OVERFLOW (1L<<4) #define BNX2_MQ_COMMAND_WR_ERROR (1L<<5) #define BNX2_MQ_COMMAND_RD_ERROR (1L<<6) #define BNX2_MQ_STATUS 0x00003c04 #define BNX2_MQ_STATUS_CTX_ACCESS_STAT (1L<<16) #define BNX2_MQ_STATUS_CTX_ACCESS64_STAT (1L<<17) #define BNX2_MQ_STATUS_PCI_STALL_STAT (1L<<18) #define BNX2_MQ_CONFIG 0x00003c08 #define BNX2_MQ_CONFIG_TX_HIGH_PRI (1L<<0) #define BNX2_MQ_CONFIG_HALT_DIS (1L<<1) #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE (0x7L<<4) #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256 (0L<<4) #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_512 (1L<<4) #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_1K (2L<<4) #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_2K (3L<<4) #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_4K (4L<<4) #define BNX2_MQ_CONFIG_MAX_DEPTH (0x7fL<<8) #define BNX2_MQ_CONFIG_CUR_DEPTH (0x7fL<<20) #define BNX2_MQ_ENQUEUE1 0x00003c0c #define BNX2_MQ_ENQUEUE1_OFFSET (0x3fL<<2) #define BNX2_MQ_ENQUEUE1_CID (0x3fffL<<8) #define BNX2_MQ_ENQUEUE1_BYTE_MASK (0xfL<<24) #define BNX2_MQ_ENQUEUE1_KNL_MODE (1L<<28) #define BNX2_MQ_ENQUEUE2 0x00003c10 #define BNX2_MQ_BAD_WR_ADDR 0x00003c14 #define BNX2_MQ_BAD_RD_ADDR 0x00003c18 #define BNX2_MQ_KNL_BYP_WIND_START 0x00003c1c #define BNX2_MQ_KNL_BYP_WIND_START_VALUE (0xfffffL<<12) #define BNX2_MQ_KNL_WIND_END 0x00003c20 #define BNX2_MQ_KNL_WIND_END_VALUE (0xffffffL<<8) #define BNX2_MQ_KNL_WRITE_MASK1 0x00003c24 #define BNX2_MQ_KNL_TX_MASK1 0x00003c28 #define BNX2_MQ_KNL_CMD_MASK1 0x00003c2c #define BNX2_MQ_KNL_COND_ENQUEUE_MASK1 0x00003c30 #define BNX2_MQ_KNL_RX_V2P_MASK1 0x00003c34 #define BNX2_MQ_KNL_WRITE_MASK2 0x00003c38 #define BNX2_MQ_KNL_TX_MASK2 0x00003c3c #define BNX2_MQ_KNL_CMD_MASK2 0x00003c40 #define BNX2_MQ_KNL_COND_ENQUEUE_MASK2 0x00003c44 #define BNX2_MQ_KNL_RX_V2P_MASK2 0x00003c48 #define BNX2_MQ_KNL_BYP_WRITE_MASK1 0x00003c4c #define BNX2_MQ_KNL_BYP_TX_MASK1 0x00003c50 #define BNX2_MQ_KNL_BYP_CMD_MASK1 0x00003c54 #define BNX2_MQ_KNL_BYP_COND_ENQUEUE_MASK1 0x00003c58 #define BNX2_MQ_KNL_BYP_RX_V2P_MASK1 0x00003c5c #define BNX2_MQ_KNL_BYP_WRITE_MASK2 0x00003c60 #define BNX2_MQ_KNL_BYP_TX_MASK2 0x00003c64 #define BNX2_MQ_KNL_BYP_CMD_MASK2 0x00003c68 #define BNX2_MQ_KNL_BYP_COND_ENQUEUE_MASK2 0x00003c6c #define BNX2_MQ_KNL_BYP_RX_V2P_MASK2 0x00003c70 #define BNX2_MQ_MEM_WR_ADDR 0x00003c74 #define BNX2_MQ_MEM_WR_ADDR_VALUE (0x3fL<<0) #define BNX2_MQ_MEM_WR_DATA0 0x00003c78 #define BNX2_MQ_MEM_WR_DATA0_VALUE (0xffffffffL<<0) #define BNX2_MQ_MEM_WR_DATA1 0x00003c7c #define BNX2_MQ_MEM_WR_DATA1_VALUE (0xffffffffL<<0) #define BNX2_MQ_MEM_WR_DATA2 0x00003c80 #define BNX2_MQ_MEM_WR_DATA2_VALUE (0x3fffffffL<<0) #define BNX2_MQ_MEM_RD_ADDR 0x00003c84 #define BNX2_MQ_MEM_RD_ADDR_VALUE (0x3fL<<0) #define BNX2_MQ_MEM_RD_DATA0 0x00003c88 #define BNX2_MQ_MEM_RD_DATA0_VALUE (0xffffffffL<<0) #define BNX2_MQ_MEM_RD_DATA1 0x00003c8c #define BNX2_MQ_MEM_RD_DATA1_VALUE (0xffffffffL<<0) #define BNX2_MQ_MEM_RD_DATA2 0x00003c90 #define BNX2_MQ_MEM_RD_DATA2_VALUE (0x3fffffffL<<0) /* * tbdr_reg definition * offset: 0x5000 */ #define BNX2_TBDR_COMMAND 0x00005000 #define BNX2_TBDR_COMMAND_ENABLE (1L<<0) #define BNX2_TBDR_COMMAND_SOFT_RST (1L<<1) #define BNX2_TBDR_COMMAND_MSTR_ABORT (1L<<4) #define BNX2_TBDR_STATUS 0x00005004 #define BNX2_TBDR_STATUS_DMA_WAIT (1L<<0) #define BNX2_TBDR_STATUS_FTQ_WAIT (1L<<1) #define BNX2_TBDR_STATUS_FIFO_OVERFLOW (1L<<2) #define BNX2_TBDR_STATUS_FIFO_UNDERFLOW (1L<<3) #define BNX2_TBDR_STATUS_SEARCHMISS_ERROR (1L<<4) #define BNX2_TBDR_STATUS_FTQ_ENTRY_CNT (1L<<5) #define BNX2_TBDR_STATUS_BURST_CNT (1L<<6) #define BNX2_TBDR_CONFIG 0x00005008 #define BNX2_TBDR_CONFIG_MAX_BDS (0xffL<<0) #define BNX2_TBDR_CONFIG_SWAP_MODE (1L<<8) #define BNX2_TBDR_CONFIG_PRIORITY (1L<<9) #define BNX2_TBDR_CONFIG_CACHE_NEXT_PAGE_PTRS (1L<<10) #define BNX2_TBDR_CONFIG_PAGE_SIZE (0xfL<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_256 (0L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_512 (1L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_1K (2L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_2K (3L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_4K (4L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_8K (5L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_16K (6L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_32K (7L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_64K (8L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_128K (9L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_256K (10L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_512K (11L<<24) #define BNX2_TBDR_CONFIG_PAGE_SIZE_1M (12L<<24) #define BNX2_TBDR_DEBUG_VECT_PEEK 0x0000500c #define BNX2_TBDR_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) #define BNX2_TBDR_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) #define BNX2_TBDR_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) #define BNX2_TBDR_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) #define BNX2_TBDR_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) #define BNX2_TBDR_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) #define BNX2_TBDR_FTQ_DATA 0x000053c0 #define BNX2_TBDR_FTQ_CMD 0x000053f8 #define BNX2_TBDR_FTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_TBDR_FTQ_CMD_WR_TOP (1L<<10) #define BNX2_TBDR_FTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_TBDR_FTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_TBDR_FTQ_CMD_SFT_RESET (1L<<25) #define BNX2_TBDR_FTQ_CMD_RD_DATA (1L<<26) #define BNX2_TBDR_FTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_TBDR_FTQ_CMD_ADD_DATA (1L<<28) #define BNX2_TBDR_FTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_TBDR_FTQ_CMD_POP (1L<<30) #define BNX2_TBDR_FTQ_CMD_BUSY (1L<<31) #define BNX2_TBDR_FTQ_CTL 0x000053fc #define BNX2_TBDR_FTQ_CTL_INTERVENE (1L<<0) #define BNX2_TBDR_FTQ_CTL_OVERFLOW (1L<<1) #define BNX2_TBDR_FTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_TBDR_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_TBDR_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) /* * tdma_reg definition * offset: 0x5c00 */ #define BNX2_TDMA_COMMAND 0x00005c00 #define BNX2_TDMA_COMMAND_ENABLED (1L<<0) #define BNX2_TDMA_COMMAND_MASTER_ABORT (1L<<4) #define BNX2_TDMA_COMMAND_BAD_L2_LENGTH_ABORT (1L<<7) #define BNX2_TDMA_STATUS 0x00005c04 #define BNX2_TDMA_STATUS_DMA_WAIT (1L<<0) #define BNX2_TDMA_STATUS_PAYLOAD_WAIT (1L<<1) #define BNX2_TDMA_STATUS_PATCH_FTQ_WAIT (1L<<2) #define BNX2_TDMA_STATUS_LOCK_WAIT (1L<<3) #define BNX2_TDMA_STATUS_FTQ_ENTRY_CNT (1L<<16) #define BNX2_TDMA_STATUS_BURST_CNT (1L<<17) #define BNX2_TDMA_CONFIG 0x00005c08 #define BNX2_TDMA_CONFIG_ONE_DMA (1L<<0) #define BNX2_TDMA_CONFIG_ONE_RECORD (1L<<1) #define BNX2_TDMA_CONFIG_LIMIT_SZ (0xfL<<4) #define BNX2_TDMA_CONFIG_LIMIT_SZ_64 (0L<<4) #define BNX2_TDMA_CONFIG_LIMIT_SZ_128 (0x4L<<4) #define BNX2_TDMA_CONFIG_LIMIT_SZ_256 (0x6L<<4) #define BNX2_TDMA_CONFIG_LIMIT_SZ_512 (0x8L<<4) #define BNX2_TDMA_CONFIG_LINE_SZ (0xfL<<8) #define BNX2_TDMA_CONFIG_LINE_SZ_64 (0L<<8) #define BNX2_TDMA_CONFIG_LINE_SZ_128 (4L<<8) #define BNX2_TDMA_CONFIG_LINE_SZ_256 (6L<<8) #define BNX2_TDMA_CONFIG_LINE_SZ_512 (8L<<8) #define BNX2_TDMA_CONFIG_ALIGN_ENA (1L<<15) #define BNX2_TDMA_CONFIG_CHK_L2_BD (1L<<16) #define BNX2_TDMA_CONFIG_FIFO_CMP (0xfL<<20) #define BNX2_TDMA_PAYLOAD_PROD 0x00005c0c #define BNX2_TDMA_PAYLOAD_PROD_VALUE (0x1fffL<<3) #define BNX2_TDMA_DBG_WATCHDOG 0x00005c10 #define BNX2_TDMA_DBG_TRIGGER 0x00005c14 #define BNX2_TDMA_DMAD_FSM 0x00005c80 #define BNX2_TDMA_DMAD_FSM_BD_INVLD (1L<<0) #define BNX2_TDMA_DMAD_FSM_PUSH (0xfL<<4) #define BNX2_TDMA_DMAD_FSM_ARB_TBDC (0x3L<<8) #define BNX2_TDMA_DMAD_FSM_ARB_CTX (1L<<12) #define BNX2_TDMA_DMAD_FSM_DR_INTF (1L<<16) #define BNX2_TDMA_DMAD_FSM_DMAD (0x7L<<20) #define BNX2_TDMA_DMAD_FSM_BD (0xfL<<24) #define BNX2_TDMA_DMAD_STATUS 0x00005c84 #define BNX2_TDMA_DMAD_STATUS_RHOLD_PUSH_ENTRY (0x3L<<0) #define BNX2_TDMA_DMAD_STATUS_RHOLD_DMAD_ENTRY (0x3L<<4) #define BNX2_TDMA_DMAD_STATUS_RHOLD_BD_ENTRY (0x3L<<8) #define BNX2_TDMA_DMAD_STATUS_IFTQ_ENUM (0xfL<<12) #define BNX2_TDMA_DR_INTF_FSM 0x00005c88 #define BNX2_TDMA_DR_INTF_FSM_L2_COMP (0x3L<<0) #define BNX2_TDMA_DR_INTF_FSM_TPATQ (0x7L<<4) #define BNX2_TDMA_DR_INTF_FSM_TPBUF (0x3L<<8) #define BNX2_TDMA_DR_INTF_FSM_DR_BUF (0x7L<<12) #define BNX2_TDMA_DR_INTF_FSM_DMAD (0x7L<<16) #define BNX2_TDMA_DR_INTF_STATUS 0x00005c8c #define BNX2_TDMA_DR_INTF_STATUS_HOLE_PHASE (0x7L<<0) #define BNX2_TDMA_DR_INTF_STATUS_DATA_AVAIL (0x3L<<4) #define BNX2_TDMA_DR_INTF_STATUS_SHIFT_ADDR (0x7L<<8) #define BNX2_TDMA_DR_INTF_STATUS_NXT_PNTR (0xfL<<12) #define BNX2_TDMA_DR_INTF_STATUS_BYTE_COUNT (0x7L<<16) #define BNX2_TDMA_FTQ_DATA 0x00005fc0 #define BNX2_TDMA_FTQ_CMD 0x00005ff8 #define BNX2_TDMA_FTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_TDMA_FTQ_CMD_WR_TOP (1L<<10) #define BNX2_TDMA_FTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_TDMA_FTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_TDMA_FTQ_CMD_SFT_RESET (1L<<25) #define BNX2_TDMA_FTQ_CMD_RD_DATA (1L<<26) #define BNX2_TDMA_FTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_TDMA_FTQ_CMD_ADD_DATA (1L<<28) #define BNX2_TDMA_FTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_TDMA_FTQ_CMD_POP (1L<<30) #define BNX2_TDMA_FTQ_CMD_BUSY (1L<<31) #define BNX2_TDMA_FTQ_CTL 0x00005ffc #define BNX2_TDMA_FTQ_CTL_INTERVENE (1L<<0) #define BNX2_TDMA_FTQ_CTL_OVERFLOW (1L<<1) #define BNX2_TDMA_FTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_TDMA_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_TDMA_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) /* * hc_reg definition * offset: 0x6800 */ #define BNX2_HC_COMMAND 0x00006800 #define BNX2_HC_COMMAND_ENABLE (1L<<0) #define BNX2_HC_COMMAND_SKIP_ABORT (1L<<4) #define BNX2_HC_COMMAND_COAL_NOW (1L<<16) #define BNX2_HC_COMMAND_COAL_NOW_WO_INT (1L<<17) #define BNX2_HC_COMMAND_STATS_NOW (1L<<18) #define BNX2_HC_COMMAND_FORCE_INT (0x3L<<19) #define BNX2_HC_COMMAND_FORCE_INT_NULL (0L<<19) #define BNX2_HC_COMMAND_FORCE_INT_HIGH (1L<<19) #define BNX2_HC_COMMAND_FORCE_INT_LOW (2L<<19) #define BNX2_HC_COMMAND_FORCE_INT_FREE (3L<<19) #define BNX2_HC_COMMAND_CLR_STAT_NOW (1L<<21) #define BNX2_HC_STATUS 0x00006804 #define BNX2_HC_STATUS_MASTER_ABORT (1L<<0) #define BNX2_HC_STATUS_PARITY_ERROR_STATE (1L<<1) #define BNX2_HC_STATUS_PCI_CLK_CNT_STAT (1L<<16) #define BNX2_HC_STATUS_CORE_CLK_CNT_STAT (1L<<17) #define BNX2_HC_STATUS_NUM_STATUS_BLOCKS_STAT (1L<<18) #define BNX2_HC_STATUS_NUM_INT_GEN_STAT (1L<<19) #define BNX2_HC_STATUS_NUM_INT_MBOX_WR_STAT (1L<<20) #define BNX2_HC_STATUS_CORE_CLKS_TO_HW_INTACK_STAT (1L<<23) #define BNX2_HC_STATUS_CORE_CLKS_TO_SW_INTACK_STAT (1L<<24) #define BNX2_HC_STATUS_CORE_CLKS_DURING_SW_INTACK_STAT (1L<<25) #define BNX2_HC_CONFIG 0x00006808 #define BNX2_HC_CONFIG_COLLECT_STATS (1L<<0) #define BNX2_HC_CONFIG_RX_TMR_MODE (1L<<1) #define BNX2_HC_CONFIG_TX_TMR_MODE (1L<<2) #define BNX2_HC_CONFIG_COM_TMR_MODE (1L<<3) #define BNX2_HC_CONFIG_CMD_TMR_MODE (1L<<4) #define BNX2_HC_CONFIG_STATISTIC_PRIORITY (1L<<5) #define BNX2_HC_CONFIG_STATUS_PRIORITY (1L<<6) #define BNX2_HC_CONFIG_STAT_MEM_ADDR (0xffL<<8) #define BNX2_HC_ATTN_BITS_ENABLE 0x0000680c #define BNX2_HC_STATUS_ADDR_L 0x00006810 #define BNX2_HC_STATUS_ADDR_H 0x00006814 #define BNX2_HC_STATISTICS_ADDR_L 0x00006818 #define BNX2_HC_STATISTICS_ADDR_H 0x0000681c #define BNX2_HC_TX_QUICK_CONS_TRIP 0x00006820 #define BNX2_HC_TX_QUICK_CONS_TRIP_VALUE (0xffL<<0) #define BNX2_HC_TX_QUICK_CONS_TRIP_INT (0xffL<<16) #define BNX2_HC_COMP_PROD_TRIP 0x00006824 #define BNX2_HC_COMP_PROD_TRIP_VALUE (0xffL<<0) #define BNX2_HC_COMP_PROD_TRIP_INT (0xffL<<16) #define BNX2_HC_RX_QUICK_CONS_TRIP 0x00006828 #define BNX2_HC_RX_QUICK_CONS_TRIP_VALUE (0xffL<<0) #define BNX2_HC_RX_QUICK_CONS_TRIP_INT (0xffL<<16) #define BNX2_HC_RX_TICKS 0x0000682c #define BNX2_HC_RX_TICKS_VALUE (0x3ffL<<0) #define BNX2_HC_RX_TICKS_INT (0x3ffL<<16) #define BNX2_HC_TX_TICKS 0x00006830 #define BNX2_HC_TX_TICKS_VALUE (0x3ffL<<0) #define BNX2_HC_TX_TICKS_INT (0x3ffL<<16) #define BNX2_HC_COM_TICKS 0x00006834 #define BNX2_HC_COM_TICKS_VALUE (0x3ffL<<0) #define BNX2_HC_COM_TICKS_INT (0x3ffL<<16) #define BNX2_HC_CMD_TICKS 0x00006838 #define BNX2_HC_CMD_TICKS_VALUE (0x3ffL<<0) #define BNX2_HC_CMD_TICKS_INT (0x3ffL<<16) #define BNX2_HC_PERIODIC_TICKS 0x0000683c #define BNX2_HC_PERIODIC_TICKS_HC_PERIODIC_TICKS (0xffffL<<0) #define BNX2_HC_STAT_COLLECT_TICKS 0x00006840 #define BNX2_HC_STAT_COLLECT_TICKS_HC_STAT_COLL_TICKS (0xffL<<4) #define BNX2_HC_STATS_TICKS 0x00006844 #define BNX2_HC_STATS_TICKS_HC_STAT_TICKS (0xffffL<<8) #define BNX2_HC_STAT_MEM_DATA 0x0000684c #define BNX2_HC_STAT_GEN_SEL_0 0x00006850 #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0 (0x7fL<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT0 (0L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT1 (1L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT2 (2L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT3 (3L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT4 (4L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT5 (5L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT6 (6L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT7 (7L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT8 (8L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT9 (9L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT10 (10L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT11 (11L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT0 (12L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT1 (13L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT2 (14L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT3 (15L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT4 (16L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT5 (17L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT6 (18L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT7 (19L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT0 (20L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT1 (21L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT2 (22L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT3 (23L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT4 (24L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT5 (25L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT6 (26L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT7 (27L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT8 (28L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT9 (29L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT10 (30L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT11 (31L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT0 (32L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT1 (33L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT2 (34L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT3 (35L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT0 (36L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT1 (37L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT2 (38L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT3 (39L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT4 (40L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT5 (41L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT6 (42L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT7 (43L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT0 (44L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT1 (45L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT2 (46L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT3 (47L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT4 (48L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT5 (49L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT6 (50L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT7 (51L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_PCI_CLK_CNT (52L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CORE_CLK_CNT (53L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS (54L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN (55L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR (56L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK (59L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK (60L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK (61L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCH_CMD_CNT (62L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCH_SLOT_CNT (63L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSCH_CMD_CNT (64L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSCH_SLOT_CNT (65L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT (66L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT (67L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT (68L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT (69L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT (70L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT (71L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT (72L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT (73L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT (74L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT (75L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT (76L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT (77L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT (78L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT (79L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT (80L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT (81L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT (82L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT (83L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT (84L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_READ_TRANSFERS_CNT (85L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_READ_DELAY_PCI_CLKS_CNT (86L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_TRANSFERS_CNT (87L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_DELAY_PCI_CLKS_CNT (88L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_RETRY_AFTER_DATA_CNT (89L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_WRITE_TRANSFERS_CNT (90L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_WRITE_DELAY_PCI_CLKS_CNT (91L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_TRANSFERS_CNT (92L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_DELAY_PCI_CLKS_CNT (93L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_RETRY_AFTER_DATA_CNT (94L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_WR_CNT64 (95L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_RD_CNT64 (96L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_ACC_STALL_CLKS (97L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_LOCK_STALL_CLKS (98L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_CTX_ACCESS_STAT (99L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_CTX_ACCESS64_STAT (100L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_PCI_STALL_STAT (101L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDR_FTQ_ENTRY_CNT (102L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDR_BURST_CNT (103L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMA_FTQ_ENTRY_CNT (104L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMA_BURST_CNT (105L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMA_FTQ_ENTRY_CNT (106L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMA_BURST_CNT (107L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUP_MATCH_CNT (108L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_POLL_PASS_CNT (109L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR1_CNT (110L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR2_CNT (111L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR3_CNT (112L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR4_CNT (113L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR5_CNT (114L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT0 (115L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT1 (116L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT2 (117L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT3 (118L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT4 (119L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT5 (120L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_PROC1_MISS (121L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_PROC2_MISS (122L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_BURST_CNT (127L<<0) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_1 (0x7fL<<8) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_2 (0x7fL<<16) #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_3 (0x7fL<<24) #define BNX2_HC_STAT_GEN_SEL_1 0x00006854 #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_4 (0x7fL<<0) #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_5 (0x7fL<<8) #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_6 (0x7fL<<16) #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_7 (0x7fL<<24) #define BNX2_HC_STAT_GEN_SEL_2 0x00006858 #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_8 (0x7fL<<0) #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_9 (0x7fL<<8) #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_10 (0x7fL<<16) #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_11 (0x7fL<<24) #define BNX2_HC_STAT_GEN_SEL_3 0x0000685c #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_12 (0x7fL<<0) #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_13 (0x7fL<<8) #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_14 (0x7fL<<16) #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_15 (0x7fL<<24) #define BNX2_HC_STAT_GEN_STAT0 0x00006888 #define BNX2_HC_STAT_GEN_STAT1 0x0000688c #define BNX2_HC_STAT_GEN_STAT2 0x00006890 #define BNX2_HC_STAT_GEN_STAT3 0x00006894 #define BNX2_HC_STAT_GEN_STAT4 0x00006898 #define BNX2_HC_STAT_GEN_STAT5 0x0000689c #define BNX2_HC_STAT_GEN_STAT6 0x000068a0 #define BNX2_HC_STAT_GEN_STAT7 0x000068a4 #define BNX2_HC_STAT_GEN_STAT8 0x000068a8 #define BNX2_HC_STAT_GEN_STAT9 0x000068ac #define BNX2_HC_STAT_GEN_STAT10 0x000068b0 #define BNX2_HC_STAT_GEN_STAT11 0x000068b4 #define BNX2_HC_STAT_GEN_STAT12 0x000068b8 #define BNX2_HC_STAT_GEN_STAT13 0x000068bc #define BNX2_HC_STAT_GEN_STAT14 0x000068c0 #define BNX2_HC_STAT_GEN_STAT15 0x000068c4 #define BNX2_HC_STAT_GEN_STAT_AC0 0x000068c8 #define BNX2_HC_STAT_GEN_STAT_AC1 0x000068cc #define BNX2_HC_STAT_GEN_STAT_AC2 0x000068d0 #define BNX2_HC_STAT_GEN_STAT_AC3 0x000068d4 #define BNX2_HC_STAT_GEN_STAT_AC4 0x000068d8 #define BNX2_HC_STAT_GEN_STAT_AC5 0x000068dc #define BNX2_HC_STAT_GEN_STAT_AC6 0x000068e0 #define BNX2_HC_STAT_GEN_STAT_AC7 0x000068e4 #define BNX2_HC_STAT_GEN_STAT_AC8 0x000068e8 #define BNX2_HC_STAT_GEN_STAT_AC9 0x000068ec #define BNX2_HC_STAT_GEN_STAT_AC10 0x000068f0 #define BNX2_HC_STAT_GEN_STAT_AC11 0x000068f4 #define BNX2_HC_STAT_GEN_STAT_AC12 0x000068f8 #define BNX2_HC_STAT_GEN_STAT_AC13 0x000068fc #define BNX2_HC_STAT_GEN_STAT_AC14 0x00006900 #define BNX2_HC_STAT_GEN_STAT_AC15 0x00006904 #define BNX2_HC_VIS 0x00006908 #define BNX2_HC_VIS_STAT_BUILD_STATE (0xfL<<0) #define BNX2_HC_VIS_STAT_BUILD_STATE_IDLE (0L<<0) #define BNX2_HC_VIS_STAT_BUILD_STATE_START (1L<<0) #define BNX2_HC_VIS_STAT_BUILD_STATE_REQUEST (2L<<0) #define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE64 (3L<<0) #define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE32 (4L<<0) #define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE_DONE (5L<<0) #define BNX2_HC_VIS_STAT_BUILD_STATE_DMA (6L<<0) #define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_CONTROL (7L<<0) #define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_LOW (8L<<0) #define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_HIGH (9L<<0) #define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_DATA (10L<<0) #define BNX2_HC_VIS_DMA_STAT_STATE (0xfL<<8) #define BNX2_HC_VIS_DMA_STAT_STATE_IDLE (0L<<8) #define BNX2_HC_VIS_DMA_STAT_STATE_STATUS_PARAM (1L<<8) #define BNX2_HC_VIS_DMA_STAT_STATE_STATUS_DMA (2L<<8) #define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP (3L<<8) #define BNX2_HC_VIS_DMA_STAT_STATE_COMP (4L<<8) #define BNX2_HC_VIS_DMA_STAT_STATE_STATISTIC_PARAM (5L<<8) #define BNX2_HC_VIS_DMA_STAT_STATE_STATISTIC_DMA (6L<<8) #define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP_1 (7L<<8) #define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP_2 (8L<<8) #define BNX2_HC_VIS_DMA_STAT_STATE_WAIT (9L<<8) #define BNX2_HC_VIS_DMA_STAT_STATE_ABORT (15L<<8) #define BNX2_HC_VIS_DMA_MSI_STATE (0x7L<<12) #define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE (0x3L<<15) #define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_IDLE (0L<<15) #define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_COUNT (1L<<15) #define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_START (2L<<15) #define BNX2_HC_VIS_1 0x0000690c #define BNX2_HC_VIS_1_HW_INTACK_STATE (1L<<4) #define BNX2_HC_VIS_1_HW_INTACK_STATE_IDLE (0L<<4) #define BNX2_HC_VIS_1_HW_INTACK_STATE_COUNT (1L<<4) #define BNX2_HC_VIS_1_SW_INTACK_STATE (1L<<5) #define BNX2_HC_VIS_1_SW_INTACK_STATE_IDLE (0L<<5) #define BNX2_HC_VIS_1_SW_INTACK_STATE_COUNT (1L<<5) #define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE (1L<<6) #define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE_IDLE (0L<<6) #define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE_COUNT (1L<<6) #define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE (1L<<7) #define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE_IDLE (0L<<7) #define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE_COUNT (1L<<7) #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE (0xfL<<17) #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_IDLE (0L<<17) #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_DMA (1L<<17) #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_UPDATE (2L<<17) #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_ASSIGN (3L<<17) #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_WAIT (4L<<17) #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_UPDATE (5L<<17) #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_ASSIGN (6L<<17) #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_WAIT (7L<<17) #define BNX2_HC_VIS_1_RAM_WR_ARB_STATE (0x3L<<21) #define BNX2_HC_VIS_1_RAM_WR_ARB_STATE_NORMAL (0L<<21) #define BNX2_HC_VIS_1_RAM_WR_ARB_STATE_CLEAR (1L<<21) #define BNX2_HC_VIS_1_INT_GEN_STATE (1L<<23) #define BNX2_HC_VIS_1_INT_GEN_STATE_DLE (0L<<23) #define BNX2_HC_VIS_1_INT_GEN_STATE_NTERRUPT (1L<<23) #define BNX2_HC_VIS_1_STAT_CHAN_ID (0x7L<<24) #define BNX2_HC_VIS_1_INT_B (1L<<27) #define BNX2_HC_DEBUG_VECT_PEEK 0x00006910 #define BNX2_HC_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) #define BNX2_HC_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) #define BNX2_HC_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) #define BNX2_HC_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) #define BNX2_HC_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) #define BNX2_HC_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) /* * txp_reg definition * offset: 0x40000 */ #define BNX2_TXP_CPU_MODE 0x00045000 #define BNX2_TXP_CPU_MODE_LOCAL_RST (1L<<0) #define BNX2_TXP_CPU_MODE_STEP_ENA (1L<<1) #define BNX2_TXP_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) #define BNX2_TXP_CPU_MODE_PAGE_0_INST_ENA (1L<<3) #define BNX2_TXP_CPU_MODE_MSG_BIT1 (1L<<6) #define BNX2_TXP_CPU_MODE_INTERRUPT_ENA (1L<<7) #define BNX2_TXP_CPU_MODE_SOFT_HALT (1L<<10) #define BNX2_TXP_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) #define BNX2_TXP_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) #define BNX2_TXP_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) #define BNX2_TXP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) #define BNX2_TXP_CPU_STATE 0x00045004 #define BNX2_TXP_CPU_STATE_BREAKPOINT (1L<<0) #define BNX2_TXP_CPU_STATE_BAD_INST_HALTED (1L<<2) #define BNX2_TXP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) #define BNX2_TXP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) #define BNX2_TXP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) #define BNX2_TXP_CPU_STATE_BAD_pc_HALTED (1L<<6) #define BNX2_TXP_CPU_STATE_ALIGN_HALTED (1L<<7) #define BNX2_TXP_CPU_STATE_FIO_ABORT_HALTED (1L<<8) #define BNX2_TXP_CPU_STATE_SOFT_HALTED (1L<<10) #define BNX2_TXP_CPU_STATE_SPAD_UNDERFLOW (1L<<11) #define BNX2_TXP_CPU_STATE_INTERRRUPT (1L<<12) #define BNX2_TXP_CPU_STATE_DATA_ACCESS_STALL (1L<<14) #define BNX2_TXP_CPU_STATE_INST_FETCH_STALL (1L<<15) #define BNX2_TXP_CPU_STATE_BLOCKED_READ (1L<<31) #define BNX2_TXP_CPU_EVENT_MASK 0x00045008 #define BNX2_TXP_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) #define BNX2_TXP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) #define BNX2_TXP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) #define BNX2_TXP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) #define BNX2_TXP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) #define BNX2_TXP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) #define BNX2_TXP_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) #define BNX2_TXP_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) #define BNX2_TXP_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) #define BNX2_TXP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) #define BNX2_TXP_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) #define BNX2_TXP_CPU_PROGRAM_COUNTER 0x0004501c #define BNX2_TXP_CPU_INSTRUCTION 0x00045020 #define BNX2_TXP_CPU_DATA_ACCESS 0x00045024 #define BNX2_TXP_CPU_INTERRUPT_ENABLE 0x00045028 #define BNX2_TXP_CPU_INTERRUPT_VECTOR 0x0004502c #define BNX2_TXP_CPU_INTERRUPT_SAVED_PC 0x00045030 #define BNX2_TXP_CPU_HW_BREAKPOINT 0x00045034 #define BNX2_TXP_CPU_HW_BREAKPOINT_DISABLE (1L<<0) #define BNX2_TXP_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) #define BNX2_TXP_CPU_DEBUG_VECT_PEEK 0x00045038 #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) #define BNX2_TXP_CPU_LAST_BRANCH_ADDR 0x00045048 #define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) #define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) #define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) #define BNX2_TXP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) #define BNX2_TXP_CPU_REG_FILE 0x00045200 #define BNX2_TXP_FTQ_DATA 0x000453c0 #define BNX2_TXP_FTQ_CMD 0x000453f8 #define BNX2_TXP_FTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_TXP_FTQ_CMD_WR_TOP (1L<<10) #define BNX2_TXP_FTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_TXP_FTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_TXP_FTQ_CMD_SFT_RESET (1L<<25) #define BNX2_TXP_FTQ_CMD_RD_DATA (1L<<26) #define BNX2_TXP_FTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_TXP_FTQ_CMD_ADD_DATA (1L<<28) #define BNX2_TXP_FTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_TXP_FTQ_CMD_POP (1L<<30) #define BNX2_TXP_FTQ_CMD_BUSY (1L<<31) #define BNX2_TXP_FTQ_CTL 0x000453fc #define BNX2_TXP_FTQ_CTL_INTERVENE (1L<<0) #define BNX2_TXP_FTQ_CTL_OVERFLOW (1L<<1) #define BNX2_TXP_FTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_TXP_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_TXP_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) #define BNX2_TXP_SCRATCH 0x00060000 /* * tpat_reg definition * offset: 0x80000 */ #define BNX2_TPAT_CPU_MODE 0x00085000 #define BNX2_TPAT_CPU_MODE_LOCAL_RST (1L<<0) #define BNX2_TPAT_CPU_MODE_STEP_ENA (1L<<1) #define BNX2_TPAT_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) #define BNX2_TPAT_CPU_MODE_PAGE_0_INST_ENA (1L<<3) #define BNX2_TPAT_CPU_MODE_MSG_BIT1 (1L<<6) #define BNX2_TPAT_CPU_MODE_INTERRUPT_ENA (1L<<7) #define BNX2_TPAT_CPU_MODE_SOFT_HALT (1L<<10) #define BNX2_TPAT_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) #define BNX2_TPAT_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) #define BNX2_TPAT_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) #define BNX2_TPAT_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) #define BNX2_TPAT_CPU_STATE 0x00085004 #define BNX2_TPAT_CPU_STATE_BREAKPOINT (1L<<0) #define BNX2_TPAT_CPU_STATE_BAD_INST_HALTED (1L<<2) #define BNX2_TPAT_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) #define BNX2_TPAT_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) #define BNX2_TPAT_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) #define BNX2_TPAT_CPU_STATE_BAD_pc_HALTED (1L<<6) #define BNX2_TPAT_CPU_STATE_ALIGN_HALTED (1L<<7) #define BNX2_TPAT_CPU_STATE_FIO_ABORT_HALTED (1L<<8) #define BNX2_TPAT_CPU_STATE_SOFT_HALTED (1L<<10) #define BNX2_TPAT_CPU_STATE_SPAD_UNDERFLOW (1L<<11) #define BNX2_TPAT_CPU_STATE_INTERRRUPT (1L<<12) #define BNX2_TPAT_CPU_STATE_DATA_ACCESS_STALL (1L<<14) #define BNX2_TPAT_CPU_STATE_INST_FETCH_STALL (1L<<15) #define BNX2_TPAT_CPU_STATE_BLOCKED_READ (1L<<31) #define BNX2_TPAT_CPU_EVENT_MASK 0x00085008 #define BNX2_TPAT_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) #define BNX2_TPAT_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) #define BNX2_TPAT_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) #define BNX2_TPAT_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) #define BNX2_TPAT_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) #define BNX2_TPAT_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) #define BNX2_TPAT_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) #define BNX2_TPAT_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) #define BNX2_TPAT_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) #define BNX2_TPAT_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) #define BNX2_TPAT_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) #define BNX2_TPAT_CPU_PROGRAM_COUNTER 0x0008501c #define BNX2_TPAT_CPU_INSTRUCTION 0x00085020 #define BNX2_TPAT_CPU_DATA_ACCESS 0x00085024 #define BNX2_TPAT_CPU_INTERRUPT_ENABLE 0x00085028 #define BNX2_TPAT_CPU_INTERRUPT_VECTOR 0x0008502c #define BNX2_TPAT_CPU_INTERRUPT_SAVED_PC 0x00085030 #define BNX2_TPAT_CPU_HW_BREAKPOINT 0x00085034 #define BNX2_TPAT_CPU_HW_BREAKPOINT_DISABLE (1L<<0) #define BNX2_TPAT_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK 0x00085038 #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) #define BNX2_TPAT_CPU_LAST_BRANCH_ADDR 0x00085048 #define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) #define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) #define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) #define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) #define BNX2_TPAT_CPU_REG_FILE 0x00085200 #define BNX2_TPAT_FTQ_DATA 0x000853c0 #define BNX2_TPAT_FTQ_CMD 0x000853f8 #define BNX2_TPAT_FTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_TPAT_FTQ_CMD_WR_TOP (1L<<10) #define BNX2_TPAT_FTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_TPAT_FTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_TPAT_FTQ_CMD_SFT_RESET (1L<<25) #define BNX2_TPAT_FTQ_CMD_RD_DATA (1L<<26) #define BNX2_TPAT_FTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_TPAT_FTQ_CMD_ADD_DATA (1L<<28) #define BNX2_TPAT_FTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_TPAT_FTQ_CMD_POP (1L<<30) #define BNX2_TPAT_FTQ_CMD_BUSY (1L<<31) #define BNX2_TPAT_FTQ_CTL 0x000853fc #define BNX2_TPAT_FTQ_CTL_INTERVENE (1L<<0) #define BNX2_TPAT_FTQ_CTL_OVERFLOW (1L<<1) #define BNX2_TPAT_FTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_TPAT_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_TPAT_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) #define BNX2_TPAT_SCRATCH 0x000a0000 /* * rxp_reg definition * offset: 0xc0000 */ #define BNX2_RXP_CPU_MODE 0x000c5000 #define BNX2_RXP_CPU_MODE_LOCAL_RST (1L<<0) #define BNX2_RXP_CPU_MODE_STEP_ENA (1L<<1) #define BNX2_RXP_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) #define BNX2_RXP_CPU_MODE_PAGE_0_INST_ENA (1L<<3) #define BNX2_RXP_CPU_MODE_MSG_BIT1 (1L<<6) #define BNX2_RXP_CPU_MODE_INTERRUPT_ENA (1L<<7) #define BNX2_RXP_CPU_MODE_SOFT_HALT (1L<<10) #define BNX2_RXP_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) #define BNX2_RXP_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) #define BNX2_RXP_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) #define BNX2_RXP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) #define BNX2_RXP_CPU_STATE 0x000c5004 #define BNX2_RXP_CPU_STATE_BREAKPOINT (1L<<0) #define BNX2_RXP_CPU_STATE_BAD_INST_HALTED (1L<<2) #define BNX2_RXP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) #define BNX2_RXP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) #define BNX2_RXP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) #define BNX2_RXP_CPU_STATE_BAD_pc_HALTED (1L<<6) #define BNX2_RXP_CPU_STATE_ALIGN_HALTED (1L<<7) #define BNX2_RXP_CPU_STATE_FIO_ABORT_HALTED (1L<<8) #define BNX2_RXP_CPU_STATE_SOFT_HALTED (1L<<10) #define BNX2_RXP_CPU_STATE_SPAD_UNDERFLOW (1L<<11) #define BNX2_RXP_CPU_STATE_INTERRRUPT (1L<<12) #define BNX2_RXP_CPU_STATE_DATA_ACCESS_STALL (1L<<14) #define BNX2_RXP_CPU_STATE_INST_FETCH_STALL (1L<<15) #define BNX2_RXP_CPU_STATE_BLOCKED_READ (1L<<31) #define BNX2_RXP_CPU_EVENT_MASK 0x000c5008 #define BNX2_RXP_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) #define BNX2_RXP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) #define BNX2_RXP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) #define BNX2_RXP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) #define BNX2_RXP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) #define BNX2_RXP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) #define BNX2_RXP_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) #define BNX2_RXP_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) #define BNX2_RXP_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) #define BNX2_RXP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) #define BNX2_RXP_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) #define BNX2_RXP_CPU_PROGRAM_COUNTER 0x000c501c #define BNX2_RXP_CPU_INSTRUCTION 0x000c5020 #define BNX2_RXP_CPU_DATA_ACCESS 0x000c5024 #define BNX2_RXP_CPU_INTERRUPT_ENABLE 0x000c5028 #define BNX2_RXP_CPU_INTERRUPT_VECTOR 0x000c502c #define BNX2_RXP_CPU_INTERRUPT_SAVED_PC 0x000c5030 #define BNX2_RXP_CPU_HW_BREAKPOINT 0x000c5034 #define BNX2_RXP_CPU_HW_BREAKPOINT_DISABLE (1L<<0) #define BNX2_RXP_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) #define BNX2_RXP_CPU_DEBUG_VECT_PEEK 0x000c5038 #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) #define BNX2_RXP_CPU_LAST_BRANCH_ADDR 0x000c5048 #define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) #define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) #define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) #define BNX2_RXP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) #define BNX2_RXP_CPU_REG_FILE 0x000c5200 #define BNX2_RXP_CFTQ_DATA 0x000c5380 #define BNX2_RXP_CFTQ_CMD 0x000c53b8 #define BNX2_RXP_CFTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_RXP_CFTQ_CMD_WR_TOP (1L<<10) #define BNX2_RXP_CFTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_RXP_CFTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_RXP_CFTQ_CMD_SFT_RESET (1L<<25) #define BNX2_RXP_CFTQ_CMD_RD_DATA (1L<<26) #define BNX2_RXP_CFTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_RXP_CFTQ_CMD_ADD_DATA (1L<<28) #define BNX2_RXP_CFTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_RXP_CFTQ_CMD_POP (1L<<30) #define BNX2_RXP_CFTQ_CMD_BUSY (1L<<31) #define BNX2_RXP_CFTQ_CTL 0x000c53bc #define BNX2_RXP_CFTQ_CTL_INTERVENE (1L<<0) #define BNX2_RXP_CFTQ_CTL_OVERFLOW (1L<<1) #define BNX2_RXP_CFTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_RXP_CFTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_RXP_CFTQ_CTL_CUR_DEPTH (0x3ffL<<22) #define BNX2_RXP_FTQ_DATA 0x000c53c0 #define BNX2_RXP_FTQ_CMD 0x000c53f8 #define BNX2_RXP_FTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_RXP_FTQ_CMD_WR_TOP (1L<<10) #define BNX2_RXP_FTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_RXP_FTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_RXP_FTQ_CMD_SFT_RESET (1L<<25) #define BNX2_RXP_FTQ_CMD_RD_DATA (1L<<26) #define BNX2_RXP_FTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_RXP_FTQ_CMD_ADD_DATA (1L<<28) #define BNX2_RXP_FTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_RXP_FTQ_CMD_POP (1L<<30) #define BNX2_RXP_FTQ_CMD_BUSY (1L<<31) #define BNX2_RXP_FTQ_CTL 0x000c53fc #define BNX2_RXP_FTQ_CTL_INTERVENE (1L<<0) #define BNX2_RXP_FTQ_CTL_OVERFLOW (1L<<1) #define BNX2_RXP_FTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_RXP_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_RXP_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) #define BNX2_RXP_SCRATCH 0x000e0000 /* * com_reg definition * offset: 0x100000 */ #define BNX2_COM_CPU_MODE 0x00105000 #define BNX2_COM_CPU_MODE_LOCAL_RST (1L<<0) #define BNX2_COM_CPU_MODE_STEP_ENA (1L<<1) #define BNX2_COM_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) #define BNX2_COM_CPU_MODE_PAGE_0_INST_ENA (1L<<3) #define BNX2_COM_CPU_MODE_MSG_BIT1 (1L<<6) #define BNX2_COM_CPU_MODE_INTERRUPT_ENA (1L<<7) #define BNX2_COM_CPU_MODE_SOFT_HALT (1L<<10) #define BNX2_COM_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) #define BNX2_COM_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) #define BNX2_COM_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) #define BNX2_COM_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) #define BNX2_COM_CPU_STATE 0x00105004 #define BNX2_COM_CPU_STATE_BREAKPOINT (1L<<0) #define BNX2_COM_CPU_STATE_BAD_INST_HALTED (1L<<2) #define BNX2_COM_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) #define BNX2_COM_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) #define BNX2_COM_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) #define BNX2_COM_CPU_STATE_BAD_pc_HALTED (1L<<6) #define BNX2_COM_CPU_STATE_ALIGN_HALTED (1L<<7) #define BNX2_COM_CPU_STATE_FIO_ABORT_HALTED (1L<<8) #define BNX2_COM_CPU_STATE_SOFT_HALTED (1L<<10) #define BNX2_COM_CPU_STATE_SPAD_UNDERFLOW (1L<<11) #define BNX2_COM_CPU_STATE_INTERRRUPT (1L<<12) #define BNX2_COM_CPU_STATE_DATA_ACCESS_STALL (1L<<14) #define BNX2_COM_CPU_STATE_INST_FETCH_STALL (1L<<15) #define BNX2_COM_CPU_STATE_BLOCKED_READ (1L<<31) #define BNX2_COM_CPU_EVENT_MASK 0x00105008 #define BNX2_COM_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) #define BNX2_COM_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) #define BNX2_COM_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) #define BNX2_COM_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) #define BNX2_COM_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) #define BNX2_COM_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) #define BNX2_COM_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) #define BNX2_COM_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) #define BNX2_COM_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) #define BNX2_COM_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) #define BNX2_COM_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) #define BNX2_COM_CPU_PROGRAM_COUNTER 0x0010501c #define BNX2_COM_CPU_INSTRUCTION 0x00105020 #define BNX2_COM_CPU_DATA_ACCESS 0x00105024 #define BNX2_COM_CPU_INTERRUPT_ENABLE 0x00105028 #define BNX2_COM_CPU_INTERRUPT_VECTOR 0x0010502c #define BNX2_COM_CPU_INTERRUPT_SAVED_PC 0x00105030 #define BNX2_COM_CPU_HW_BREAKPOINT 0x00105034 #define BNX2_COM_CPU_HW_BREAKPOINT_DISABLE (1L<<0) #define BNX2_COM_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) #define BNX2_COM_CPU_DEBUG_VECT_PEEK 0x00105038 #define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) #define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) #define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) #define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) #define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) #define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) #define BNX2_COM_CPU_LAST_BRANCH_ADDR 0x00105048 #define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) #define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) #define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) #define BNX2_COM_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) #define BNX2_COM_CPU_REG_FILE 0x00105200 #define BNX2_COM_COMXQ_FTQ_DATA 0x00105340 #define BNX2_COM_COMXQ_FTQ_CMD 0x00105378 #define BNX2_COM_COMXQ_FTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP (1L<<10) #define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_COM_COMXQ_FTQ_CMD_SFT_RESET (1L<<25) #define BNX2_COM_COMXQ_FTQ_CMD_RD_DATA (1L<<26) #define BNX2_COM_COMXQ_FTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_COM_COMXQ_FTQ_CMD_ADD_DATA (1L<<28) #define BNX2_COM_COMXQ_FTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_COM_COMXQ_FTQ_CMD_POP (1L<<30) #define BNX2_COM_COMXQ_FTQ_CMD_BUSY (1L<<31) #define BNX2_COM_COMXQ_FTQ_CTL 0x0010537c #define BNX2_COM_COMXQ_FTQ_CTL_INTERVENE (1L<<0) #define BNX2_COM_COMXQ_FTQ_CTL_OVERFLOW (1L<<1) #define BNX2_COM_COMXQ_FTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_COM_COMXQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_COM_COMXQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) #define BNX2_COM_COMTQ_FTQ_DATA 0x00105380 #define BNX2_COM_COMTQ_FTQ_CMD 0x001053b8 #define BNX2_COM_COMTQ_FTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP (1L<<10) #define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_COM_COMTQ_FTQ_CMD_SFT_RESET (1L<<25) #define BNX2_COM_COMTQ_FTQ_CMD_RD_DATA (1L<<26) #define BNX2_COM_COMTQ_FTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_COM_COMTQ_FTQ_CMD_ADD_DATA (1L<<28) #define BNX2_COM_COMTQ_FTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_COM_COMTQ_FTQ_CMD_POP (1L<<30) #define BNX2_COM_COMTQ_FTQ_CMD_BUSY (1L<<31) #define BNX2_COM_COMTQ_FTQ_CTL 0x001053bc #define BNX2_COM_COMTQ_FTQ_CTL_INTERVENE (1L<<0) #define BNX2_COM_COMTQ_FTQ_CTL_OVERFLOW (1L<<1) #define BNX2_COM_COMTQ_FTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_COM_COMTQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_COM_COMTQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) #define BNX2_COM_COMQ_FTQ_DATA 0x001053c0 #define BNX2_COM_COMQ_FTQ_CMD 0x001053f8 #define BNX2_COM_COMQ_FTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_COM_COMQ_FTQ_CMD_WR_TOP (1L<<10) #define BNX2_COM_COMQ_FTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_COM_COMQ_FTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_COM_COMQ_FTQ_CMD_SFT_RESET (1L<<25) #define BNX2_COM_COMQ_FTQ_CMD_RD_DATA (1L<<26) #define BNX2_COM_COMQ_FTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_COM_COMQ_FTQ_CMD_ADD_DATA (1L<<28) #define BNX2_COM_COMQ_FTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_COM_COMQ_FTQ_CMD_POP (1L<<30) #define BNX2_COM_COMQ_FTQ_CMD_BUSY (1L<<31) #define BNX2_COM_COMQ_FTQ_CTL 0x001053fc #define BNX2_COM_COMQ_FTQ_CTL_INTERVENE (1L<<0) #define BNX2_COM_COMQ_FTQ_CTL_OVERFLOW (1L<<1) #define BNX2_COM_COMQ_FTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_COM_COMQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_COM_COMQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) #define BNX2_COM_SCRATCH 0x00120000 /* * cp_reg definition * offset: 0x180000 */ #define BNX2_CP_CPU_MODE 0x00185000 #define BNX2_CP_CPU_MODE_LOCAL_RST (1L<<0) #define BNX2_CP_CPU_MODE_STEP_ENA (1L<<1) #define BNX2_CP_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) #define BNX2_CP_CPU_MODE_PAGE_0_INST_ENA (1L<<3) #define BNX2_CP_CPU_MODE_MSG_BIT1 (1L<<6) #define BNX2_CP_CPU_MODE_INTERRUPT_ENA (1L<<7) #define BNX2_CP_CPU_MODE_SOFT_HALT (1L<<10) #define BNX2_CP_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) #define BNX2_CP_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) #define BNX2_CP_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) #define BNX2_CP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) #define BNX2_CP_CPU_STATE 0x00185004 #define BNX2_CP_CPU_STATE_BREAKPOINT (1L<<0) #define BNX2_CP_CPU_STATE_BAD_INST_HALTED (1L<<2) #define BNX2_CP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) #define BNX2_CP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) #define BNX2_CP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) #define BNX2_CP_CPU_STATE_BAD_pc_HALTED (1L<<6) #define BNX2_CP_CPU_STATE_ALIGN_HALTED (1L<<7) #define BNX2_CP_CPU_STATE_FIO_ABORT_HALTED (1L<<8) #define BNX2_CP_CPU_STATE_SOFT_HALTED (1L<<10) #define BNX2_CP_CPU_STATE_SPAD_UNDERFLOW (1L<<11) #define BNX2_CP_CPU_STATE_INTERRRUPT (1L<<12) #define BNX2_CP_CPU_STATE_DATA_ACCESS_STALL (1L<<14) #define BNX2_CP_CPU_STATE_INST_FETCH_STALL (1L<<15) #define BNX2_CP_CPU_STATE_BLOCKED_READ (1L<<31) #define BNX2_CP_CPU_EVENT_MASK 0x00185008 #define BNX2_CP_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) #define BNX2_CP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) #define BNX2_CP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) #define BNX2_CP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) #define BNX2_CP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) #define BNX2_CP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) #define BNX2_CP_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) #define BNX2_CP_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) #define BNX2_CP_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) #define BNX2_CP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) #define BNX2_CP_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) #define BNX2_CP_CPU_PROGRAM_COUNTER 0x0018501c #define BNX2_CP_CPU_INSTRUCTION 0x00185020 #define BNX2_CP_CPU_DATA_ACCESS 0x00185024 #define BNX2_CP_CPU_INTERRUPT_ENABLE 0x00185028 #define BNX2_CP_CPU_INTERRUPT_VECTOR 0x0018502c #define BNX2_CP_CPU_INTERRUPT_SAVED_PC 0x00185030 #define BNX2_CP_CPU_HW_BREAKPOINT 0x00185034 #define BNX2_CP_CPU_HW_BREAKPOINT_DISABLE (1L<<0) #define BNX2_CP_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) #define BNX2_CP_CPU_DEBUG_VECT_PEEK 0x00185038 #define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) #define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) #define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) #define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) #define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) #define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) #define BNX2_CP_CPU_LAST_BRANCH_ADDR 0x00185048 #define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) #define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) #define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) #define BNX2_CP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) #define BNX2_CP_CPU_REG_FILE 0x00185200 #define BNX2_CP_CPQ_FTQ_DATA 0x001853c0 #define BNX2_CP_CPQ_FTQ_CMD 0x001853f8 #define BNX2_CP_CPQ_FTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_CP_CPQ_FTQ_CMD_WR_TOP (1L<<10) #define BNX2_CP_CPQ_FTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_CP_CPQ_FTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_CP_CPQ_FTQ_CMD_SFT_RESET (1L<<25) #define BNX2_CP_CPQ_FTQ_CMD_RD_DATA (1L<<26) #define BNX2_CP_CPQ_FTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_CP_CPQ_FTQ_CMD_ADD_DATA (1L<<28) #define BNX2_CP_CPQ_FTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_CP_CPQ_FTQ_CMD_POP (1L<<30) #define BNX2_CP_CPQ_FTQ_CMD_BUSY (1L<<31) #define BNX2_CP_CPQ_FTQ_CTL 0x001853fc #define BNX2_CP_CPQ_FTQ_CTL_INTERVENE (1L<<0) #define BNX2_CP_CPQ_FTQ_CTL_OVERFLOW (1L<<1) #define BNX2_CP_CPQ_FTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_CP_CPQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_CP_CPQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) #define BNX2_CP_SCRATCH 0x001a0000 /* * mcp_reg definition * offset: 0x140000 */ #define BNX2_MCP_CPU_MODE 0x00145000 #define BNX2_MCP_CPU_MODE_LOCAL_RST (1L<<0) #define BNX2_MCP_CPU_MODE_STEP_ENA (1L<<1) #define BNX2_MCP_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) #define BNX2_MCP_CPU_MODE_PAGE_0_INST_ENA (1L<<3) #define BNX2_MCP_CPU_MODE_MSG_BIT1 (1L<<6) #define BNX2_MCP_CPU_MODE_INTERRUPT_ENA (1L<<7) #define BNX2_MCP_CPU_MODE_SOFT_HALT (1L<<10) #define BNX2_MCP_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) #define BNX2_MCP_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) #define BNX2_MCP_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) #define BNX2_MCP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) #define BNX2_MCP_CPU_STATE 0x00145004 #define BNX2_MCP_CPU_STATE_BREAKPOINT (1L<<0) #define BNX2_MCP_CPU_STATE_BAD_INST_HALTED (1L<<2) #define BNX2_MCP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) #define BNX2_MCP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) #define BNX2_MCP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) #define BNX2_MCP_CPU_STATE_BAD_pc_HALTED (1L<<6) #define BNX2_MCP_CPU_STATE_ALIGN_HALTED (1L<<7) #define BNX2_MCP_CPU_STATE_FIO_ABORT_HALTED (1L<<8) #define BNX2_MCP_CPU_STATE_SOFT_HALTED (1L<<10) #define BNX2_MCP_CPU_STATE_SPAD_UNDERFLOW (1L<<11) #define BNX2_MCP_CPU_STATE_INTERRRUPT (1L<<12) #define BNX2_MCP_CPU_STATE_DATA_ACCESS_STALL (1L<<14) #define BNX2_MCP_CPU_STATE_INST_FETCH_STALL (1L<<15) #define BNX2_MCP_CPU_STATE_BLOCKED_READ (1L<<31) #define BNX2_MCP_CPU_EVENT_MASK 0x00145008 #define BNX2_MCP_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) #define BNX2_MCP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) #define BNX2_MCP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) #define BNX2_MCP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) #define BNX2_MCP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) #define BNX2_MCP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) #define BNX2_MCP_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) #define BNX2_MCP_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) #define BNX2_MCP_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) #define BNX2_MCP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) #define BNX2_MCP_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) #define BNX2_MCP_CPU_PROGRAM_COUNTER 0x0014501c #define BNX2_MCP_CPU_INSTRUCTION 0x00145020 #define BNX2_MCP_CPU_DATA_ACCESS 0x00145024 #define BNX2_MCP_CPU_INTERRUPT_ENABLE 0x00145028 #define BNX2_MCP_CPU_INTERRUPT_VECTOR 0x0014502c #define BNX2_MCP_CPU_INTERRUPT_SAVED_PC 0x00145030 #define BNX2_MCP_CPU_HW_BREAKPOINT 0x00145034 #define BNX2_MCP_CPU_HW_BREAKPOINT_DISABLE (1L<<0) #define BNX2_MCP_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) #define BNX2_MCP_CPU_DEBUG_VECT_PEEK 0x00145038 #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) #define BNX2_MCP_CPU_LAST_BRANCH_ADDR 0x00145048 #define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) #define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) #define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) #define BNX2_MCP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) #define BNX2_MCP_CPU_REG_FILE 0x00145200 #define BNX2_MCP_MCPQ_FTQ_DATA 0x001453c0 #define BNX2_MCP_MCPQ_FTQ_CMD 0x001453f8 #define BNX2_MCP_MCPQ_FTQ_CMD_OFFSET (0x3ffL<<0) #define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP (1L<<10) #define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP_0 (0L<<10) #define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP_1 (1L<<10) #define BNX2_MCP_MCPQ_FTQ_CMD_SFT_RESET (1L<<25) #define BNX2_MCP_MCPQ_FTQ_CMD_RD_DATA (1L<<26) #define BNX2_MCP_MCPQ_FTQ_CMD_ADD_INTERVEN (1L<<27) #define BNX2_MCP_MCPQ_FTQ_CMD_ADD_DATA (1L<<28) #define BNX2_MCP_MCPQ_FTQ_CMD_INTERVENE_CLR (1L<<29) #define BNX2_MCP_MCPQ_FTQ_CMD_POP (1L<<30) #define BNX2_MCP_MCPQ_FTQ_CMD_BUSY (1L<<31) #define BNX2_MCP_MCPQ_FTQ_CTL 0x001453fc #define BNX2_MCP_MCPQ_FTQ_CTL_INTERVENE (1L<<0) #define BNX2_MCP_MCPQ_FTQ_CTL_OVERFLOW (1L<<1) #define BNX2_MCP_MCPQ_FTQ_CTL_FORCE_INTERVENE (1L<<2) #define BNX2_MCP_MCPQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) #define BNX2_MCP_MCPQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) #define BNX2_MCP_ROM 0x00150000 #define BNX2_MCP_SCRATCH 0x00160000 #define BNX2_SHM_HDR_SIGNATURE BNX2_MCP_SCRATCH #define BNX2_SHM_HDR_SIGNATURE_SIG_MASK 0xffff0000 #define BNX2_SHM_HDR_SIGNATURE_SIG 0x53530000 #define BNX2_SHM_HDR_SIGNATURE_VER_MASK 0x000000ff #define BNX2_SHM_HDR_SIGNATURE_VER_ONE 0x00000001 #define BNX2_SHM_HDR_ADDR_0 BNX2_MCP_SCRATCH + 4 #define BNX2_SHM_HDR_ADDR_1 BNX2_MCP_SCRATCH + 8 #define NUM_MC_HASH_REGISTERS 8 /* PHY_ID1: bits 31-16; PHY_ID2: bits 15-0. */ #define PHY_BCM5706_PHY_ID 0x00206160 #define PHY_ID(id) ((id) & 0xfffffff0) #define PHY_REV_ID(id) ((id) & 0xf) /* 5708 Serdes PHY registers */ #define BCM5708S_UP1 0xb #define BCM5708S_UP1_2G5 0x1 #define BCM5708S_BLK_ADDR 0x1f #define BCM5708S_BLK_ADDR_DIG 0x0000 #define BCM5708S_BLK_ADDR_DIG3 0x0002 #define BCM5708S_BLK_ADDR_TX_MISC 0x0005 /* Digital Block */ #define BCM5708S_1000X_CTL1 0x10 #define BCM5708S_1000X_CTL1_FIBER_MODE 0x0001 #define BCM5708S_1000X_CTL1_AUTODET_EN 0x0010 #define BCM5708S_1000X_CTL2 0x11 #define BCM5708S_1000X_CTL2_PLLEL_DET_EN 0x0001 #define BCM5708S_1000X_STAT1 0x14 #define BCM5708S_1000X_STAT1_SGMII 0x0001 #define BCM5708S_1000X_STAT1_LINK 0x0002 #define BCM5708S_1000X_STAT1_FD 0x0004 #define BCM5708S_1000X_STAT1_SPEED_MASK 0x0018 #define BCM5708S_1000X_STAT1_SPEED_10 0x0000 #define BCM5708S_1000X_STAT1_SPEED_100 0x0008 #define BCM5708S_1000X_STAT1_SPEED_1G 0x0010 #define BCM5708S_1000X_STAT1_SPEED_2G5 0x0018 #define BCM5708S_1000X_STAT1_TX_PAUSE 0x0020 #define BCM5708S_1000X_STAT1_RX_PAUSE 0x0040 /* Digital3 Block */ #define BCM5708S_DIG_3_0 0x10 #define BCM5708S_DIG_3_0_USE_IEEE 0x0001 /* Tx/Misc Block */ #define BCM5708S_TX_ACTL1 0x15 #define BCM5708S_TX_ACTL1_DRIVER_VCM 0x30 #define BCM5708S_TX_ACTL3 0x17 #define MIN_ETHERNET_PACKET_SIZE 60 #define MAX_ETHERNET_PACKET_SIZE 1514 #define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014 #define RX_COPY_THRESH 92 #define DMA_READ_CHANS 5 #define DMA_WRITE_CHANS 3 #define BCM_PAGE_BITS 12 #define BCM_PAGE_SIZE (1 << BCM_PAGE_BITS) #define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct tx_bd)) #define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) #define MAX_RX_RINGS 4 #define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct rx_bd)) #define MAX_RX_DESC_CNT (RX_DESC_CNT - 1) #define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS) #define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) == \ (MAX_TX_DESC_CNT - 1)) ? \ (x) + 2 : (x) + 1 #define PREV_TX_BD(x) ((((x)-1) & (MAX_TX_DESC_CNT)) == \ (MAX_TX_DESC_CNT)) ? \ (x) - 2 : (x) - 1 #define TX_RING_IDX(x) ((x) & MAX_TX_DESC_CNT) #define NEXT_RX_BD(x) (((x) & (MAX_RX_DESC_CNT - 1)) == \ (MAX_RX_DESC_CNT - 1)) ? \ (x) + 2 : (x) + 1 #define RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx) //#define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> 8) #define RX_IDX(x) ((x) & MAX_RX_DESC_CNT) /* Context size. */ #define CTX_SHIFT 7 #define CTX_SIZE (1 << CTX_SHIFT) #define CTX_MASK (CTX_SIZE - 1) #define GET_CID_ADDR(_cid) ((_cid) << CTX_SHIFT) #define GET_CID(_cid_addr) ((_cid_addr) >> CTX_SHIFT) #define PHY_CTX_SHIFT 6 #define PHY_CTX_SIZE (1 << PHY_CTX_SHIFT) #define PHY_CTX_MASK (PHY_CTX_SIZE - 1) #define GET_PCID_ADDR(_pcid) ((_pcid) << PHY_CTX_SHIFT) #define GET_PCID(_pcid_addr) ((_pcid_addr) >> PHY_CTX_SHIFT) #define MB_KERNEL_CTX_SHIFT 8 #define MB_KERNEL_CTX_SIZE (1 << MB_KERNEL_CTX_SHIFT) #define MB_KERNEL_CTX_MASK (MB_KERNEL_CTX_SIZE - 1) #define MB_GET_CID_ADDR(_cid) (0x10000 + ((_cid) << MB_KERNEL_CTX_SHIFT)) #define MAX_CID_CNT 0x4000 #define MAX_CID_ADDR (GET_CID_ADDR(MAX_CID_CNT)) #define INVALID_CID_ADDR 0xffffffff #define TX_CID 16 #define RX_CID 0 #define MB_TX_CID_ADDR MB_GET_CID_ADDR(TX_CID) #define MB_RX_CID_ADDR MB_GET_CID_ADDR(RX_CID) #if 0 struct sw_bd { struct sk_buff *skb; DECLARE_PCI_UNMAP_ADDR(mapping) }; #endif /* Buffered flash (Atmel: AT45DB011B) specific information */ #define SEEPROM_PAGE_BITS 2 #define SEEPROM_PHY_PAGE_SIZE (1 << SEEPROM_PAGE_BITS) #define SEEPROM_BYTE_ADDR_MASK (SEEPROM_PHY_PAGE_SIZE-1) #define SEEPROM_PAGE_SIZE 4 #define SEEPROM_TOTAL_SIZE 65536 #define BUFFERED_FLASH_PAGE_BITS 9 #define BUFFERED_FLASH_PHY_PAGE_SIZE (1 << BUFFERED_FLASH_PAGE_BITS) #define BUFFERED_FLASH_BYTE_ADDR_MASK (BUFFERED_FLASH_PHY_PAGE_SIZE-1) #define BUFFERED_FLASH_PAGE_SIZE 264 #define BUFFERED_FLASH_TOTAL_SIZE 0x21000 #define SAIFUN_FLASH_PAGE_BITS 8 #define SAIFUN_FLASH_PHY_PAGE_SIZE (1 << SAIFUN_FLASH_PAGE_BITS) #define SAIFUN_FLASH_BYTE_ADDR_MASK (SAIFUN_FLASH_PHY_PAGE_SIZE-1) #define SAIFUN_FLASH_PAGE_SIZE 256 #define SAIFUN_FLASH_BASE_TOTAL_SIZE 65536 #define ST_MICRO_FLASH_PAGE_BITS 8 #define ST_MICRO_FLASH_PHY_PAGE_SIZE (1 << ST_MICRO_FLASH_PAGE_BITS) #define ST_MICRO_FLASH_BYTE_ADDR_MASK (ST_MICRO_FLASH_PHY_PAGE_SIZE-1) #define ST_MICRO_FLASH_PAGE_SIZE 256 #define ST_MICRO_FLASH_BASE_TOTAL_SIZE 65536 #define NVRAM_TIMEOUT_COUNT 30000 #define FLASH_STRAP_MASK (BNX2_NVM_CFG1_FLASH_MODE | \ BNX2_NVM_CFG1_BUFFER_MODE | \ BNX2_NVM_CFG1_PROTECT_MODE | \ BNX2_NVM_CFG1_FLASH_SIZE) #define FLASH_BACKUP_STRAP_MASK (0xf << 26) struct flash_spec { u32 strapping; u32 config1; u32 config2; u32 config3; u32 write1; u32 buffered; u32 page_bits; u32 page_size; u32 addr_mask; u32 total_size; char *name; }; struct bnx2 { /* Fields used in the tx and intr/napi performance paths are grouped */ /* together in the beginning of the structure. */ void /*__iomem*/ *regview; struct nic *nic; struct pci_device *pdev; /* atomic_t intr_sem; */ struct status_block *status_blk; u32 last_status_idx; u32 flags; #define PCIX_FLAG 1 #define PCI_32BIT_FLAG 2 #define ONE_TDMA_FLAG 4 /* no longer used */ #define NO_WOL_FLAG 8 #define USING_DAC_FLAG 0x10 #define USING_MSI_FLAG 0x20 #define ASF_ENABLE_FLAG 0x40 /* Put tx producer and consumer fields in separate cache lines. */ u32 tx_prod_bseq __attribute__((aligned(L1_CACHE_BYTES))); u16 tx_prod; struct tx_bd *tx_desc_ring; struct sw_bd *tx_buf_ring; int tx_ring_size; u16 tx_cons __attribute__((aligned(L1_CACHE_BYTES))); u16 hw_tx_cons; #ifdef BCM_VLAN struct vlan_group *vlgrp; #endif u32 rx_offset; u32 rx_buf_use_size; /* useable size */ u32 rx_buf_size; /* with alignment */ u32 rx_max_ring_idx; u32 rx_prod_bseq; u16 rx_prod; u16 rx_cons; u16 hw_rx_cons; u32 rx_csum; #if 0 struct rx_bd *rx_desc_ring[MAX_RX_RINGS]; #endif struct rx_bd *rx_desc_ring; /* End of fields used in the performance code paths. */ char *name; #if 0 int timer_interval; int current_interval; struct timer_list timer; struct work_struct reset_task; int in_reset_task; /* Used to synchronize phy accesses. */ spinlock_t phy_lock; #endif u32 phy_flags; #define PHY_SERDES_FLAG 1 #define PHY_CRC_FIX_FLAG 2 #define PHY_PARALLEL_DETECT_FLAG 4 #define PHY_2_5G_CAPABLE_FLAG 8 #define PHY_INT_MODE_MASK_FLAG 0x300 #define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100 #define PHY_INT_MODE_LINK_READY_FLAG 0x200 u32 chip_id; /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ #define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000) #define CHIP_NUM_5706 0x57060000 #define CHIP_NUM_5708 0x57080000 #define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000) #define CHIP_REV_Ax 0x00000000 #define CHIP_REV_Bx 0x00001000 #define CHIP_REV_Cx 0x00002000 #define CHIP_METAL(bp) (((bp)->chip_id) & 0x00000ff0) #define CHIP_BONDING(bp) (((bp)->chip_id) & 0x0000000f) #define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0) #define CHIP_ID_5706_A0 0x57060000 #define CHIP_ID_5706_A1 0x57060010 #define CHIP_ID_5706_A2 0x57060020 #define CHIP_ID_5708_A0 0x57080000 #define CHIP_ID_5708_B0 0x57081000 #define CHIP_ID_5708_B1 0x57081010 #define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0xf) /* A serdes chip will have the first bit of the bond id set. */ #define CHIP_BOND_ID_SERDES_BIT 0x01 u32 phy_addr; u32 phy_id; u16 bus_speed_mhz; u8 wol; u8 pad; u16 fw_wr_seq; u16 fw_drv_pulse_wr_seq; dma_addr_t tx_desc_mapping; int rx_max_ring; int rx_ring_size; #if 0 dma_addr_t rx_desc_mapping[MAX_RX_RINGS]; #endif dma_addr_t rx_desc_mapping; u16 tx_quick_cons_trip; u16 tx_quick_cons_trip_int; u16 rx_quick_cons_trip; u16 rx_quick_cons_trip_int; u16 comp_prod_trip; u16 comp_prod_trip_int; u16 tx_ticks; u16 tx_ticks_int; u16 com_ticks; u16 com_ticks_int; u16 cmd_ticks; u16 cmd_ticks_int; u16 rx_ticks; u16 rx_ticks_int; u32 stats_ticks; dma_addr_t status_blk_mapping; struct statistics_block *stats_blk; dma_addr_t stats_blk_mapping; u32 hc_cmd; u32 rx_mode; u16 req_line_speed; u8 req_duplex; u8 link_up; u16 line_speed; u8 duplex; u8 flow_ctrl; /* actual flow ctrl settings */ /* may be different from */ /* req_flow_ctrl if autoneg */ #define FLOW_CTRL_TX 1 #define FLOW_CTRL_RX 2 u32 advertising; u8 req_flow_ctrl; /* flow ctrl advertisement */ /* settings or forced */ /* settings */ u8 autoneg; #define AUTONEG_SPEED 1 #define AUTONEG_FLOW_CTRL 2 u8 loopback; #define MAC_LOOPBACK 1 #define PHY_LOOPBACK 2 u8 serdes_an_pending; #define SERDES_AN_TIMEOUT (HZ / 3) u8 mac_addr[8]; u32 shmem_base; u32 fw_ver; int pm_cap; int pcix_cap; /* struct net_device_stats net_stats; */ struct flash_spec *flash_info; u32 flash_size; int status_stats_size; }; static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset); static void bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val); #define REG_RD(bp, offset) \ readl(bp->regview + offset) #define REG_WR(bp, offset, val) \ writel(val, bp->regview + offset) #define REG_WR16(bp, offset, val) \ writew(val, bp->regview + offset) #define REG_RD_IND(bp, offset) \ bnx2_reg_rd_ind(bp, offset) #define REG_WR_IND(bp, offset, val) \ bnx2_reg_wr_ind(bp, offset, val) /* Indirect context access. Unlike the MBQ_WR, these macros will not * trigger a chip event. */ static void bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val); #define CTX_WR(bp, cid_addr, offset, val) \ bnx2_ctx_wr(bp, cid_addr, offset, val) struct cpu_reg { u32 mode; u32 mode_value_halt; u32 mode_value_sstep; u32 state; u32 state_value_clear; u32 gpr0; u32 evmask; u32 pc; u32 inst; u32 bp; u32 spad_base; u32 mips_view_base; }; struct fw_info { u32 ver_major; u32 ver_minor; u32 ver_fix; u32 start_addr; /* Text section. */ u32 text_addr; u32 text_len; u32 text_index; u32 *text; /* Data section. */ u32 data_addr; u32 data_len; u32 data_index; u32 *data; /* SBSS section. */ u32 sbss_addr; u32 sbss_len; u32 sbss_index; u32 *sbss; /* BSS section. */ u32 bss_addr; u32 bss_len; u32 bss_index; u32 *bss; /* Read-only section. */ u32 rodata_addr; u32 rodata_len; u32 rodata_index; u32 *rodata; }; #define RV2P_PROC1 0 #define RV2P_PROC2 1 /* This value (in milliseconds) determines the frequency of the driver * issuing the PULSE message code. The firmware monitors this periodic * pulse to determine when to switch to an OS-absent mode. */ #define DRV_PULSE_PERIOD_MS 250 /* This value (in milliseconds) determines how long the driver should * wait for an acknowledgement from the firmware before timing out. Once * the firmware has timed out, the driver will assume there is no firmware * running and there won't be any firmware-driver synchronization during a * driver reset. */ #define FW_ACK_TIME_OUT_MS 100 #define BNX2_DRV_RESET_SIGNATURE 0x00000000 #define BNX2_DRV_RESET_SIGNATURE_MAGIC 0x4841564b /* HAVK */ //#define DRV_RESET_SIGNATURE_MAGIC 0x47495352 /* RSIG */ #define BNX2_DRV_MB 0x00000004 #define BNX2_DRV_MSG_CODE 0xff000000 #define BNX2_DRV_MSG_CODE_RESET 0x01000000 #define BNX2_DRV_MSG_CODE_UNLOAD 0x02000000 #define BNX2_DRV_MSG_CODE_SHUTDOWN 0x03000000 #define BNX2_DRV_MSG_CODE_SUSPEND_WOL 0x04000000 #define BNX2_DRV_MSG_CODE_FW_TIMEOUT 0x05000000 #define BNX2_DRV_MSG_CODE_PULSE 0x06000000 #define BNX2_DRV_MSG_CODE_DIAG 0x07000000 #define BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL 0x09000000 #define BNX2_DRV_MSG_DATA 0x00ff0000 #define BNX2_DRV_MSG_DATA_WAIT0 0x00010000 #define BNX2_DRV_MSG_DATA_WAIT1 0x00020000 #define BNX2_DRV_MSG_DATA_WAIT2 0x00030000 #define BNX2_DRV_MSG_DATA_WAIT3 0x00040000 #define BNX2_DRV_MSG_SEQ 0x0000ffff #define BNX2_FW_MB 0x00000008 #define BNX2_FW_MSG_ACK 0x0000ffff #define BNX2_FW_MSG_STATUS_MASK 0x00ff0000 #define BNX2_FW_MSG_STATUS_OK 0x00000000 #define BNX2_FW_MSG_STATUS_FAILURE 0x00ff0000 #define BNX2_LINK_STATUS 0x0000000c #define BNX2_LINK_STATUS_INIT_VALUE 0xffffffff #define BNX2_LINK_STATUS_LINK_UP 0x1 #define BNX2_LINK_STATUS_LINK_DOWN 0x0 #define BNX2_LINK_STATUS_SPEED_MASK 0x1e #define BNX2_LINK_STATUS_AN_INCOMPLETE (0<<1) #define BNX2_LINK_STATUS_10HALF (1<<1) #define BNX2_LINK_STATUS_10FULL (2<<1) #define BNX2_LINK_STATUS_100HALF (3<<1) #define BNX2_LINK_STATUS_100BASE_T4 (4<<1) #define BNX2_LINK_STATUS_100FULL (5<<1) #define BNX2_LINK_STATUS_1000HALF (6<<1) #define BNX2_LINK_STATUS_1000FULL (7<<1) #define BNX2_LINK_STATUS_2500HALF (8<<1) #define BNX2_LINK_STATUS_2500FULL (9<<1) #define BNX2_LINK_STATUS_AN_ENABLED (1<<5) #define BNX2_LINK_STATUS_AN_COMPLETE (1<<6) #define BNX2_LINK_STATUS_PARALLEL_DET (1<<7) #define BNX2_LINK_STATUS_RESERVED (1<<8) #define BNX2_LINK_STATUS_PARTNER_AD_1000FULL (1<<9) #define BNX2_LINK_STATUS_PARTNER_AD_1000HALF (1<<10) #define BNX2_LINK_STATUS_PARTNER_AD_100BT4 (1<<11) #define BNX2_LINK_STATUS_PARTNER_AD_100FULL (1<<12) #define BNX2_LINK_STATUS_PARTNER_AD_100HALF (1<<13) #define BNX2_LINK_STATUS_PARTNER_AD_10FULL (1<<14) #define BNX2_LINK_STATUS_PARTNER_AD_10HALF (1<<15) #define BNX2_LINK_STATUS_TX_FC_ENABLED (1<<16) #define BNX2_LINK_STATUS_RX_FC_ENABLED (1<<17) #define BNX2_LINK_STATUS_PARTNER_SYM_PAUSE_CAP (1<<18) #define BNX2_LINK_STATUS_PARTNER_ASYM_PAUSE_CAP (1<<19) #define BNX2_LINK_STATUS_SERDES_LINK (1<<20) #define BNX2_LINK_STATUS_PARTNER_AD_2500FULL (1<<21) #define BNX2_LINK_STATUS_PARTNER_AD_2500HALF (1<<22) #define BNX2_DRV_PULSE_MB 0x00000010 #define BNX2_DRV_PULSE_SEQ_MASK 0x00007fff /* Indicate to the firmware not to go into the * OS absent when it is not getting driver pulse. * This is used for debugging. */ #define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE 0x00080000 #define BNX2_DEV_INFO_SIGNATURE 0x00000020 #define BNX2_DEV_INFO_SIGNATURE_MAGIC 0x44564900 #define BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK 0xffffff00 #define BNX2_DEV_INFO_FEATURE_CFG_VALID 0x01 #define BNX2_DEV_INFO_SECONDARY_PORT 0x80 #define BNX2_DEV_INFO_DRV_ALWAYS_ALIVE 0x40 #define BNX2_SHARED_HW_CFG_PART_NUM 0x00000024 #define BNX2_SHARED_HW_CFG_POWER_DISSIPATED 0x00000034 #define BNX2_SHARED_HW_CFG_POWER_STATE_D3_MASK 0xff000000 #define BNX2_SHARED_HW_CFG_POWER_STATE_D2_MASK 0xff0000 #define BNX2_SHARED_HW_CFG_POWER_STATE_D1_MASK 0xff00 #define BNX2_SHARED_HW_CFG_POWER_STATE_D0_MASK 0xff #define BNX2_SHARED_HW_CFG POWER_CONSUMED 0x00000038 #define BNX2_SHARED_HW_CFG_CONFIG 0x0000003c #define BNX2_SHARED_HW_CFG_DESIGN_NIC 0 #define BNX2_SHARED_HW_CFG_DESIGN_LOM 0x1 #define BNX2_SHARED_HW_CFG_PHY_COPPER 0 #define BNX2_SHARED_HW_CFG_PHY_FIBER 0x2 #define BNX2_SHARED_HW_CFG_PHY_2_5G 0x20 #define BNX2_SHARED_HW_CFG_PHY_BACKPLANE 0x40 #define BNX2_SHARED_HW_CFG_LED_MODE_SHIFT_BITS 8 #define BNX2_SHARED_HW_CFG_LED_MODE_MASK 0x300 #define BNX2_SHARED_HW_CFG_LED_MODE_MAC 0 #define BNX2_SHARED_HW_CFG_LED_MODE_GPHY1 0x100 #define BNX2_SHARED_HW_CFG_LED_MODE_GPHY2 0x200 #define BNX2_SHARED_HW_CFG_CONFIG2 0x00000040 #define BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK 0x00fff000 #define BNX2_DEV_INFO_BC_REV 0x0000004c #define BNX2_PORT_HW_CFG_MAC_UPPER 0x00000050 #define BNX2_PORT_HW_CFG_UPPERMAC_MASK 0xffff #define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054 #define BNX2_PORT_HW_CFG_CONFIG 0x00000058 #define BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK 0x0000ffff #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK 0x001f0000 #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_AN 0x00000000 #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G 0x00030000 #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_2_5G 0x00040000 #define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068 #define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c #define BNX2_PORT_HW_CFG_IMD_MAC_B_UPPER 0x00000070 #define BNX2_PORT_HW_CFG_IMD_MAC_B_LOWER 0x00000074 #define BNX2_PORT_HW_CFG_ISCSI_MAC_UPPER 0x00000078 #define BNX2_PORT_HW_CFG_ISCSI_MAC_LOWER 0x0000007c #define BNX2_DEV_INFO_PER_PORT_HW_CONFIG2 0x000000b4 #define BNX2_DEV_INFO_FORMAT_REV 0x000000c4 #define BNX2_DEV_INFO_FORMAT_REV_MASK 0xff000000 #define BNX2_DEV_INFO_FORMAT_REV_ID ('A' << 24) #define BNX2_SHARED_FEATURE 0x000000c8 #define BNX2_SHARED_FEATURE_MASK 0xffffffff #define BNX2_PORT_FEATURE 0x000000d8 #define BNX2_PORT2_FEATURE 0x00000014c #define BNX2_PORT_FEATURE_WOL_ENABLED 0x01000000 #define BNX2_PORT_FEATURE_MBA_ENABLED 0x02000000 #define BNX2_PORT_FEATURE_ASF_ENABLED 0x04000000 #define BNX2_PORT_FEATURE_IMD_ENABLED 0x08000000 #define BNX2_PORT_FEATURE_BAR1_SIZE_MASK 0xf #define BNX2_PORT_FEATURE_BAR1_SIZE_DISABLED 0x0 #define BNX2_PORT_FEATURE_BAR1_SIZE_64K 0x1 #define BNX2_PORT_FEATURE_BAR1_SIZE_128K 0x2 #define BNX2_PORT_FEATURE_BAR1_SIZE_256K 0x3 #define BNX2_PORT_FEATURE_BAR1_SIZE_512K 0x4 #define BNX2_PORT_FEATURE_BAR1_SIZE_1M 0x5 #define BNX2_PORT_FEATURE_BAR1_SIZE_2M 0x6 #define BNX2_PORT_FEATURE_BAR1_SIZE_4M 0x7 #define BNX2_PORT_FEATURE_BAR1_SIZE_8M 0x8 #define BNX2_PORT_FEATURE_BAR1_SIZE_16M 0x9 #define BNX2_PORT_FEATURE_BAR1_SIZE_32M 0xa #define BNX2_PORT_FEATURE_BAR1_SIZE_64M 0xb #define BNX2_PORT_FEATURE_BAR1_SIZE_128M 0xc #define BNX2_PORT_FEATURE_BAR1_SIZE_256M 0xd #define BNX2_PORT_FEATURE_BAR1_SIZE_512M 0xe #define BNX2_PORT_FEATURE_BAR1_SIZE_1G 0xf #define BNX2_PORT_FEATURE_WOL 0xdc #define BNX2_PORT2_FEATURE_WOL 0x150 #define BNX2_PORT_FEATURE_WOL_DEFAULT_SHIFT_BITS 4 #define BNX2_PORT_FEATURE_WOL_DEFAULT_MASK 0x30 #define BNX2_PORT_FEATURE_WOL_DEFAULT_DISABLE 0 #define BNX2_PORT_FEATURE_WOL_DEFAULT_MAGIC 0x10 #define BNX2_PORT_FEATURE_WOL_DEFAULT_ACPI 0x20 #define BNX2_PORT_FEATURE_WOL_DEFAULT_MAGIC_AND_ACPI 0x30 #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_MASK 0xf #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_AUTONEG 0 #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_10HALF 1 #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_10FULL 2 #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_100HALF 3 #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_100FULL 4 #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_1000HALF 5 #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_1000FULL 6 #define BNX2_PORT_FEATURE_WOL_AUTONEG_ADVERTISE_1000 0x40 #define BNX2_PORT_FEATURE_WOL_RESERVED_PAUSE_CAP 0x400 #define BNX2_PORT_FEATURE_WOL_RESERVED_ASYM_PAUSE_CAP 0x800 #define BNX2_PORT_FEATURE_MBA 0xe0 #define BNX2_PORT2_FEATURE_MBA 0x154 #define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_SHIFT_BITS 0 #define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK 0x3 #define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_PXE 0 #define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_RPL 1 #define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_BOOTP 2 #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_SHIFT_BITS 2 #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_MASK 0x3c #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_AUTONEG 0 #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_10HALF 0x4 #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_10FULL 0x8 #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_100HALF 0xc #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_100FULL 0x10 #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_1000HALF 0x14 #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_1000FULL 0x18 #define BNX2_PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE 0x40 #define BNX2_PORT_FEATURE_MBA_HOTKEY_CTRL_S 0 #define BNX2_PORT_FEATURE_MBA_HOTKEY_CTRL_B 0x80 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_SHIFT_BITS 8 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_MASK 0xff00 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_DISABLED 0 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_1K 0x100 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_2K 0x200 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_4K 0x300 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_8K 0x400 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_16K 0x500 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_32K 0x600 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_64K 0x700 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_128K 0x800 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_256K 0x900 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_512K 0xa00 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_1M 0xb00 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_2M 0xc00 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_4M 0xd00 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_8M 0xe00 #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_16M 0xf00 #define BNX2_PORT_FEATURE_MBA_MSG_TIMEOUT_SHIFT_BITS 16 #define BNX2_PORT_FEATURE_MBA_MSG_TIMEOUT_MASK 0xf0000 #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_SHIFT_BITS 20 #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_MASK 0x300000 #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_AUTO 0 #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_BBS 0x100000 #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT18H 0x200000 #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT19H 0x300000 #define BNX2_PORT_FEATURE_IMD 0xe4 #define BNX2_PORT2_FEATURE_IMD 0x158 #define BNX2_PORT_FEATURE_IMD_LINK_OVERRIDE_DEFAULT 0 #define BNX2_PORT_FEATURE_IMD_LINK_OVERRIDE_ENABLE 1 #define BNX2_PORT_FEATURE_VLAN 0xe8 #define BNX2_PORT2_FEATURE_VLAN 0x15c #define BNX2_PORT_FEATURE_MBA_VLAN_TAG_MASK 0xffff #define BNX2_PORT_FEATURE_MBA_VLAN_ENABLE 0x10000 #define BNX2_BC_STATE_RESET_TYPE 0x000001c0 #define BNX2_BC_STATE_RESET_TYPE_SIG 0x00005254 #define BNX2_BC_STATE_RESET_TYPE_SIG_MASK 0x0000ffff #define BNX2_BC_STATE_RESET_TYPE_NONE (BNX2_BC_STATE_RESET_TYPE_SIG | \ 0x00010000) #define BNX2_BC_STATE_RESET_TYPE_PCI (BNX2_BC_STATE_RESET_TYPE_SIG | \ 0x00020000) #define BNX2_BC_STATE_RESET_TYPE_VAUX (BNX2_BC_STATE_RESET_TYPE_SIG | \ 0x00030000) #define BNX2_BC_STATE_RESET_TYPE_DRV_MASK DRV_MSG_CODE #define BNX2_BC_STATE_RESET_TYPE_DRV_RESET (BNX2_BC_STATE_RESET_TYPE_SIG | \ DRV_MSG_CODE_RESET) #define BNX2_BC_STATE_RESET_TYPE_DRV_UNLOAD (BNX2_BC_STATE_RESET_TYPE_SIG | \ DRV_MSG_CODE_UNLOAD) #define BNX2_BC_STATE_RESET_TYPE_DRV_SHUTDOWN (BNX2_BC_STATE_RESET_TYPE_SIG | \ DRV_MSG_CODE_SHUTDOWN) #define BNX2_BC_STATE_RESET_TYPE_DRV_WOL (BNX2_BC_STATE_RESET_TYPE_SIG | \ DRV_MSG_CODE_WOL) #define BNX2_BC_STATE_RESET_TYPE_DRV_DIAG (BNX2_BC_STATE_RESET_TYPE_SIG | \ DRV_MSG_CODE_DIAG) #define BNX2_BC_STATE_RESET_TYPE_VALUE(msg) (BNX2_BC_STATE_RESET_TYPE_SIG | \ (msg)) #define BNX2_BC_STATE 0x000001c4 #define BNX2_BC_STATE_ERR_MASK 0x0000ff00 #define BNX2_BC_STATE_SIGN 0x42530000 #define BNX2_BC_STATE_SIGN_MASK 0xffff0000 #define BNX2_BC_STATE_BC1_START (BNX2_BC_STATE_SIGN | 0x1) #define BNX2_BC_STATE_GET_NVM_CFG1 (BNX2_BC_STATE_SIGN | 0x2) #define BNX2_BC_STATE_PROG_BAR (BNX2_BC_STATE_SIGN | 0x3) #define BNX2_BC_STATE_INIT_VID (BNX2_BC_STATE_SIGN | 0x4) #define BNX2_BC_STATE_GET_NVM_CFG2 (BNX2_BC_STATE_SIGN | 0x5) #define BNX2_BC_STATE_APPLY_WKARND (BNX2_BC_STATE_SIGN | 0x6) #define BNX2_BC_STATE_LOAD_BC2 (BNX2_BC_STATE_SIGN | 0x7) #define BNX2_BC_STATE_GOING_BC2 (BNX2_BC_STATE_SIGN | 0x8) #define BNX2_BC_STATE_GOING_DIAG (BNX2_BC_STATE_SIGN | 0x9) #define BNX2_BC_STATE_RT_FINAL_INIT (BNX2_BC_STATE_SIGN | 0x81) #define BNX2_BC_STATE_RT_WKARND (BNX2_BC_STATE_SIGN | 0x82) #define BNX2_BC_STATE_RT_DRV_PULSE (BNX2_BC_STATE_SIGN | 0x83) #define BNX2_BC_STATE_RT_FIOEVTS (BNX2_BC_STATE_SIGN | 0x84) #define BNX2_BC_STATE_RT_DRV_CMD (BNX2_BC_STATE_SIGN | 0x85) #define BNX2_BC_STATE_RT_LOW_POWER (BNX2_BC_STATE_SIGN | 0x86) #define BNX2_BC_STATE_RT_SET_WOL (BNX2_BC_STATE_SIGN | 0x87) #define BNX2_BC_STATE_RT_OTHER_FW (BNX2_BC_STATE_SIGN | 0x88) #define BNX2_BC_STATE_RT_GOING_D3 (BNX2_BC_STATE_SIGN | 0x89) #define BNX2_BC_STATE_ERR_BAD_VERSION (BNX2_BC_STATE_SIGN | 0x0100) #define BNX2_BC_STATE_ERR_BAD_BC2_CRC (BNX2_BC_STATE_SIGN | 0x0200) #define BNX2_BC_STATE_ERR_BC1_LOOP (BNX2_BC_STATE_SIGN | 0x0300) #define BNX2_BC_STATE_ERR_UNKNOWN_CMD (BNX2_BC_STATE_SIGN | 0x0400) #define BNX2_BC_STATE_ERR_DRV_DEAD (BNX2_BC_STATE_SIGN | 0x0500) #define BNX2_BC_STATE_ERR_NO_RXP (BNX2_BC_STATE_SIGN | 0x0600) #define BNX2_BC_STATE_ERR_TOO_MANY_RBUF (BNX2_BC_STATE_SIGN | 0x0700) #define BNX2_BC_STATE_DEBUG_CMD 0x1dc #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE 0x42440000 #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE_MASK 0xffff0000 #define BNX2_BC_STATE_BC_DBG_CMD_LOOP_CNT_MASK 0xffff #define BNX2_BC_STATE_BC_DBG_CMD_LOOP_INFINITE 0xffff #define HOST_VIEW_SHMEM_BASE 0x167c00 /* Enable or disable autonegotiation. If this is set to enable, * the forced link modes above are completely ignored. */ #define AUTONEG_DISABLE 0x00 #define AUTONEG_ENABLE 0x01 #define RX_OFFSET (sizeof(struct l2_fhdr) + 2) #define RX_BUF_CNT 20 /* 8 for CRC and VLAN */ #define RX_BUF_USE_SIZE (ETH_MAX_MTU + ETH_HLEN + RX_OFFSET + 8) /* 8 for alignment */ //#define RX_BUF_SIZE (RX_BUF_USE_SIZE + 8) #define RX_BUF_SIZE (L1_CACHE_ALIGN(RX_BUF_USE_SIZE + 8)) #endif debian/grub-extras/disabled/gpxe/src/drivers/net/natsemi.h0000664000000000000000000001315012524662415021020 0ustar FILE_LICENCE ( GPL_ANY ); #define NATSEMI_HW_TIMEOUT 400 #define TX_RING_SIZE 4 #define NUM_RX_DESC 4 #define RX_BUF_SIZE 1536 #define OWN 0x80000000 #define DSIZE 0x00000FFF #define CRC_SIZE 4 struct natsemi_tx { uint32_t link; uint32_t cmdsts; uint32_t bufptr; }; struct natsemi_rx { uint32_t link; uint32_t cmdsts; uint32_t bufptr; }; struct natsemi_private { unsigned short ioaddr; unsigned short tx_cur; unsigned short tx_dirty; unsigned short rx_cur; struct natsemi_tx tx[TX_RING_SIZE]; struct natsemi_rx rx[NUM_RX_DESC]; /* need to add iobuf as we cannot free iobuf->data in close without this * alternatively substracting sizeof(head) and sizeof(list_head) can also * give the same. */ struct io_buffer *iobuf[NUM_RX_DESC]; /* netdev_tx_complete needs pointer to the iobuf of the data so as to free * it from the memory. */ struct io_buffer *tx_iobuf[TX_RING_SIZE]; struct spi_bit_basher spibit; struct spi_device eeprom; struct nvo_block nvo; }; /* * Support for fibre connections on Am79C874: * This phy needs a special setup when connected to a fibre cable. * http://www.amd.com/files/connectivitysolutions/networking/archivednetworking/22235.pdf */ #define PHYID_AM79C874 0x0022561b enum { MII_MCTRL = 0x15, /* mode control register */ MII_FX_SEL = 0x0001, /* 100BASE-FX (fiber) */ MII_EN_SCRM = 0x0004, /* enable scrambler (tp) */ }; /* values we might find in the silicon revision register */ #define SRR_DP83815_C 0x0302 #define SRR_DP83815_D 0x0403 #define SRR_DP83816_A4 0x0504 #define SRR_DP83816_A5 0x0505 /* NATSEMI: Offsets to the device registers. * Unlike software-only systems, device drivers interact with complex hardware. * It's not useful to define symbolic names for every register bit in the * device. */ enum register_offsets { ChipCmd = 0x00, ChipConfig = 0x04, EECtrl = 0x08, PCIBusCfg = 0x0C, IntrStatus = 0x10, IntrMask = 0x14, IntrEnable = 0x18, TxRingPtr = 0x20, TxConfig = 0x24, RxRingPtr = 0x30, RxConfig = 0x34, ClkRun = 0x3C, WOLCmd = 0x40, PauseCmd = 0x44, RxFilterAddr = 0x48, RxFilterData = 0x4C, BootRomAddr = 0x50, BootRomData = 0x54, SiliconRev = 0x58, StatsCtrl = 0x5C, StatsData = 0x60, RxPktErrs = 0x60, RxMissed = 0x68, RxCRCErrs = 0x64, PCIPM = 0x44, PhyStatus = 0xC0, MIntrCtrl = 0xC4, MIntrStatus = 0xC8, /* These are from the spec, around page 78... on a separate table. */ PGSEL = 0xCC, PMDCSR = 0xE4, TSTDAT = 0xFC, DSPCFG = 0xF4, SDCFG = 0x8C, BasicControl = 0x80, BasicStatus = 0x84 }; /* the values for the 'magic' registers above (PGSEL=1) */ #define PMDCSR_VAL 0x189c /* enable preferred adaptation circuitry */ #define TSTDAT_VAL 0x0 #define DSPCFG_VAL 0x5040 #define SDCFG_VAL 0x008c /* set voltage thresholds for Signal Detect */ #define DSPCFG_LOCK 0x20 /* coefficient lock bit in DSPCFG */ #define DSPCFG_COEF 0x1000 /* see coefficient (in TSTDAT) bit in DSPCFG */ #define TSTDAT_FIXED 0xe8 /* magic number for bad coefficients */ /* Bit in ChipCmd. */ enum ChipCmdBits { ChipReset = 0x100, RxReset = 0x20, TxReset = 0x10, RxOff = 0x08, RxOn = 0x04, TxOff = 0x02, TxOn = 0x01 }; enum ChipConfig_bits { CfgPhyDis = 0x200, CfgPhyRst = 0x400, CfgExtPhy = 0x1000, CfgAnegEnable = 0x2000, CfgAneg100 = 0x4000, CfgAnegFull = 0x8000, CfgAnegDone = 0x8000000, CfgFullDuplex = 0x20000000, CfgSpeed100 = 0x40000000, CfgLink = 0x80000000, }; /* Bits in the RxMode register. */ enum rx_mode_bits { AcceptErr = 0x20, AcceptRunt = 0x10, AcceptBroadcast = 0xC0000000, AcceptMulticast = 0x00200000, AcceptAllMulticast = 0x20000000, AcceptAllPhys = 0x10000000, AcceptMyPhys = 0x08000000, RxFilterEnable = 0x80000000 }; /* Bits in network_desc.status */ enum desc_status_bits { DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000, DescNoCRC = 0x10000000, DescPktOK = 0x08000000, RxTooLong = 0x00400000 }; /*Bits in Interrupt Mask register */ enum Intr_mask_register_bits { RxOk = 0x001, RxErr = 0x004, TxOk = 0x040, TxErr = 0x100 }; enum MIntrCtrl_bits { MICRIntEn = 0x2, }; /* CFG bits [13:16] [18:23] */ #define CFG_RESET_SAVE 0xfde000 /* WCSR bits [0:4] [9:10] */ #define WCSR_RESET_SAVE 0x61f /* RFCR bits [20] [22] [27:31] */ #define RFCR_RESET_SAVE 0xf8500000; /* Delay between EEPROM clock transitions. No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need a delay. */ #define eeprom_delay(ee_addr) inl(ee_addr) enum EEPROM_Ctrl_Bits { EE_ShiftClk = 0x04, EE_DataIn = 0x01, EE_ChipSelect = 0x08, EE_DataOut = 0x02 }; #define EE_Write0 (EE_ChipSelect) #define EE_Write1 (EE_ChipSelect | EE_DataIn) /* The EEPROM commands include the alway-set leading bit. */ enum EEPROM_Cmds { EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6), }; /* EEPROM access , values are devices specific */ #define EE_CS 0x08 /* EEPROM chip select */ #define EE_SK 0x04 /* EEPROM shift clock */ #define EE_DI 0x01 /* Data in */ #define EE_DO 0x02 /* Data out */ /* Offsets within EEPROM (these are word offsets) */ #define EE_MAC 7 #define EE_REG EECtrl static const uint8_t natsemi_ee_bits[] = { [SPI_BIT_SCLK] = EE_SK, [SPI_BIT_MOSI] = EE_DI, [SPI_BIT_MISO] = EE_DO, [SPI_BIT_SS(0)] = EE_CS, }; debian/grub-extras/disabled/gpxe/src/drivers/net/etherfabric_nic.h0000664000000000000000000001154712524662415022477 0ustar /************************************************************************** * * Etherboot driver for Level 5 Etherfabric network cards * * Written by Michael Brown * * Copyright Fen Systems Ltd. 2005 * Copyright Level 5 Networks Inc. 2005 * * This software may be used and distributed according to the terms of * the GNU General Public License (GPL), incorporated herein by * reference. Drivers based on or derived from this code fall under * the GPL and must retain the authorship, copyright and license * notice. * ************************************************************************** */ FILE_LICENCE ( GPL_ANY ); #ifndef EFAB_NIC_H #define EFAB_NIC_H #include #include #include #include #include /************************************************************************** * * Constants and macros * ************************************************************************** */ /* Board IDs. Early boards have no board_type, (e.g. EF1002 and 401/403) * But newer boards are getting bigger... */ typedef enum { EFAB_BOARD_INVALID = 0, /* Early boards do not have board rev. info. */ EFAB_BOARD_SFE4001 = 1, EFAB_BOARD_SFE4002 = 2, EFAB_BOARD_SFE4003 = 3, /* Insert new types before here */ EFAB_BOARD_MAX } efab_board_type; /* PHY types. */ typedef enum { PHY_TYPE_AUTO = 0, /* on development board detect between CX4 & alaska */ PHY_TYPE_CX4_RTMR = 1, PHY_TYPE_1GIG_ALASKA = 2, PHY_TYPE_10XPRESS = 3, PHY_TYPE_XFP = 4, PHY_TYPE_CX4 = 5, PHY_TYPE_PM8358 = 6, } phy_type_t; /************************************************************************** * * Hardware data structures and sizing * ************************************************************************** */ #define dma_addr_t unsigned long typedef efab_qword_t falcon_rx_desc_t; typedef efab_qword_t falcon_tx_desc_t; typedef efab_qword_t falcon_event_t; #define EFAB_BUF_ALIGN 4096 #define EFAB_RXD_SIZE 512 #define EFAB_TXD_SIZE 512 #define EFAB_EVQ_SIZE 512 #define EFAB_NUM_RX_DESC 16 #define EFAB_RX_BUF_SIZE 1600 /************************************************************************** * * Data structures * ************************************************************************** */ struct efab_nic; /* A buffer table allocation backing a tx dma, rx dma or eventq */ struct efab_special_buffer { dma_addr_t dma_addr; int id; }; /* A TX queue */ struct efab_tx_queue { /* The hardware ring */ falcon_tx_desc_t *ring; /* The software ring storing io_buffers. */ struct io_buffer *buf[EFAB_TXD_SIZE]; /* The buffer table reservation pushed to hardware */ struct efab_special_buffer entry; /* Software descriptor write ptr */ unsigned int write_ptr; /* Hardware descriptor read ptr */ unsigned int read_ptr; }; /* An RX queue */ struct efab_rx_queue { /* The hardware ring */ falcon_rx_desc_t *ring; /* The software ring storing io_buffers */ struct io_buffer *buf[EFAB_NUM_RX_DESC]; /* The buffer table reservation pushed to hardware */ struct efab_special_buffer entry; /* Descriptor write ptr, into both the hardware and software rings */ unsigned int write_ptr; /* Hardware completion ptr */ unsigned int read_ptr; }; /* An event queue */ struct efab_ev_queue { /* The hardware ring to push to hardware. * Must be the first entry in the structure */ falcon_event_t *ring; /* The buffer table reservation pushed to hardware */ struct efab_special_buffer entry; /* Pointers into the ring */ unsigned int read_ptr; }; struct efab_mac_operations { int ( * init ) ( struct efab_nic *efab ); }; struct efab_phy_operations { int ( * init ) ( struct efab_nic *efab ); unsigned int mmds; }; struct efab_board_operations { int ( * init ) ( struct efab_nic *efab ); void ( * fini ) ( struct efab_nic *efab ); }; struct efab_nic { struct net_device *netdev; int pci_revision; int is_asic; /* I2C bit-bashed interface */ struct i2c_bit_basher i2c_bb; /** SPI bus and devices, and the user visible NVO area */ struct spi_bus spi_bus; struct spi_device spi_flash; struct spi_device spi_eeprom; struct spi_device *spi; struct nvo_block nvo; /** Board, MAC, and PHY operations tables */ struct efab_board_operations *board_op; struct efab_mac_operations *mac_op; struct efab_phy_operations *phy_op; /* PHY and board types */ int phy_addr; int phy_type; int phy_10g; int board_type; /** Memory and IO base */ void *membase; unsigned int iobase; /* Buffer table allocation head */ int buffer_head; /* Queues */ struct efab_rx_queue rx_queue; struct efab_tx_queue tx_queue; struct efab_ev_queue ev_queue; /** MAC address */ uint8_t mac_addr[ETH_ALEN]; /** GMII link options */ unsigned int link_options; /** Link status */ int link_up; /** INT_REG_KER */ efab_oword_t int_ker __attribute__ (( aligned ( 16 ) )); }; #endif /* EFAB_NIC_H */ debian/grub-extras/disabled/gpxe/src/drivers/net/3c515.c0000664000000000000000000005753412524662415020131 0ustar /* * 3c515.c -- 3COM 3C515 Fast Etherlink ISA 10/100BASE-TX driver for etherboot * Copyright (C) 2002 Timothy Legge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Portions of this code: * Copyright (C) 1997-2002 Donald Becker 3c515.c: A 3Com ISA EtherLink XL "Corkscrew" ethernet driver for linux. * Copyright (C) 2001 P.J.H.Fox (fox@roestock.demon.co.uk) ISAPNP Tools * Copyright (c) 2002 Jaroslav Kysela ISA Plug & Play support Linux Kernel * Copyright (C) 2000 Shusuke Nisiyama etherboot-5.0.5 3c595.c * Coptright (C) 1995 Martin Renters etherboot-5.0.5 3c509.c * Copyright (C) 1999 LightSys Technology Services, Inc. etherboot-5.0.5 3c90x.c * Portions Copyright (C) 1999 Steve Smith etherboot-5.0.5 3c90x.c * * The probe and reset functions and defines are direct copies from the * Becker code modified where necessary to make it work for etherboot * * The poll and transmit functions either contain code from or were written by referencing * the above referenced etherboot drivers. This driver would not have been * possible without this prior work * * REVISION HISTORY: * ================ * v0.10 4-17-2002 TJL Initial implementation. * v0.11 4-17-2002 TJL Cleanup of the code * v0.12 4-26-2002 TJL Added ISA Plug and Play for Non-PNP Bioses * v0.13 6-10-2002 TJL Fixed ISA_PNP MAC Address problem * v0.14 9-23-2003 TJL Replaced delay with currticks * * Indent Options: indent -kr -i8 * *********************************************************/ FILE_LICENCE ( GPL2_OR_LATER ); /* to get some global routines like printf */ #include "etherboot.h" /* to get the interface to the body of the program */ #include "nic.h" #include #include /* for ISA_ROM */ #include static void t3c515_wait(unsigned int nticks) { unsigned int to = currticks() + nticks; while (currticks() < to) /* wait */ ; } /* TJL definations */ #define HZ 100 static int if_port; static struct corkscrew_private *vp; /* Brought directly from 3c515.c by Becker */ #define CORKSCREW 1 /* Maximum events (Rx packets, etc.) to handle at each interrupt. static int max_interrupt_work = 20; */ /* Enable the automatic media selection code -- usually set. */ #define AUTOMEDIA 1 /* Allow the use of fragment bus master transfers instead of only programmed-I/O for Vortex cards. Full-bus-master transfers are always enabled by default on Boomerang cards. If VORTEX_BUS_MASTER is defined, the feature may be turned on using 'options'. */ #define VORTEX_BUS_MASTER /* A few values that may be tweaked. */ /* Keep the ring sizes a power of two for efficiency. */ #define TX_RING_SIZE 16 #define RX_RING_SIZE 16 #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */ /* "Knobs" for adjusting internal parameters. */ /* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */ #define DRIVER_DEBUG 1 /* Some values here only for performance evaluation and path-coverage debugging. static int rx_nocopy, rx_copy, queued_packet; */ #define CORKSCREW_ID 10 #define EL3WINDOW(win_num) \ outw(SelectWindow + (win_num), nic->ioaddr + EL3_CMD) #define EL3_CMD 0x0e #define EL3_STATUS 0x0e #define RX_BYTES_MASK (unsigned short) (0x07ff) enum corkscrew_cmd { TotalReset = 0 << 11, SelectWindow = 1 << 11, StartCoax = 2 << 11, RxDisable = 3 << 11, RxEnable = 4 << 11, RxReset = 5 << 11, UpStall = 6 << 11, UpUnstall = (6 << 11) + 1, DownStall = (6 << 11) + 2, DownUnstall = (6 << 11) + 3, RxDiscard = 8 << 11, TxEnable = 9 << 11, TxDisable = 10 << 11, TxReset = 11 << 11, FakeIntr = 12 << 11, AckIntr = 13 << 11, SetIntrEnb = 14 << 11, SetStatusEnb = 15 << 11, SetRxFilter = 16 << 11, SetRxThreshold = 17 << 11, SetTxThreshold = 18 << 11, SetTxStart = 19 << 11, StartDMAUp = 20 << 11, StartDMADown = (20 << 11) + 1, StatsEnable = 21 << 11, StatsDisable = 22 << 11, StopCoax = 23 << 11, }; /* The SetRxFilter command accepts the following classes: */ enum RxFilter { RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 }; /* Bits in the general status register. */ enum corkscrew_status { IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004, TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020, IntReq = 0x0040, StatsFull = 0x0080, DMADone = 1 << 8, DownComplete = 1 << 9, UpComplete = 1 << 10, DMAInProgress = 1 << 11, /* DMA controller is still busy. */ CmdInProgress = 1 << 12, /* EL3_CMD is still busy. */ }; /* Register window 1 offsets, the window used in normal operation. On the Corkscrew this window is always mapped at offsets 0x10-0x1f. */ enum Window1 { TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14, RxStatus = 0x18, Timer = 0x1A, TxStatus = 0x1B, TxFree = 0x1C, /* Remaining free bytes in Tx buffer. */ }; enum Window0 { Wn0IRQ = 0x08, #if defined(CORKSCREW) Wn0EepromCmd = 0x200A, /* Corkscrew EEPROM command register. */ Wn0EepromData = 0x200C, /* Corkscrew EEPROM results register. */ #else Wn0EepromCmd = 10, /* Window 0: EEPROM command register. */ Wn0EepromData = 12, /* Window 0: EEPROM results register. */ #endif }; enum Win0_EEPROM_bits { EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0, EEPROM_EWENB = 0x30, /* Enable erasing/writing for 10 msec. */ EEPROM_EWDIS = 0x00, /* Disable EWENB before 10 msec timeout. */ }; enum Window3 { /* Window 3: MAC/config bits. */ Wn3_Config = 0, Wn3_MAC_Ctrl = 6, Wn3_Options = 8, }; union wn3_config { int i; struct w3_config_fields { unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2; int pad8:8; unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1; int pad24:7; } u; }; enum Window4 { Wn4_NetDiag = 6, Wn4_Media = 10, /* Window 4: Xcvr/media bits. */ }; enum Win4_Media_bits { Media_SQE = 0x0008, /* Enable SQE error counting for AUI. */ Media_10TP = 0x00C0, /* Enable link beat and jabber for 10baseT. */ Media_Lnk = 0x0080, /* Enable just link beat for 100TX/100FX. */ Media_LnkBeat = 0x0800, }; enum Window7 { /* Window 7: Bus Master control. */ Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12, }; /* Boomerang-style bus master control registers. Note ISA aliases! */ enum MasterCtrl { PktStatus = 0x400, DownListPtr = 0x404, FragAddr = 0x408, FragLen = 0x40c, TxFreeThreshold = 0x40f, UpPktStatus = 0x410, UpListPtr = 0x418, }; /* The Rx and Tx descriptor lists. Caution Alpha hackers: these types are 32 bits! Note also the 8 byte alignment contraint on tx_ring[] and rx_ring[]. */ struct boom_rx_desc { u32 next; s32 status; u32 addr; s32 length; }; /* Values for the Rx status entry. */ enum rx_desc_status { RxDComplete = 0x00008000, RxDError = 0x4000, /* See boomerang_rx() for actual error bits */ }; struct boom_tx_desc { u32 next; s32 status; u32 addr; s32 length; }; struct corkscrew_private { const char *product_name; struct net_device *next_module; /* The Rx and Tx rings are here to keep them quad-word-aligned. */ struct boom_rx_desc rx_ring[RX_RING_SIZE]; struct boom_tx_desc tx_ring[TX_RING_SIZE]; /* The addresses of transmit- and receive-in-place skbuffs. */ struct sk_buff *rx_skbuff[RX_RING_SIZE]; struct sk_buff *tx_skbuff[TX_RING_SIZE]; unsigned int cur_rx, cur_tx; /* The next free ring entry */ unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ int capabilities; /* Adapter capabilities word. */ int options; /* User-settable misc. driver options. */ int last_rx_packets; /* For media autoselection. */ unsigned int available_media:8, /* From Wn3_Options */ media_override:3, /* Passed-in media type. */ default_media:3, /* Read from the EEPROM. */ full_duplex:1, autoselect:1, bus_master:1, /* Vortex can only do a fragment bus-m. */ full_bus_master_tx:1, full_bus_master_rx:1, /* Boomerang */ tx_full:1; }; /* The action to take with a media selection timer tick. Note that we deviate from the 3Com order by checking 10base2 before AUI. */ enum xcvr_types { XCVR_10baseT = 0, XCVR_AUI, XCVR_10baseTOnly, XCVR_10base2, XCVR_100baseTx, XCVR_100baseFx, XCVR_MII = 6, XCVR_Default = 8, }; static struct media_table { char *name; unsigned int media_bits:16, /* Bits to set in Wn4_Media register. */ mask:8, /* The transceiver-present bit in Wn3_Config. */ next:8; /* The media type to try next. */ short wait; /* Time before we check media status. */ } media_tbl[] = { { "10baseT", Media_10TP, 0x08, XCVR_10base2, (14 * HZ) / 10} , { "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1 * HZ) / 10} , { "undefined", 0, 0x80, XCVR_10baseT, 10000} , { "10base2", 0, 0x10, XCVR_AUI, (1 * HZ) / 10} , { "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx, (14 * HZ) / 10} , { "100baseFX", Media_Lnk, 0x04, XCVR_MII, (14 * HZ) / 10} , { "MII", 0, 0x40, XCVR_10baseT, 3 * HZ} , { "undefined", 0, 0x01, XCVR_10baseT, 10000} , { "Default", 0, 0xFF, XCVR_10baseT, 10000} ,}; /* TILEG Modified to remove reference to dev */ static int corkscrew_found_device(int ioaddr, int irq, int product_index, int options, struct nic *nic); static int corkscrew_probe1(int ioaddr, int irq, int product_index, struct nic *nic); /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */ /* Note: this is the only limit on the number of cards supported!! */ static int options = -1; /* End Brought directly from 3c515.c by Becker */ /************************************************************************** RESET - Reset adapter ***************************************************************************/ static void t515_reset(struct nic *nic) { union wn3_config config; int i; /* Before initializing select the active media port. */ EL3WINDOW(3); if (vp->full_duplex) outb(0x20, nic->ioaddr + Wn3_MAC_Ctrl); /* Set the full-duplex bit. */ config.i = inl(nic->ioaddr + Wn3_Config); if (vp->media_override != 7) { DBG ( "Media override to transceiver %d (%s).\n", vp->media_override, media_tbl[vp->media_override].name); if_port = vp->media_override; } else if (vp->autoselect) { /* Find first available media type, starting with 100baseTx. */ if_port = 4; while (!(vp->available_media & media_tbl[if_port].mask)) if_port = media_tbl[if_port].next; DBG ( "Initial media type %s.\n", media_tbl[if_port].name); } else if_port = vp->default_media; config.u.xcvr = if_port; outl(config.i, nic->ioaddr + Wn3_Config); DBG ( "corkscrew_open() InternalConfig 0x%hX.\n", config.i); outw(TxReset, nic->ioaddr + EL3_CMD); for (i = 20; i >= 0; i--) if (!(inw(nic->ioaddr + EL3_STATUS) & CmdInProgress)) break; outw(RxReset, nic->ioaddr + EL3_CMD); /* Wait a few ticks for the RxReset command to complete. */ for (i = 20; i >= 0; i--) if (!(inw(nic->ioaddr + EL3_STATUS) & CmdInProgress)) break; outw(SetStatusEnb | 0x00, nic->ioaddr + EL3_CMD); #ifdef debug_3c515 EL3WINDOW(4); DBG ( "FIXME: fix print for irq, not 9" ); DBG ( "corkscrew_open() irq %d media status 0x%hX.\n", 9, inw(nic->ioaddr + Wn4_Media) ); #endif /* Set the station address and mask in window 2 each time opened. */ EL3WINDOW(2); for (i = 0; i < 6; i++) outb(nic->node_addr[i], nic->ioaddr + i); for (; i < 12; i += 2) outw(0, nic->ioaddr + i); if (if_port == 3) /* Start the thinnet transceiver. We should really wait 50ms... */ outw(StartCoax, nic->ioaddr + EL3_CMD); EL3WINDOW(4); outw((inw(nic->ioaddr + Wn4_Media) & ~(Media_10TP | Media_SQE)) | media_tbl[if_port].media_bits, nic->ioaddr + Wn4_Media); /* Switch to the stats window, and clear all stats by reading. */ /* outw(StatsDisable, nic->ioaddr + EL3_CMD);*/ EL3WINDOW(6); for (i = 0; i < 10; i++) inb(nic->ioaddr + i); inw(nic->ioaddr + 10); inw(nic->ioaddr + 12); /* New: On the Vortex we must also clear the BadSSD counter. */ EL3WINDOW(4); inb(nic->ioaddr + 12); /* ..and on the Boomerang we enable the extra statistics bits. */ outw(0x0040, nic->ioaddr + Wn4_NetDiag); /* Switch to register set 7 for normal use. */ EL3WINDOW(7); /* Temporarily left in place. If these FIXMEs are printed it meand that special logic for that card may need to be added see Becker's 3c515.c driver */ if (vp->full_bus_master_rx) { /* Boomerang bus master. */ printf("FIXME: Is this if necessary"); vp->cur_rx = vp->dirty_rx = 0; DBG ( " Filling in the Rx ring.\n" ); for (i = 0; i < RX_RING_SIZE; i++) { printf("FIXME: Is this if necessary"); } } if (vp->full_bus_master_tx) { /* Boomerang bus master Tx. */ vp->cur_tx = vp->dirty_tx = 0; outb(PKT_BUF_SZ >> 8, nic->ioaddr + TxFreeThreshold); /* Room for a packet. */ /* Clear the Tx ring. */ for (i = 0; i < TX_RING_SIZE; i++) vp->tx_skbuff[i] = 0; outl(0, nic->ioaddr + DownListPtr); } /* Set receiver mode: presumably accept b-case and phys addr only. */ outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm, nic->ioaddr + EL3_CMD); outw(RxEnable, nic->ioaddr + EL3_CMD); /* Enable the receiver. */ outw(TxEnable, nic->ioaddr + EL3_CMD); /* Enable transmitter. */ /* Allow status bits to be seen. */ outw(SetStatusEnb | AdapterFailure | IntReq | StatsFull | (vp->full_bus_master_tx ? DownComplete : TxAvailable) | (vp->full_bus_master_rx ? UpComplete : RxComplete) | (vp->bus_master ? DMADone : 0), nic->ioaddr + EL3_CMD); /* Ack all pending events, and set active indicator mask. */ outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, nic->ioaddr + EL3_CMD); outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete, nic->ioaddr + EL3_CMD); } /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int t515_poll(struct nic *nic, int retrieve) { short status, cst; register short rx_fifo; cst = inw(nic->ioaddr + EL3_STATUS); if ((cst & RxComplete) == 0) { /* Ack all pending events, and set active indicator mask. */ outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, nic->ioaddr + EL3_CMD); outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull | (vp-> bus_master ? DMADone : 0) | UpComplete | DownComplete, nic->ioaddr + EL3_CMD); return 0; } status = inw(nic->ioaddr + RxStatus); if (status & RxDError) { printf("RxDError\n"); outw(RxDiscard, nic->ioaddr + EL3_CMD); return 0; } rx_fifo = status & RX_BYTES_MASK; if (rx_fifo == 0) return 0; if ( ! retrieve ) return 1; DBG ( "[l=%d", rx_fifo ); insw(nic->ioaddr + RX_FIFO, nic->packet, rx_fifo / 2); if (rx_fifo & 1) nic->packet[rx_fifo - 1] = inb(nic->ioaddr + RX_FIFO); nic->packetlen = rx_fifo; while (1) { status = inw(nic->ioaddr + RxStatus); DBG ( "0x%hX*", status ); rx_fifo = status & RX_BYTES_MASK; if (rx_fifo > 0) { insw(nic->ioaddr + RX_FIFO, nic->packet + nic->packetlen, rx_fifo / 2); if (rx_fifo & 1) nic->packet[nic->packetlen + rx_fifo - 1] = inb(nic->ioaddr + RX_FIFO); nic->packetlen += rx_fifo; DBG ( "+%d", rx_fifo ); } if ((status & RxComplete) == 0) { DBG ( "=%d", nic->packetlen ); break; } udelay(1000); } /* acknowledge reception of packet */ outw(RxDiscard, nic->ioaddr + EL3_CMD); while (inw(nic->ioaddr + EL3_STATUS) & CmdInProgress); #ifdef debug_3c515 { unsigned short type = 0; type = (nic->packet[12] << 8) | nic->packet[13]; if (nic->packet[0] + nic->packet[1] + nic->packet[2] + nic->packet[3] + nic->packet[4] + nic->packet[5] == 0xFF * ETH_ALEN) DBG ( ",t=0x%hX,b]", type ); else DBG ( ",t=0x%hX]", type ); } #endif return 1; } /************************************************************************* 3Com 515 - specific routines **************************************************************************/ static char padmap[] = { 0, 3, 2, 1 }; /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void t515_transmit(struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) { /* Packet */ register int len; int pad; int status; DBG ( "{l=%d,t=0x%hX}", s + ETH_HLEN, t ); /* swap bytes of type */ t = htons(t); len = s + ETH_HLEN; /* actual length of packet */ pad = padmap[len & 3]; /* * The 3c515 automatically pads short packets to minimum ethernet length, * but we drop packets that are too large. Perhaps we should truncate * them instead? Copied from 3c595. Is this true for the 3c515? */ if (len + pad > ETH_FRAME_LEN) { return; } /* drop acknowledgements */ while ((status = inb(nic->ioaddr + TxStatus)) & TxComplete) { /*if(status & (TXS_UNDERRUN|0x88|TXS_STATUS_OVERFLOW)) { */ outw(TxReset, nic->ioaddr + EL3_CMD); outw(TxEnable, nic->ioaddr + EL3_CMD); /* } */ outb(0x0, nic->ioaddr + TxStatus); } while (inw(nic->ioaddr + TxFree) < len + pad + 4) { /* no room in FIFO */ } outw(len, nic->ioaddr + TX_FIFO); outw(0x0, nic->ioaddr + TX_FIFO); /* Second dword meaningless */ /* write packet */ outsw(nic->ioaddr + TX_FIFO, d, ETH_ALEN / 2); outsw(nic->ioaddr + TX_FIFO, nic->node_addr, ETH_ALEN / 2); outw(t, nic->ioaddr + TX_FIFO); outsw(nic->ioaddr + TX_FIFO, p, s / 2); if (s & 1) outb(*(p + s - 1), nic->ioaddr + TX_FIFO); while (pad--) outb(0, nic->ioaddr + TX_FIFO); /* Padding */ /* wait for Tx complete */ while ((inw(nic->ioaddr + EL3_STATUS) & CmdInProgress) != 0); } /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void t515_disable ( struct nic *nic, struct isapnp_device *isapnp ) { t515_reset(nic); /* This is a hack. Since ltsp worked on my system without any disable functionality I have no way to determine if this works */ /* Disable the receiver and transmitter. */ outw(RxDisable, nic->ioaddr + EL3_CMD); outw(TxDisable, nic->ioaddr + EL3_CMD); if (if_port == XCVR_10base2) /* Turn off thinnet power. Green! */ outw(StopCoax, nic->ioaddr + EL3_CMD); outw(SetIntrEnb | 0x0000, nic->ioaddr + EL3_CMD); deactivate_isapnp_device ( isapnp ); return; } static void t515_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } static struct nic_operations t515_operations = { .connect = dummy_connect, .poll = t515_poll, .transmit = t515_transmit, .irq = t515_irq, }; /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside You should omit the last argument struct pci_device * for a non-PCI NIC ***************************************************************************/ static int t515_probe ( struct nic *nic, struct isapnp_device *isapnp ) { /* Direct copy from Beckers 3c515.c removing any ISAPNP sections */ nic->ioaddr = isapnp->ioaddr; nic->irqno = isapnp->irqno; activate_isapnp_device ( isapnp ); /* Check the resource configuration for a matching ioaddr. */ if ((unsigned)(inw(nic->ioaddr + 0x2002) & 0x1f0) != (nic->ioaddr & 0x1f0)) { DBG ( "3c515 ioaddr mismatch\n" ); return 0; } /* Verify by reading the device ID from the EEPROM. */ { int timer; outw(EEPROM_Read + 7, nic->ioaddr + Wn0EepromCmd); /* Pause for at least 162 us. for the read to take place. */ for (timer = 4; timer >= 0; timer--) { t3c515_wait(1); if ((inw(nic->ioaddr + Wn0EepromCmd) & 0x0200) == 0) break; } if (inw(nic->ioaddr + Wn0EepromData) != 0x6d50) { DBG ( "3c515 read incorrect vendor ID from EEPROM" ); return 0; } } DBG ( "3c515 Resource configuration register 0x%X, DCR 0x%hX.\n", inl(nic->ioaddr + 0x2002), inw(nic->ioaddr + 0x2000) ); corkscrew_found_device(nic->ioaddr, nic->irqno, CORKSCREW_ID, options, nic); t515_reset(nic); nic->nic_op = &t515_operations; return 1; } static int corkscrew_found_device(int ioaddr, int irq, int product_index, int options, struct nic *nic) { /* Direct copy from Becker 3c515.c with unecessary parts removed */ vp->product_name = "3c515"; vp->options = options; if (options >= 0) { vp->media_override = ((options & 7) == 2) ? 0 : options & 7; vp->full_duplex = (options & 8) ? 1 : 0; vp->bus_master = (options & 16) ? 1 : 0; } else { vp->media_override = 7; vp->full_duplex = 0; vp->bus_master = 0; } corkscrew_probe1(ioaddr, irq, product_index, nic); return 0; } static int corkscrew_probe1(int ioaddr, int irq, int product_index __unused, struct nic *nic) { unsigned int eeprom[0x40], checksum = 0; /* EEPROM contents */ int i; printf("3Com %s at 0x%hX, ", vp->product_name, ioaddr); /* Read the station address from the EEPROM. */ EL3WINDOW(0); for (i = 0; i < 0x18; i++) { short *phys_addr = (short *) nic->node_addr; int timer; outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd); /* Pause for at least 162 us. for the read to take place. */ for (timer = 4; timer >= 0; timer--) { t3c515_wait(1); if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0) break; } eeprom[i] = inw(ioaddr + Wn0EepromData); DBG ( "Value %d: %hX ", i, eeprom[i] ); checksum ^= eeprom[i]; if (i < 3) phys_addr[i] = htons(eeprom[i]); } checksum = (checksum ^ (checksum >> 8)) & 0xff; if (checksum != 0x00) printf(" ***INVALID CHECKSUM 0x%hX*** ", checksum); DBG ( "%s", eth_ntoa ( nic->node_addr ) ); if (eeprom[16] == 0x11c7) { /* Corkscrew */ } printf(", IRQ %d\n", irq); /* Tell them about an invalid IRQ. */ if ( (irq <= 0 || irq > 15) ) { DBG (" *** Warning: this IRQ is unlikely to work! ***\n" ); } { char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" }; union wn3_config config; EL3WINDOW(3); vp->available_media = inw(ioaddr + Wn3_Options); config.i = inl(ioaddr + Wn3_Config); DBG ( " Internal config register is %4.4x, " "transceivers 0x%hX.\n", config.i, inw(ioaddr + Wn3_Options) ); printf (" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n", 8 << config.u.ram_size, config.u.ram_width ? "word" : "byte", ram_split[config.u.ram_split], config.u.autoselect ? "autoselect/" : "", media_tbl[config.u.xcvr].name); if_port = config.u.xcvr; vp->default_media = config.u.xcvr; vp->autoselect = config.u.autoselect; } if (vp->media_override != 7) { printf(" Media override to transceiver type %d (%s).\n", vp->media_override, media_tbl[vp->media_override].name); if_port = vp->media_override; } vp->capabilities = eeprom[16]; vp->full_bus_master_tx = (vp->capabilities & 0x20) ? 1 : 0; /* Rx is broken at 10mbps, so we always disable it. */ /* vp->full_bus_master_rx = 0; */ vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0; return 0; } static struct isapnp_device_id t515_adapters[] = { { "3c515 (ISAPnP)", ISAPNP_VENDOR('T','C','M'), 0x5051 }, }; ISAPNP_DRIVER ( t515_driver, t515_adapters ); DRIVER ( "3c515", nic_driver, isapnp_driver, t515_driver, t515_probe, t515_disable ); ISA_ROM ( "3c515", "3c515 Fast EtherLink ISAPnP" ); debian/grub-extras/disabled/gpxe/src/drivers/net/davicom.c0000664000000000000000000005126412524662415021005 0ustar #ifdef ALLMULTI #error multicast support is not yet implemented #endif /* DAVICOM DM9009/DM9102/DM9102A Etherboot Driver V1.00 This driver was ported from Marty Connor's Tulip Etherboot driver. Thanks Marty Connor (mdc@etherboot.org) This davicom etherboot driver supports DM9009/DM9102/DM9102A/ DM9102A+DM9801/DM9102A+DM9802 NICs. This software may be used and distributed according to the terms of the GNU Public License, incorporated herein by reference. */ FILE_LICENCE ( GPL_ANY ); /*********************************************************************/ /* Revision History */ /*********************************************************************/ /* 19 OCT 2000 Sten 1.00 Different half and full duplex mode Do the different programming for DM9801/DM9802 12 OCT 2000 Sten 0.90 This driver was ported from tulip driver and it has the following difference. Changed symbol tulip/TULIP to davicom/DAVICOM Deleted some code that did not use in this driver. Used chain-strcture to replace ring structure for both TX/RX descriptor. Allocated two tx descriptor. According current media mode to set operating register(CR6) */ /*********************************************************************/ /* Declarations */ /*********************************************************************/ #include "etherboot.h" #include "nic.h" #include #include #undef DAVICOM_DEBUG #undef DAVICOM_DEBUG_WHERE #define TX_TIME_OUT 2*TICKS_PER_SEC /* Register offsets for davicom device */ enum davicom_offsets { CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28, CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58, CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0 }; /* EEPROM Address width definitions */ #define EEPROM_ADDRLEN 6 #define EEPROM_SIZE 32 /* 1 << EEPROM_ADDRLEN */ /* Used to be 128, but we only need to read enough to get the MAC address at bytes 20..25 */ /* Data Read from the EEPROM */ static unsigned char ee_data[EEPROM_SIZE]; /* The EEPROM commands include the alway-set leading bit. */ #define EE_WRITE_CMD (5 << addr_len) #define EE_READ_CMD (6 << addr_len) #define EE_ERASE_CMD (7 << addr_len) /* EEPROM_Ctrl bits. */ #define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */ #define EE_CS 0x01 /* EEPROM chip select. */ #define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ #define EE_WRITE_0 0x01 #define EE_WRITE_1 0x05 #define EE_DATA_READ 0x08 /* EEPROM chip data out. */ #define EE_ENB (0x4800 | EE_CS) /* Sten 10/11 for phyxcer */ #define PHY_DATA_0 0x0 #define PHY_DATA_1 0x20000 #define MDCLKH 0x10000 /* Delay between EEPROM clock transitions. Even at 33Mhz current PCI implementations don't overrun the EEPROM clock. We add a bus turn-around to insure that this remains true. */ #define eeprom_delay() inl(ee_addr) /* helpful macro if on a big_endian machine for changing byte order. not strictly needed on Intel Already defined in Etherboot includes #define le16_to_cpu(val) (val) */ /* transmit and receive descriptor format */ struct txdesc { volatile unsigned long status; /* owner, status */ unsigned long buf1sz:11, /* size of buffer 1 */ buf2sz:11, /* size of buffer 2 */ control:10; /* control bits */ const unsigned char *buf1addr; /* buffer 1 address */ const unsigned char *buf2addr; /* buffer 2 address */ }; struct rxdesc { volatile unsigned long status; /* owner, status */ unsigned long buf1sz:11, /* size of buffer 1 */ buf2sz:11, /* size of buffer 2 */ control:10; /* control bits */ unsigned char *buf1addr; /* buffer 1 address */ unsigned char *buf2addr; /* buffer 2 address */ }; /* Size of transmit and receive buffers */ #define BUFLEN 1536 /*********************************************************************/ /* Global Storage */ /*********************************************************************/ static struct nic_operations davicom_operations; /* PCI Bus parameters */ static unsigned short vendor, dev_id; static unsigned long ioaddr; /* Note: transmit and receive buffers must be longword aligned and longword divisable */ /* transmit descriptor and buffer */ #define NTXD 2 #define NRXD 4 struct { struct txdesc txd[NTXD] __attribute__ ((aligned(4))); unsigned char txb[BUFLEN] __attribute__ ((aligned(4))); struct rxdesc rxd[NRXD] __attribute__ ((aligned(4))); unsigned char rxb[NRXD * BUFLEN] __attribute__ ((aligned(4))); } davicom_bufs __shared; #define txd davicom_bufs.txd #define txb davicom_bufs.txb #define rxd davicom_bufs.rxd #define rxb davicom_bufs.rxb static int rxd_tail; static int TxPtr; /*********************************************************************/ /* Function Prototypes */ /*********************************************************************/ static void whereami(const char *str); static int read_eeprom(unsigned long ioaddr, int location, int addr_len); static int davicom_probe(struct nic *nic,struct pci_device *pci); static void davicom_init_chain(struct nic *nic); /* Sten 10/9 */ static void davicom_reset(struct nic *nic); static void davicom_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p); static int davicom_poll(struct nic *nic, int retrieve); static void davicom_disable(struct nic *nic); #ifdef DAVICOM_DEBUG static void davicom_more(void); #endif /* DAVICOM_DEBUG */ static void davicom_wait(unsigned int nticks); static int phy_read(int); static void phy_write(int, u16); static void phy_write_1bit(u32, u32); static int phy_read_1bit(u32); static void davicom_media_chk(struct nic *); /*********************************************************************/ /* Utility Routines */ /*********************************************************************/ static inline void whereami(const char *str) { printf("%s\n", str); /* sleep(2); */ } #ifdef DAVICOM_DEBUG static void davicom_more() { printf("\n\n-- more --"); while (!iskey()) /* wait */; getchar(); printf("\n\n"); } #endif /* DAVICOM_DEBUG */ static void davicom_wait(unsigned int nticks) { unsigned int to = currticks() + nticks; while (currticks() < to) /* wait */ ; } /*********************************************************************/ /* For DAVICOM phyxcer register by MII interface */ /*********************************************************************/ /* Read a word data from phy register */ static int phy_read(int location) { int i, phy_addr=1; u16 phy_data; u32 io_dcr9; whereami("phy_read\n"); io_dcr9 = ioaddr + CSR9; /* Send 33 synchronization clock to Phy controller */ for (i=0; i<34; i++) phy_write_1bit(io_dcr9, PHY_DATA_1); /* Send start command(01) to Phy */ phy_write_1bit(io_dcr9, PHY_DATA_0); phy_write_1bit(io_dcr9, PHY_DATA_1); /* Send read command(10) to Phy */ phy_write_1bit(io_dcr9, PHY_DATA_1); phy_write_1bit(io_dcr9, PHY_DATA_0); /* Send Phy addres */ for (i=0x10; i>0; i=i>>1) phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0); /* Send register addres */ for (i=0x10; i>0; i=i>>1) phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0); /* Skip transition state */ phy_read_1bit(io_dcr9); /* read 16bit data */ for (phy_data=0, i=0; i<16; i++) { phy_data<<=1; phy_data|=phy_read_1bit(io_dcr9); } return phy_data; } /* Write a word to Phy register */ static void phy_write(int location, u16 phy_data) { u16 i, phy_addr=1; u32 io_dcr9; whereami("phy_write\n"); io_dcr9 = ioaddr + CSR9; /* Send 33 synchronization clock to Phy controller */ for (i=0; i<34; i++) phy_write_1bit(io_dcr9, PHY_DATA_1); /* Send start command(01) to Phy */ phy_write_1bit(io_dcr9, PHY_DATA_0); phy_write_1bit(io_dcr9, PHY_DATA_1); /* Send write command(01) to Phy */ phy_write_1bit(io_dcr9, PHY_DATA_0); phy_write_1bit(io_dcr9, PHY_DATA_1); /* Send Phy addres */ for (i=0x10; i>0; i=i>>1) phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0); /* Send register addres */ for (i=0x10; i>0; i=i>>1) phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0); /* written trasnition */ phy_write_1bit(io_dcr9, PHY_DATA_1); phy_write_1bit(io_dcr9, PHY_DATA_0); /* Write a word data to PHY controller */ for (i=0x8000; i>0; i>>=1) phy_write_1bit(io_dcr9, phy_data&i ? PHY_DATA_1: PHY_DATA_0); } /* Write one bit data to Phy Controller */ static void phy_write_1bit(u32 ee_addr, u32 phy_data) { whereami("phy_write_1bit\n"); outl(phy_data, ee_addr); /* MII Clock Low */ eeprom_delay(); outl(phy_data|MDCLKH, ee_addr); /* MII Clock High */ eeprom_delay(); outl(phy_data, ee_addr); /* MII Clock Low */ eeprom_delay(); } /* Read one bit phy data from PHY controller */ static int phy_read_1bit(u32 ee_addr) { int phy_data; whereami("phy_read_1bit\n"); outl(0x50000, ee_addr); eeprom_delay(); phy_data=(inl(ee_addr)>>19) & 0x1; outl(0x40000, ee_addr); eeprom_delay(); return phy_data; } /* DM9801/DM9802 present check and program */ static void HPNA_process(void) { if ( (phy_read(3) & 0xfff0) == 0xb900 ) { if ( phy_read(31) == 0x4404 ) { /* DM9801 present */ if (phy_read(3) == 0xb901) phy_write(16, 0x5); /* DM9801 E4 */ else phy_write(16, 0x1005); /* DM9801 E3 and others */ phy_write(25, ((phy_read(24) + 3) & 0xff) | 0xf000); } else { /* DM9802 present */ phy_write(16, 0x5); phy_write(25, (phy_read(25) & 0xff00) + 2); } } } /* Sense media mode and set CR6 */ static void davicom_media_chk(struct nic * nic __unused) { unsigned long to, csr6; csr6 = 0x00200000; /* SF */ outl(csr6, ioaddr + CSR6); #define PCI_DEVICE_ID_DM9009 0x9009 if (vendor == PCI_VENDOR_ID_DAVICOM && dev_id == PCI_DEVICE_ID_DM9009) { /* Set to 10BaseT mode for DM9009 */ phy_write(0, 0); } else { /* For DM9102/DM9102A */ to = currticks() + 2 * TICKS_PER_SEC; while ( ((phy_read(1) & 0x24)!=0x24) && (currticks() < to)) /* wait */ ; if ( (phy_read(1) & 0x24) == 0x24 ) { if (phy_read(17) & 0xa000) csr6 |= 0x00000200; /* Full Duplex mode */ } else csr6 |= 0x00040000; /* Select DM9801/DM9802 when Ethernet link failed */ } /* set the chip's operating mode */ outl(csr6, ioaddr + CSR6); /* DM9801/DM9802 present check & program */ if (csr6 & 0x40000) HPNA_process(); } /*********************************************************************/ /* EEPROM Reading Code */ /*********************************************************************/ /* EEPROM routines adapted from the Linux Tulip Code */ /* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->. */ static int read_eeprom(unsigned long ioaddr, int location, int addr_len) { int i; unsigned short retval = 0; long ee_addr = ioaddr + CSR9; int read_cmd = location | EE_READ_CMD; whereami("read_eeprom\n"); outl(EE_ENB & ~EE_CS, ee_addr); outl(EE_ENB, ee_addr); /* Shift the read command bits out. */ for (i = 4 + addr_len; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; outl(EE_ENB | dataval, ee_addr); eeprom_delay(); outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); eeprom_delay(); } outl(EE_ENB, ee_addr); for (i = 16; i > 0; i--) { outl(EE_ENB | EE_SHIFT_CLK, ee_addr); eeprom_delay(); retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0); outl(EE_ENB, ee_addr); eeprom_delay(); } /* Terminate the EEPROM access. */ outl(EE_ENB & ~EE_CS, ee_addr); return retval; } /*********************************************************************/ /* davicom_init_chain - setup the tx and rx descriptors */ /* Sten 10/9 */ /*********************************************************************/ static void davicom_init_chain(struct nic *nic) { int i; /* setup the transmit descriptor */ /* Sten: Set 2 TX descriptor but use one TX buffer because it transmit a packet and wait complete every time. */ for (i=0; inode_addr[0]; txb[1] = nic->node_addr[1]; txb[4] = nic->node_addr[2]; txb[5] = nic->node_addr[3]; txb[8] = nic->node_addr[4]; txb[9] = nic->node_addr[5]; /* setup receive descriptor */ for (i=0; i= to) { printf ("TX Setup Timeout!\n"); } /* Point to next TX descriptor */ TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr; /* Sten 10/9 */ #ifdef DAVICOM_DEBUG printf("txd.status = %X\n", txd.status); printf("ticks = %d\n", currticks() - (to - TX_TIME_OUT)); davicom_more(); #endif /* enable RX */ outl(inl(ioaddr + CSR6) | 0x00000002, ioaddr + CSR6); /* immediate poll demand */ outl(0, ioaddr + CSR2); } /*********************************************************************/ /* eth_transmit - Transmit a frame */ /*********************************************************************/ static void davicom_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p) { unsigned long to; whereami("davicom_transmit\n"); /* Stop Tx */ /* outl(inl(ioaddr + CSR6) & ~0x00002000, ioaddr + CSR6); */ /* setup ethernet header */ memcpy(&txb[0], d, ETH_ALEN); /* DA 6byte */ memcpy(&txb[ETH_ALEN], nic->node_addr, ETH_ALEN); /* SA 6byte*/ txb[ETH_ALEN*2] = (t >> 8) & 0xFF; /* Frame type: 2byte */ txb[ETH_ALEN*2+1] = t & 0xFF; memcpy(&txb[ETH_HLEN], p, s); /* Frame data */ /* setup the transmit descriptor */ txd[TxPtr].buf1sz = ETH_HLEN+s; txd[TxPtr].control = 0x00000184; /* LS+FS+CE */ txd[TxPtr].status = 0x80000000; /* give ownership to device */ /* immediate transmit demand */ outl(0, ioaddr + CSR1); to = currticks() + TX_TIME_OUT; while ((txd[TxPtr].status & 0x80000000) && (currticks() < to)) /* wait */ ; if (currticks() >= to) { printf ("TX Timeout!\n"); } /* Point to next TX descriptor */ TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr; /* Sten 10/9 */ } /*********************************************************************/ /* eth_poll - Wait for a frame */ /*********************************************************************/ static int davicom_poll(struct nic *nic, int retrieve) { whereami("davicom_poll\n"); if (rxd[rxd_tail].status & 0x80000000) return 0; if ( ! retrieve ) return 1; whereami("davicom_poll got one\n"); nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16; if( rxd[rxd_tail].status & 0x00008000){ rxd[rxd_tail].status = 0x80000000; rxd_tail++; if (rxd_tail == NRXD) rxd_tail = 0; return 0; } /* copy packet to working buffer */ /* XXX - this copy could be avoided with a little more work but for now we are content with it because the optimised memcpy is quite fast */ memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen); /* return the descriptor and buffer to receive ring */ rxd[rxd_tail].status = 0x80000000; rxd_tail++; if (rxd_tail == NRXD) rxd_tail = 0; return 1; } /*********************************************************************/ /* eth_disable - Disable the interface */ /*********************************************************************/ static void davicom_disable ( struct nic *nic ) { whereami("davicom_disable\n"); davicom_reset(nic); /* disable interrupts */ outl(0x00000000, ioaddr + CSR7); /* Stop the chip's Tx and Rx processes. */ outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6); /* Clear the missed-packet counter. */ inl(ioaddr + CSR8); } /*********************************************************************/ /* eth_irq - enable, disable and force interrupts */ /*********************************************************************/ static void davicom_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } /*********************************************************************/ /* eth_probe - Look for an adapter */ /*********************************************************************/ static int davicom_probe ( struct nic *nic, struct pci_device *pci ) { unsigned int i; whereami("davicom_probe\n"); if (pci->ioaddr == 0) return 0; vendor = pci->vendor; dev_id = pci->device; ioaddr = pci->ioaddr; nic->ioaddr = pci->ioaddr; nic->irqno = 0; /* wakeup chip */ pci_write_config_dword(pci, 0x40, 0x00000000); /* Stop the chip's Tx and Rx processes. */ outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6); /* Clear the missed-packet counter. */ inl(ioaddr + CSR8); /* Get MAC Address */ /* read EEPROM data */ for (i = 0; i < sizeof(ee_data)/2; i++) ((unsigned short *)ee_data)[i] = le16_to_cpu(read_eeprom(ioaddr, i, EEPROM_ADDRLEN)); /* extract MAC address from EEPROM buffer */ for (i=0; inode_addr[i] = ee_data[20+i]; DBG ( "Davicom %s at IOADDR %4.4lx\n", eth_ntoa ( nic->node_addr ), ioaddr ); /* initialize device */ davicom_reset(nic); nic->nic_op = &davicom_operations; return 1; } static struct nic_operations davicom_operations = { .connect = dummy_connect, .poll = davicom_poll, .transmit = davicom_transmit, .irq = davicom_irq, }; static struct pci_device_id davicom_nics[] = { PCI_ROM(0x1282, 0x9100, "davicom9100", "Davicom 9100", 0), PCI_ROM(0x1282, 0x9102, "davicom9102", "Davicom 9102", 0), PCI_ROM(0x1282, 0x9009, "davicom9009", "Davicom 9009", 0), PCI_ROM(0x1282, 0x9132, "davicom9132", "Davicom 9132", 0), /* Needs probably some fixing */ }; PCI_DRIVER ( davicom_driver, davicom_nics, PCI_NO_CLASS ); DRIVER ( "DAVICOM", nic_driver, pci_driver, davicom_driver, davicom_probe, davicom_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/ipoib.c0000664000000000000000000004453512524662415020470 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * IP over Infiniband */ /** Number of IPoIB send work queue entries */ #define IPOIB_NUM_SEND_WQES 2 /** Number of IPoIB receive work queue entries */ #define IPOIB_NUM_RECV_WQES 4 /** Number of IPoIB completion entries */ #define IPOIB_NUM_CQES 8 /** An IPoIB device */ struct ipoib_device { /** Network device */ struct net_device *netdev; /** Underlying Infiniband device */ struct ib_device *ibdev; /** Completion queue */ struct ib_completion_queue *cq; /** Queue pair */ struct ib_queue_pair *qp; /** Broadcast MAC */ struct ipoib_mac broadcast; /** Joined to IPv4 broadcast multicast group * * This flag indicates whether or not we have initiated the * join to the IPv4 broadcast multicast group. */ int broadcast_joined; /** IPv4 broadcast multicast group membership */ struct ib_mc_membership broadcast_membership; }; /** Broadcast IPoIB address */ static struct ipoib_mac ipoib_broadcast = { .qpn = htonl ( IB_QPN_BROADCAST ), .gid.u.bytes = { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff }, }; /**************************************************************************** * * IPoIB peer cache * **************************************************************************** */ /** * IPoIB peer address * * The IPoIB link-layer header is only four bytes long and so does not * have sufficient room to store IPoIB MAC address(es). We therefore * maintain a cache of MAC addresses identified by a single-byte key, * and abuse the spare two bytes within the link-layer header to * communicate these MAC addresses between the link-layer code and the * netdevice driver. */ struct ipoib_peer { /** Key */ uint8_t key; /** MAC address */ struct ipoib_mac mac; }; /** Number of IPoIB peer cache entries * * Must be a power of two. */ #define IPOIB_NUM_CACHED_PEERS 4 /** IPoIB peer address cache */ static struct ipoib_peer ipoib_peer_cache[IPOIB_NUM_CACHED_PEERS]; /** Oldest IPoIB peer cache entry index */ static unsigned int ipoib_peer_cache_idx = 1; /** * Look up cached peer by key * * @v key Peer cache key * @ret peer Peer cache entry, or NULL */ static struct ipoib_peer * ipoib_lookup_peer_by_key ( unsigned int key ) { struct ipoib_peer *peer; unsigned int i; for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) { peer = &ipoib_peer_cache[i]; if ( peer->key == key ) return peer; } if ( key != 0 ) { DBG ( "IPoIB warning: peer cache lost track of key %x while " "still in use\n", key ); } return NULL; } /** * Store GID and QPN in peer cache * * @v gid Peer GID * @v qpn Peer QPN * @ret peer Peer cache entry */ static struct ipoib_peer * ipoib_cache_peer ( const struct ipoib_mac *mac ) { struct ipoib_peer *peer; unsigned int key; unsigned int i; /* Look for existing cache entry */ for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) { peer = &ipoib_peer_cache[i]; if ( memcmp ( &peer->mac, mac, sizeof ( peer->mac ) ) == 0 ) return peer; } /* No entry found: create a new one */ key = ipoib_peer_cache_idx++; peer = &ipoib_peer_cache[ key % IPOIB_NUM_CACHED_PEERS ]; if ( peer->key ) DBG ( "IPoIB peer %x evicted from cache\n", peer->key ); memset ( peer, 0, sizeof ( *peer ) ); peer->key = key; memcpy ( &peer->mac, mac, sizeof ( peer->mac ) ); DBG ( "IPoIB peer %x has MAC %s\n", peer->key, ipoib_ntoa ( &peer->mac ) ); return peer; } /**************************************************************************** * * IPoIB link layer * **************************************************************************** */ /** * Add IPoIB link-layer header * * @v netdev Network device * @v iobuf I/O buffer * @v ll_dest Link-layer destination address * @v ll_source Source link-layer address * @v net_proto Network-layer protocol, in network-byte order * @ret rc Return status code */ static int ipoib_push ( struct net_device *netdev __unused, struct io_buffer *iobuf, const void *ll_dest, const void *ll_source __unused, uint16_t net_proto ) { struct ipoib_hdr *ipoib_hdr = iob_push ( iobuf, sizeof ( *ipoib_hdr ) ); const struct ipoib_mac *dest_mac = ll_dest; const struct ipoib_mac *src_mac = ll_source; struct ipoib_peer *dest; struct ipoib_peer *src; /* Add link-layer addresses to cache */ dest = ipoib_cache_peer ( dest_mac ); src = ipoib_cache_peer ( src_mac ); /* Build IPoIB header */ ipoib_hdr->proto = net_proto; ipoib_hdr->u.peer.dest = dest->key; ipoib_hdr->u.peer.src = src->key; return 0; } /** * Remove IPoIB link-layer header * * @v netdev Network device * @v iobuf I/O buffer * @ret ll_dest Link-layer destination address * @ret ll_source Source link-layer address * @ret net_proto Network-layer protocol, in network-byte order * @ret rc Return status code */ static int ipoib_pull ( struct net_device *netdev, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t *net_proto ) { struct ipoib_device *ipoib = netdev->priv; struct ipoib_hdr *ipoib_hdr = iobuf->data; struct ipoib_peer *dest; struct ipoib_peer *source; /* Sanity check */ if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) { DBG ( "IPoIB packet too short for link-layer header\n" ); DBG_HD ( iobuf->data, iob_len ( iobuf ) ); return -EINVAL; } /* Strip off IPoIB header */ iob_pull ( iobuf, sizeof ( *ipoib_hdr ) ); /* Identify source and destination addresses, and clear * reserved word in IPoIB header */ dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest ); source = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.src ); ipoib_hdr->u.reserved = 0; /* Fill in required fields */ *ll_dest = ( dest ? &dest->mac : &ipoib->broadcast ); *ll_source = ( source ? &source->mac : &ipoib->broadcast ); *net_proto = ipoib_hdr->proto; return 0; } /** * Initialise IPoIB link-layer address * * @v hw_addr Hardware address * @v ll_addr Link-layer address */ static void ipoib_init_addr ( const void *hw_addr, void *ll_addr ) { const struct ib_gid_half *guid = hw_addr; struct ipoib_mac *mac = ll_addr; memset ( mac, 0, sizeof ( *mac ) ); memcpy ( &mac->gid.u.half[1], guid, sizeof ( mac->gid.u.half[1] ) ); } /** * Transcribe IPoIB link-layer address * * @v ll_addr Link-layer address * @ret string Link-layer address in human-readable format */ const char * ipoib_ntoa ( const void *ll_addr ) { static char buf[45]; const struct ipoib_mac *mac = ll_addr; snprintf ( buf, sizeof ( buf ), "%08x:%08x:%08x:%08x:%08x", htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ), htonl ( mac->gid.u.dwords[1] ), htonl ( mac->gid.u.dwords[2] ), htonl ( mac->gid.u.dwords[3] ) ); return buf; } /** * Hash multicast address * * @v af Address family * @v net_addr Network-layer address * @v ll_addr Link-layer address to fill in * @ret rc Return status code */ static int ipoib_mc_hash ( unsigned int af __unused, const void *net_addr __unused, void *ll_addr __unused ) { return -ENOTSUP; } /** IPoIB protocol */ struct ll_protocol ipoib_protocol __ll_protocol = { .name = "IPoIB", .ll_proto = htons ( ARPHRD_INFINIBAND ), .hw_addr_len = sizeof ( struct ib_gid_half ), .ll_addr_len = IPOIB_ALEN, .ll_header_len = IPOIB_HLEN, .push = ipoib_push, .pull = ipoib_pull, .init_addr = ipoib_init_addr, .ntoa = ipoib_ntoa, .mc_hash = ipoib_mc_hash, }; /** * Allocate IPoIB device * * @v priv_size Size of driver private data * @ret netdev Network device, or NULL */ struct net_device * alloc_ipoibdev ( size_t priv_size ) { struct net_device *netdev; netdev = alloc_netdev ( priv_size ); if ( netdev ) { netdev->ll_protocol = &ipoib_protocol; netdev->ll_broadcast = ( uint8_t * ) &ipoib_broadcast; netdev->max_pkt_len = IB_MAX_PAYLOAD_SIZE; } return netdev; } /**************************************************************************** * * IPoIB network device * **************************************************************************** */ /** * Transmit packet via IPoIB network device * * @v netdev Network device * @v iobuf I/O buffer * @ret rc Return status code */ static int ipoib_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { struct ipoib_device *ipoib = netdev->priv; struct ib_device *ibdev = ipoib->ibdev; struct ipoib_hdr *ipoib_hdr; struct ipoib_peer *dest; struct ib_address_vector av; int rc; /* Sanity check */ if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) { DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib ); return -EINVAL; } ipoib_hdr = iobuf->data; /* Attempting transmission while link is down will put the * queue pair into an error state, so don't try it. */ if ( ! ib_link_ok ( ibdev ) ) return -ENETUNREACH; /* Identify destination address */ dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest ); if ( ! dest ) return -ENXIO; ipoib_hdr->u.reserved = 0; /* Construct address vector */ memset ( &av, 0, sizeof ( av ) ); av.qpn = ntohl ( dest->mac.qpn ); av.gid_present = 1; memcpy ( &av.gid, &dest->mac.gid, sizeof ( av.gid ) ); if ( ( rc = ib_resolve_path ( ibdev, &av ) ) != 0 ) { /* Path not resolved yet */ return rc; } return ib_post_send ( ibdev, ipoib->qp, &av, iobuf ); } /** * Handle IPoIB send completion * * @v ibdev Infiniband device * @v qp Queue pair * @v iobuf I/O buffer * @v rc Completion status code */ static void ipoib_complete_send ( struct ib_device *ibdev __unused, struct ib_queue_pair *qp, struct io_buffer *iobuf, int rc ) { struct ipoib_device *ipoib = ib_qp_get_ownerdata ( qp ); netdev_tx_complete_err ( ipoib->netdev, iobuf, rc ); } /** * Handle IPoIB receive completion * * @v ibdev Infiniband device * @v qp Queue pair * @v av Address vector, or NULL * @v iobuf I/O buffer * @v rc Completion status code */ static void ipoib_complete_recv ( struct ib_device *ibdev __unused, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf, int rc ) { struct ipoib_device *ipoib = ib_qp_get_ownerdata ( qp ); struct net_device *netdev = ipoib->netdev; struct ipoib_hdr *ipoib_hdr; struct ipoib_mac ll_src; struct ipoib_peer *src; if ( rc != 0 ) { netdev_rx_err ( netdev, iobuf, rc ); return; } /* Sanity check */ if ( iob_len ( iobuf ) < sizeof ( struct ipoib_hdr ) ) { DBGC ( ipoib, "IPoIB %p received packet too short to " "contain IPoIB header\n", ipoib ); DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) ); netdev_rx_err ( netdev, iobuf, -EIO ); return; } ipoib_hdr = iobuf->data; /* Parse source address */ if ( av->gid_present ) { ll_src.qpn = htonl ( av->qpn ); memcpy ( &ll_src.gid, &av->gid, sizeof ( ll_src.gid ) ); src = ipoib_cache_peer ( &ll_src ); ipoib_hdr->u.peer.src = src->key; } /* Hand off to network layer */ netdev_rx ( netdev, iobuf ); } /** IPoIB completion operations */ static struct ib_completion_queue_operations ipoib_cq_op = { .complete_send = ipoib_complete_send, .complete_recv = ipoib_complete_recv, }; /** * Poll IPoIB network device * * @v netdev Network device */ static void ipoib_poll ( struct net_device *netdev ) { struct ipoib_device *ipoib = netdev->priv; struct ib_device *ibdev = ipoib->ibdev; ib_poll_eq ( ibdev ); } /** * Enable/disable interrupts on IPoIB network device * * @v netdev Network device * @v enable Interrupts should be enabled */ static void ipoib_irq ( struct net_device *netdev __unused, int enable __unused ) { /* No implementation */ } /** * Handle IPv4 broadcast multicast group join completion * * @v ibdev Infiniband device * @v qp Queue pair * @v membership Multicast group membership * @v rc Status code * @v mad Response MAD (or NULL on error) */ void ipoib_join_complete ( struct ib_device *ibdev __unused, struct ib_queue_pair *qp __unused, struct ib_mc_membership *membership, int rc, union ib_mad *mad __unused ) { struct ipoib_device *ipoib = container_of ( membership, struct ipoib_device, broadcast_membership ); /* Record join status as link status */ netdev_link_err ( ipoib->netdev, rc ); } /** * Join IPv4 broadcast multicast group * * @v ipoib IPoIB device * @ret rc Return status code */ static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) { int rc; if ( ( rc = ib_mcast_join ( ipoib->ibdev, ipoib->qp, &ipoib->broadcast_membership, &ipoib->broadcast.gid, ipoib_join_complete ) ) != 0 ) { DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n", ipoib, strerror ( rc ) ); return rc; } ipoib->broadcast_joined = 1; return 0; } /** * Leave IPv4 broadcast multicast group * * @v ipoib IPoIB device */ static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) { if ( ipoib->broadcast_joined ) { ib_mcast_leave ( ipoib->ibdev, ipoib->qp, &ipoib->broadcast_membership ); ipoib->broadcast_joined = 0; } } /** * Open IPoIB network device * * @v netdev Network device * @ret rc Return status code */ static int ipoib_open ( struct net_device *netdev ) { struct ipoib_device *ipoib = netdev->priv; struct ib_device *ibdev = ipoib->ibdev; struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr ); int rc; /* Open IB device */ if ( ( rc = ib_open ( ibdev ) ) != 0 ) { DBGC ( ipoib, "IPoIB %p could not open device: %s\n", ipoib, strerror ( rc ) ); goto err_ib_open; } /* Allocate completion queue */ ipoib->cq = ib_create_cq ( ibdev, IPOIB_NUM_CQES, &ipoib_cq_op ); if ( ! ipoib->cq ) { DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n", ipoib ); rc = -ENOMEM; goto err_create_cq; } /* Allocate queue pair */ ipoib->qp = ib_create_qp ( ibdev, IB_QPT_UD, IPOIB_NUM_SEND_WQES, ipoib->cq, IPOIB_NUM_RECV_WQES, ipoib->cq ); if ( ! ipoib->qp ) { DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n", ipoib ); rc = -ENOMEM; goto err_create_qp; } ib_qp_set_ownerdata ( ipoib->qp, ipoib ); /* Update MAC address with QPN */ mac->qpn = htonl ( ipoib->qp->qpn ); /* Fill receive rings */ ib_refill_recv ( ibdev, ipoib->qp ); /* Fake a link status change to join the broadcast group */ ipoib_link_state_changed ( ibdev ); return 0; ib_destroy_qp ( ibdev, ipoib->qp ); err_create_qp: ib_destroy_cq ( ibdev, ipoib->cq ); err_create_cq: ib_close ( ibdev ); err_ib_open: return rc; } /** * Close IPoIB network device * * @v netdev Network device */ static void ipoib_close ( struct net_device *netdev ) { struct ipoib_device *ipoib = netdev->priv; struct ib_device *ibdev = ipoib->ibdev; struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr ); /* Leave broadcast group */ ipoib_leave_broadcast_group ( ipoib ); /* Remove QPN from MAC address */ mac->qpn = 0; /* Tear down the queues */ ib_destroy_qp ( ibdev, ipoib->qp ); ib_destroy_cq ( ibdev, ipoib->cq ); /* Close IB device */ ib_close ( ibdev ); } /** IPoIB network device operations */ static struct net_device_operations ipoib_operations = { .open = ipoib_open, .close = ipoib_close, .transmit = ipoib_transmit, .poll = ipoib_poll, .irq = ipoib_irq, }; /** * Handle link status change * * @v ibdev Infiniband device */ void ipoib_link_state_changed ( struct ib_device *ibdev ) { struct net_device *netdev = ib_get_ownerdata ( ibdev ); struct ipoib_device *ipoib = netdev->priv; struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr ); int rc; /* Leave existing broadcast group */ ipoib_leave_broadcast_group ( ipoib ); /* Update MAC address based on potentially-new GID prefix */ memcpy ( &mac->gid.u.half[0], &ibdev->gid.u.half[0], sizeof ( mac->gid.u.half[0] ) ); /* Update broadcast GID based on potentially-new partition key */ ipoib->broadcast.gid.u.words[2] = htons ( ibdev->pkey ); /* Set net device link state to reflect Infiniband link state */ if ( ib_link_ok ( ibdev ) ) { netdev_link_up ( netdev ); } else { netdev_link_down ( netdev ); } /* Join new broadcast group */ if ( ib_link_ok ( ibdev ) && ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) ) { DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: " "%s\n", ipoib, strerror ( rc ) ); return; } } /** * Probe IPoIB device * * @v ibdev Infiniband device * @ret rc Return status code */ int ipoib_probe ( struct ib_device *ibdev ) { struct net_device *netdev; struct ipoib_device *ipoib; int rc; /* Allocate network device */ netdev = alloc_ipoibdev ( sizeof ( *ipoib ) ); if ( ! netdev ) return -ENOMEM; netdev_init ( netdev, &ipoib_operations ); ipoib = netdev->priv; ib_set_ownerdata ( ibdev, netdev ); netdev->dev = ibdev->dev; memset ( ipoib, 0, sizeof ( *ipoib ) ); ipoib->netdev = netdev; ipoib->ibdev = ibdev; /* Extract hardware address */ memcpy ( netdev->hw_addr, &ibdev->gid.u.half[1], sizeof ( ibdev->gid.u.half[1] ) ); /* Set default broadcast address */ memcpy ( &ipoib->broadcast, &ipoib_broadcast, sizeof ( ipoib->broadcast ) ); netdev->ll_broadcast = ( ( uint8_t * ) &ipoib->broadcast ); /* Register network device */ if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err_register_netdev; return 0; err_register_netdev: netdev_nullify ( netdev ); netdev_put ( netdev ); return rc; } /** * Remove IPoIB device * * @v ibdev Infiniband device */ void ipoib_remove ( struct ib_device *ibdev ) { struct net_device *netdev = ib_get_ownerdata ( ibdev ); unregister_netdev ( netdev ); netdev_nullify ( netdev ); netdev_put ( netdev ); } debian/grub-extras/disabled/gpxe/src/drivers/net/legacy.c0000664000000000000000000000740512524662415020625 0ustar #include #include #include #include #include #include #include #include /* * Quick and dirty compatibility layer * * This should allow old-API PCI drivers to at least function until * they are updated. It will not help non-PCI drivers. * * No drivers should rely on this code. It will be removed asap. * */ FILE_LICENCE ( GPL2_OR_LATER ); struct nic nic; static int legacy_registered = 0; static int legacy_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { struct nic *nic = netdev->priv; struct ethhdr *ethhdr; DBG ( "Transmitting %zd bytes\n", iob_len ( iobuf ) ); iob_pad ( iobuf, ETH_ZLEN ); ethhdr = iobuf->data; iob_pull ( iobuf, sizeof ( *ethhdr ) ); nic->nic_op->transmit ( nic, ( const char * ) ethhdr->h_dest, ntohs ( ethhdr->h_protocol ), iob_len ( iobuf ), iobuf->data ); netdev_tx_complete ( netdev, iobuf ); return 0; } static void legacy_poll ( struct net_device *netdev ) { struct nic *nic = netdev->priv; struct io_buffer *iobuf; iobuf = alloc_iob ( ETH_FRAME_LEN ); if ( ! iobuf ) return; nic->packet = iobuf->data; if ( nic->nic_op->poll ( nic, 1 ) ) { DBG ( "Received %d bytes\n", nic->packetlen ); iob_put ( iobuf, nic->packetlen ); netdev_rx ( netdev, iobuf ); } else { free_iob ( iobuf ); } } static int legacy_open ( struct net_device *netdev __unused ) { /* Nothing to do */ return 0; } static void legacy_close ( struct net_device *netdev __unused ) { /* Nothing to do */ } static void legacy_irq ( struct net_device *netdev __unused, int enable ) { struct nic *nic = netdev->priv; nic->nic_op->irq ( nic, ( enable ? ENABLE : DISABLE ) ); } static struct net_device_operations legacy_operations = { .open = legacy_open, .close = legacy_close, .transmit = legacy_transmit, .poll = legacy_poll, .irq = legacy_irq, }; int legacy_probe ( void *hwdev, void ( * set_drvdata ) ( void *hwdev, void *priv ), struct device *dev, int ( * probe ) ( struct nic *nic, void *hwdev ), void ( * disable ) ( struct nic *nic, void *hwdev ) ) { struct net_device *netdev; int rc; if ( legacy_registered ) return -EBUSY; netdev = alloc_etherdev ( 0 ); if ( ! netdev ) return -ENOMEM; netdev_init ( netdev, &legacy_operations ); netdev->priv = &nic; memset ( &nic, 0, sizeof ( nic ) ); set_drvdata ( hwdev, netdev ); netdev->dev = dev; nic.node_addr = netdev->hw_addr; // nic.irqno = dev->desc.irq; if ( ! probe ( &nic, hwdev ) ) { rc = -ENODEV; goto err_probe; } /* Overwrite the IRQ number. Some legacy devices set * nic->irqno to 0 in the probe routine to indicate that they * don't support interrupts; doing this allows the timer * interrupt to be used instead. */ // dev->desc.irq = nic.irqno; /* Mark as link up; legacy devices don't handle link state */ netdev_link_up ( netdev ); if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err_register; /* Do not remove this message */ printf ( "WARNING: Using legacy NIC wrapper on %s\n", netdev->ll_protocol->ntoa ( nic.node_addr ) ); legacy_registered = 1; return 0; err_register: disable ( &nic, hwdev ); err_probe: netdev_nullify ( netdev ); netdev_put ( netdev ); return rc; } void legacy_remove ( void *hwdev, void * ( * get_drvdata ) ( void *hwdev ), void ( * disable ) ( struct nic *nic, void *hwdev ) ) { struct net_device *netdev = get_drvdata ( hwdev ); struct nic *nic = netdev->priv; unregister_netdev ( netdev ); disable ( nic, hwdev ); netdev_nullify ( netdev ); netdev_put ( netdev ); legacy_registered = 0; } int dummy_connect ( struct nic *nic __unused ) { return 1; } void dummy_irq ( struct nic *nic __unused, irq_action_t irq_action __unused ) { return; } debian/grub-extras/disabled/gpxe/src/drivers/net/r8169.h0000664000000000000000000003372612524662415020164 0ustar /* * Copyright (c) 2008 Marty Connor * Copyright (c) 2008 Entity Cyber, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * This driver is based on rtl8169 data sheets and work by: * * Copyright (c) 2002 ShuChen * Copyright (c) 2003 - 2007 Francois Romieu * Copyright (c) a lot of people too. Please respect their work. * */ FILE_LICENCE ( GPL2_OR_LATER ); #ifndef _R8169_H_ #define _R8169_H_ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) /** FIXME: include/linux/pci_regs.h has these PCI regs, maybe we need such a file in gPXE? **/ #define PCI_EXP_DEVCTL 8 /* Device Control */ #define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ #define PCI_EXP_LNKCTL 16 /* Link Control */ #define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 /* Enable clkreq */ #define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ /** FIXME: update mii.h in src/include/mii.h from Linux sources so we don't have to include these definitiions. **/ /* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */ #define SPEED_10 10 #define SPEED_100 100 #define SPEED_1000 1000 #define SPEED_2500 2500 #define SPEED_10000 10000 /* Duplex, half or full. */ #define DUPLEX_HALF 0x00 #define DUPLEX_FULL 0x01 #define AUTONEG_DISABLE 0x00 #define AUTONEG_ENABLE 0x01 /* MAC address length */ #define MAC_ADDR_LEN 6 #define MAX_READ_REQUEST_SHIFT 12 #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ #define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */ #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ #define R8169_REGS_SIZE 256 #define R8169_NAPI_WEIGHT 64 #define NUM_TX_DESC 8 /* Number of Tx descriptor registers */ #define NUM_RX_DESC 8 /* Number of Rx descriptor registers */ #define RX_BUF_SIZE 1536 /* Rx Buffer size */ #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) #define TX_RING_ALIGN 256 #define RX_RING_ALIGN 256 #define RTL8169_TX_TIMEOUT (6*HZ) #define RTL8169_PHY_TIMEOUT (10*HZ) #define RTL_EEPROM_SIG cpu_to_le32(0x8129) #define RTL_EEPROM_SIG_MASK cpu_to_le32(0xffff) #define RTL_EEPROM_SIG_ADDR 0x0000 /* write/read MMIO register */ #define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) #define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) #define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) #define RTL_R8(reg) readb (ioaddr + (reg)) #define RTL_R16(reg) readw (ioaddr + (reg)) #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) enum mac_version { RTL_GIGA_MAC_VER_01 = 0x01, // 8169 RTL_GIGA_MAC_VER_02 = 0x02, // 8169S RTL_GIGA_MAC_VER_03 = 0x03, // 8110S RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe RTL_GIGA_MAC_VER_07 = 0x07, // 8102e RTL_GIGA_MAC_VER_08 = 0x08, // 8102e RTL_GIGA_MAC_VER_09 = 0x09, // 8102e RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 ? RTL_GIGA_MAC_VER_15 = 0x0f, // 8101 ? RTL_GIGA_MAC_VER_16 = 0x11, // 8101Ec RTL_GIGA_MAC_VER_17 = 0x10, // 8168Bf RTL_GIGA_MAC_VER_18 = 0x12, // 8168CP RTL_GIGA_MAC_VER_19 = 0x13, // 8168C RTL_GIGA_MAC_VER_20 = 0x14, // 8168C RTL_GIGA_MAC_VER_21 = 0x15, // 8168C RTL_GIGA_MAC_VER_22 = 0x16, // 8168C RTL_GIGA_MAC_VER_23 = 0x17, // 8168CP RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP RTL_GIGA_MAC_VER_25 = 0x19, // 8168D }; #define _R(NAME,MAC,MASK) \ { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK } static const struct { const char *name; u8 mac_version; u32 RxConfigMask; /* Clears the bits supported by this chip */ } rtl_chip_info[] = { _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169 _R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139 _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880), // PCI-E 8139 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_17, 0xff7e1880), // PCI-E _R("RTL8101e", RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, 0xff7e1880), // PCI-E _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_21, 0xff7e1880), // PCI-E _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880) // PCI-E }; #undef _R enum cfg_version { RTL_CFG_0 = 0x00, RTL_CFG_1, RTL_CFG_2 }; #if 0 /** Device Table from Linux Driver **/ static struct pci_device_id rtl8169_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, RTL_CFG_2 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xc107), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, { 0x0001, 0x8168, PCI_ANY_ID, 0x2410, 0, 0, RTL_CFG_2 }, {0,}, }; #endif enum rtl_registers { MAC0 = 0, /* Ethernet hardware address. */ MAC4 = 4, MAR0 = 8, /* Multicast filter. */ CounterAddrLow = 0x10, CounterAddrHigh = 0x14, TxDescStartAddrLow = 0x20, TxDescStartAddrHigh = 0x24, TxHDescStartAddrLow = 0x28, TxHDescStartAddrHigh = 0x2c, FLASH = 0x30, ERSR = 0x36, ChipCmd = 0x37, TxPoll = 0x38, IntrMask = 0x3c, IntrStatus = 0x3e, TxConfig = 0x40, RxConfig = 0x44, RxMissed = 0x4c, Cfg9346 = 0x50, Config0 = 0x51, Config1 = 0x52, Config2 = 0x53, Config3 = 0x54, Config4 = 0x55, Config5 = 0x56, MultiIntr = 0x5c, PHYAR = 0x60, PHYstatus = 0x6c, RxMaxSize = 0xda, CPlusCmd = 0xe0, IntrMitigate = 0xe2, RxDescAddrLow = 0xe4, RxDescAddrHigh = 0xe8, EarlyTxThres = 0xec, FuncEvent = 0xf0, FuncEventMask = 0xf4, FuncPresetState = 0xf8, FuncForceEvent = 0xfc, }; enum rtl8110_registers { TBICSR = 0x64, TBI_ANAR = 0x68, TBI_LPAR = 0x6a, }; enum rtl8168_8101_registers { CSIDR = 0x64, CSIAR = 0x68, #define CSIAR_FLAG 0x80000000 #define CSIAR_WRITE_CMD 0x80000000 #define CSIAR_BYTE_ENABLE 0x0f #define CSIAR_BYTE_ENABLE_SHIFT 12 #define CSIAR_ADDR_MASK 0x0fff EPHYAR = 0x80, #define EPHYAR_FLAG 0x80000000 #define EPHYAR_WRITE_CMD 0x80000000 #define EPHYAR_REG_MASK 0x1f #define EPHYAR_REG_SHIFT 16 #define EPHYAR_DATA_MASK 0xffff DBG_REG = 0xd1, #define FIX_NAK_1 (1 << 4) #define FIX_NAK_2 (1 << 3) }; enum rtl_register_content { /* InterruptStatusBits */ SYSErr = 0x8000, PCSTimeout = 0x4000, SWInt = 0x0100, TxDescUnavail = 0x0080, RxFIFOOver = 0x0040, LinkChg = 0x0020, RxOverflow = 0x0010, TxErr = 0x0008, TxOK = 0x0004, RxErr = 0x0002, RxOK = 0x0001, /* RxStatusDesc */ RxFOVF = (1 << 23), RxRWT = (1 << 22), RxRES = (1 << 21), RxRUNT = (1 << 20), RxCRC = (1 << 19), /* ChipCmdBits */ CmdReset = 0x10, CmdRxEnb = 0x08, CmdTxEnb = 0x04, RxBufEmpty = 0x01, /* TXPoll register p.5 */ HPQ = 0x80, /* Poll cmd on the high prio queue */ NPQ = 0x40, /* Poll cmd on the low prio queue */ FSWInt = 0x01, /* Forced software interrupt */ /* Cfg9346Bits */ Cfg9346_Lock = 0x00, Cfg9346_Unlock = 0xc0, /* rx_mode_bits */ AcceptErr = 0x20, AcceptRunt = 0x10, AcceptBroadcast = 0x08, AcceptMulticast = 0x04, AcceptMyPhys = 0x02, AcceptAllPhys = 0x01, /* RxConfigBits */ RxCfgFIFOShift = 13, RxCfgDMAShift = 8, /* TxConfigBits */ TxInterFrameGapShift = 24, TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ /* Config1 register p.24 */ LEDS1 = (1 << 7), LEDS0 = (1 << 6), MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */ Speed_down = (1 << 4), MEMMAP = (1 << 3), IOMAP = (1 << 2), VPD = (1 << 1), PMEnable = (1 << 0), /* Power Management Enable */ /* Config2 register p. 25 */ PCI_Clock_66MHz = 0x01, PCI_Clock_33MHz = 0x00, /* Config3 register p.25 */ MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */ /* Config5 register p.27 */ BWF = (1 << 6), /* Accept Broadcast wakeup frame */ MWF = (1 << 5), /* Accept Multicast wakeup frame */ UWF = (1 << 4), /* Accept Unicast wakeup frame */ LanWake = (1 << 1), /* LanWake enable/disable */ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ /* TBICSR p.28 */ TBIReset = 0x80000000, TBILoopback = 0x40000000, TBINwEnable = 0x20000000, TBINwRestart = 0x10000000, TBILinkOk = 0x02000000, TBINwComplete = 0x01000000, /* CPlusCmd p.31 */ EnableBist = (1 << 15), // 8168 8101 Mac_dbgo_oe = (1 << 14), // 8168 8101 Normal_mode = (1 << 13), // unused Force_half_dup = (1 << 12), // 8168 8101 Force_rxflow_en = (1 << 11), // 8168 8101 Force_txflow_en = (1 << 10), // 8168 8101 Cxpl_dbg_sel = (1 << 9), // 8168 8101 ASF = (1 << 8), // 8168 8101 PktCntrDisable = (1 << 7), // 8168 8101 Mac_dbgo_sel = 0x001c, // 8168 RxVlan = (1 << 6), RxChkSum = (1 << 5), PCIDAC = (1 << 4), PCIMulRW = (1 << 3), INTT_0 = 0x0000, // 8168 INTT_1 = 0x0001, // 8168 INTT_2 = 0x0002, // 8168 INTT_3 = 0x0003, // 8168 /* rtl8169_PHYstatus */ TBI_Enable = 0x80, TxFlowCtrl = 0x40, RxFlowCtrl = 0x20, _1000bpsF = 0x10, _100bps = 0x08, _10bps = 0x04, LinkStatus = 0x02, FullDup = 0x01, /* _TBICSRBit */ TBILinkOK = 0x02000000, /* DumpCounterCommand */ CounterDump = 0x8, }; enum desc_status_bit { DescOwn = (1 << 31), /* Descriptor is owned by NIC */ RingEnd = (1 << 30), /* End of descriptor ring */ FirstFrag = (1 << 29), /* First segment of a packet */ LastFrag = (1 << 28), /* Final segment of a packet */ /* Tx private */ LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ MSSShift = 16, /* MSS value position */ MSSMask = 0xfff, /* MSS value + LargeSend bit: 12 bits */ IPCS = (1 << 18), /* Calculate IP checksum */ UDPCS = (1 << 17), /* Calculate UDP/IP checksum */ TCPCS = (1 << 16), /* Calculate TCP/IP checksum */ TxVlanTag = (1 << 17), /* Add VLAN tag */ /* Rx private */ PID1 = (1 << 18), /* Protocol ID bit 1/2 */ PID0 = (1 << 17), /* Protocol ID bit 2/2 */ #define RxProtoUDP (PID1) #define RxProtoTCP (PID0) #define RxProtoIP (PID1 | PID0) #define RxProtoMask RxProtoIP IPFail = (1 << 16), /* IP checksum failed */ UDPFail = (1 << 15), /* UDP/IP checksum failed */ TCPFail = (1 << 14), /* TCP/IP checksum failed */ RxVlanTag = (1 << 16), /* VLAN tag available */ }; #define RsvdMask 0x3fffc000 struct TxDesc { volatile uint32_t opts1; volatile uint32_t opts2; volatile uint32_t addr_lo; volatile uint32_t addr_hi; }; struct RxDesc { volatile uint32_t opts1; volatile uint32_t opts2; volatile uint32_t addr_lo; volatile uint32_t addr_hi; }; enum features { RTL_FEATURE_WOL = (1 << 0), RTL_FEATURE_MSI = (1 << 1), RTL_FEATURE_GMII = (1 << 2), }; static void rtl_hw_start_8169(struct net_device *); static void rtl_hw_start_8168(struct net_device *); static void rtl_hw_start_8101(struct net_device *); struct rtl8169_private { struct pci_device *pci_dev; struct net_device *netdev; uint8_t *hw_addr; void *mmio_addr; uint32_t irqno; int chipset; int mac_version; int cfg_index; u16 intr_event; struct io_buffer *tx_iobuf[NUM_TX_DESC]; struct io_buffer *rx_iobuf[NUM_RX_DESC]; struct TxDesc *tx_base; struct RxDesc *rx_base; uint32_t tx_curr; uint32_t rx_curr; uint32_t tx_tail; uint32_t tx_fill_ctr; u16 cp_cmd; int phy_auto_nego_reg; int phy_1000_ctrl_reg; int ( *set_speed ) (struct net_device *, u8 autoneg, u16 speed, u8 duplex ); void ( *phy_reset_enable ) ( void *ioaddr ); void ( *hw_start ) ( struct net_device * ); unsigned int ( *phy_reset_pending ) ( void *ioaddr ); unsigned int ( *link_ok ) ( void *ioaddr ); int pcie_cap; unsigned features; }; static const unsigned int rtl8169_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); #endif /* _R8169_H_ */ /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/bnx2.c0000664000000000000000000020520512524662415020230 0ustar /* bnx2.c: Broadcom NX2 network driver. * * Copyright (c) 2004, 2005, 2006 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * * Written by: Michael Chan (mchan@broadcom.com) * * Etherboot port by Ryan Jackson (rjackson@lnxi.com), based on driver * version 1.4.40 from linux 2.6.17 */ FILE_LICENCE ( GPL_ANY ); #include "etherboot.h" #include "nic.h" #include #include #include #include "string.h" #include #include "bnx2.h" #include "bnx2_fw.h" #if 0 /* Dummy defines for error handling */ #define EBUSY 1 #define ENODEV 2 #define EINVAL 3 #define ENOMEM 4 #define EIO 5 #endif /* The bnx2 seems to be picky about the alignment of the receive buffers * and possibly the status block. */ static struct bss { struct tx_bd tx_desc_ring[TX_DESC_CNT]; struct rx_bd rx_desc_ring[RX_DESC_CNT]; unsigned char rx_buf[RX_BUF_CNT][RX_BUF_SIZE]; struct status_block status_blk; struct statistics_block stats_blk; } bnx2_bss; static struct bnx2 bnx2; static struct flash_spec flash_table[] = { /* Slow EEPROM */ {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400, 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, "EEPROM - slow"}, /* Expansion entry 0001 */ {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406, 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, SAIFUN_FLASH_BYTE_ADDR_MASK, 0, "Entry 0001"}, /* Saifun SA25F010 (non-buffered flash) */ /* strap, cfg1, & write1 need updates */ {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406, 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2, "Non-buffered flash (128kB)"}, /* Saifun SA25F020 (non-buffered flash) */ /* strap, cfg1, & write1 need updates */ {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406, 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4, "Non-buffered flash (256kB)"}, /* Expansion entry 0100 */ {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406, 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, SAIFUN_FLASH_BYTE_ADDR_MASK, 0, "Entry 0100"}, /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */ {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406, 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2, "Entry 0101: ST M45PE10 (128kB non-bufferred)"}, /* Entry 0110: ST M45PE20 (non-buffered flash)*/ {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406, 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4, "Entry 0110: ST M45PE20 (256kB non-bufferred)"}, /* Saifun SA25F005 (non-buffered flash) */ /* strap, cfg1, & write1 need updates */ {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406, 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE, "Non-buffered flash (64kB)"}, /* Fast EEPROM */ {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400, 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, "EEPROM - fast"}, /* Expansion entry 1001 */ {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406, 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, SAIFUN_FLASH_BYTE_ADDR_MASK, 0, "Entry 1001"}, /* Expansion entry 1010 */ {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406, 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, SAIFUN_FLASH_BYTE_ADDR_MASK, 0, "Entry 1010"}, /* ATMEL AT45DB011B (buffered flash) */ {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400, 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE, "Buffered flash (128kB)"}, /* Expansion entry 1100 */ {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406, 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, SAIFUN_FLASH_BYTE_ADDR_MASK, 0, "Entry 1100"}, /* Expansion entry 1101 */ {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406, 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, SAIFUN_FLASH_BYTE_ADDR_MASK, 0, "Entry 1101"}, /* Ateml Expansion entry 1110 */ {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400, 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, BUFFERED_FLASH_BYTE_ADDR_MASK, 0, "Entry 1110 (Atmel)"}, /* ATMEL AT45DB021B (buffered flash) */ {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400, 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2, "Buffered flash (256kB)"}, }; static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset) { REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); return (REG_RD(bp, BNX2_PCICFG_REG_WINDOW)); } static void bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val) { REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val); } static void bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) { offset += cid_addr; REG_WR(bp, BNX2_CTX_DATA_ADR, offset); REG_WR(bp, BNX2_CTX_DATA, val); } static int bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val) { u32 val1; int i, ret; if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL; REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); REG_RD(bp, BNX2_EMAC_MDIO_MODE); udelay(40); } val1 = (bp->phy_addr << 21) | (reg << 16) | BNX2_EMAC_MDIO_COMM_COMMAND_READ | BNX2_EMAC_MDIO_COMM_DISEXT | BNX2_EMAC_MDIO_COMM_START_BUSY; REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1); for (i = 0; i < 50; i++) { udelay(10); val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM); if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) { udelay(5); val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM); val1 &= BNX2_EMAC_MDIO_COMM_DATA; break; } } if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY) { *val = 0x0; ret = -EBUSY; } else { *val = val1; ret = 0; } if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL; REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); REG_RD(bp, BNX2_EMAC_MDIO_MODE); udelay(40); } return ret; } static int bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val) { u32 val1; int i, ret; if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL; REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); REG_RD(bp, BNX2_EMAC_MDIO_MODE); udelay(40); } val1 = (bp->phy_addr << 21) | (reg << 16) | val | BNX2_EMAC_MDIO_COMM_COMMAND_WRITE | BNX2_EMAC_MDIO_COMM_START_BUSY | BNX2_EMAC_MDIO_COMM_DISEXT; REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1); for (i = 0; i < 50; i++) { udelay(10); val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM); if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; } } if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY) ret = -EBUSY; else ret = 0; if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL; REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); REG_RD(bp, BNX2_EMAC_MDIO_MODE); udelay(40); } return ret; } static void bnx2_disable_int(struct bnx2 *bp) { REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT); REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD); } static int bnx2_alloc_mem(struct bnx2 *bp) { bp->tx_desc_ring = bnx2_bss.tx_desc_ring; bp->tx_desc_mapping = virt_to_bus(bp->tx_desc_ring); bp->rx_desc_ring = bnx2_bss.rx_desc_ring; memset(bp->rx_desc_ring, 0, sizeof(struct rx_bd) * RX_DESC_CNT); bp->rx_desc_mapping = virt_to_bus(bp->rx_desc_ring); memset(&bnx2_bss.status_blk, 0, sizeof(struct status_block)); bp->status_blk = &bnx2_bss.status_blk; bp->status_blk_mapping = virt_to_bus(&bnx2_bss.status_blk); bp->stats_blk = &bnx2_bss.stats_blk; memset(&bnx2_bss.stats_blk, 0, sizeof(struct statistics_block)); bp->stats_blk_mapping = virt_to_bus(&bnx2_bss.stats_blk); return 0; } static void bnx2_report_fw_link(struct bnx2 *bp) { u32 fw_link_status = 0; if (bp->link_up) { u32 bmsr; switch (bp->line_speed) { case SPEED_10: if (bp->duplex == DUPLEX_HALF) fw_link_status = BNX2_LINK_STATUS_10HALF; else fw_link_status = BNX2_LINK_STATUS_10FULL; break; case SPEED_100: if (bp->duplex == DUPLEX_HALF) fw_link_status = BNX2_LINK_STATUS_100HALF; else fw_link_status = BNX2_LINK_STATUS_100FULL; break; case SPEED_1000: if (bp->duplex == DUPLEX_HALF) fw_link_status = BNX2_LINK_STATUS_1000HALF; else fw_link_status = BNX2_LINK_STATUS_1000FULL; break; case SPEED_2500: if (bp->duplex == DUPLEX_HALF) fw_link_status = BNX2_LINK_STATUS_2500HALF; else fw_link_status = BNX2_LINK_STATUS_2500FULL; break; } fw_link_status |= BNX2_LINK_STATUS_LINK_UP; if (bp->autoneg) { fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED; bnx2_read_phy(bp, MII_BMSR, &bmsr); bnx2_read_phy(bp, MII_BMSR, &bmsr); if (!(bmsr & BMSR_ANEGCOMPLETE) || bp->phy_flags & PHY_PARALLEL_DETECT_FLAG) fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET; else fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE; } } else fw_link_status = BNX2_LINK_STATUS_LINK_DOWN; REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status); } static void bnx2_report_link(struct bnx2 *bp) { if (bp->link_up) { printf("NIC Link is Up, "); printf("%d Mbps ", bp->line_speed); if (bp->duplex == DUPLEX_FULL) printf("full duplex"); else printf("half duplex"); if (bp->flow_ctrl) { if (bp->flow_ctrl & FLOW_CTRL_RX) { printf(", receive "); if (bp->flow_ctrl & FLOW_CTRL_TX) printf("& transmit "); } else { printf(", transmit "); } printf("flow control ON"); } printf("\n"); } else { printf("NIC Link is Down\n"); } bnx2_report_fw_link(bp); } static void bnx2_resolve_flow_ctrl(struct bnx2 *bp) { u32 local_adv, remote_adv; bp->flow_ctrl = 0; if ((bp->autoneg & (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) != (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) { if (bp->duplex == DUPLEX_FULL) { bp->flow_ctrl = bp->req_flow_ctrl; } return; } if (bp->duplex != DUPLEX_FULL) { return; } if ((bp->phy_flags & PHY_SERDES_FLAG) && (CHIP_NUM(bp) == CHIP_NUM_5708)) { u32 val; bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val); if (val & BCM5708S_1000X_STAT1_TX_PAUSE) bp->flow_ctrl |= FLOW_CTRL_TX; if (val & BCM5708S_1000X_STAT1_RX_PAUSE) bp->flow_ctrl |= FLOW_CTRL_RX; return; } bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); bnx2_read_phy(bp, MII_LPA, &remote_adv); if (bp->phy_flags & PHY_SERDES_FLAG) { u32 new_local_adv = 0; u32 new_remote_adv = 0; if (local_adv & ADVERTISE_1000XPAUSE) new_local_adv |= ADVERTISE_PAUSE_CAP; if (local_adv & ADVERTISE_1000XPSE_ASYM) new_local_adv |= ADVERTISE_PAUSE_ASYM; if (remote_adv & ADVERTISE_1000XPAUSE) new_remote_adv |= ADVERTISE_PAUSE_CAP; if (remote_adv & ADVERTISE_1000XPSE_ASYM) new_remote_adv |= ADVERTISE_PAUSE_ASYM; local_adv = new_local_adv; remote_adv = new_remote_adv; } /* See Table 28B-3 of 802.3ab-1999 spec. */ if (local_adv & ADVERTISE_PAUSE_CAP) { if(local_adv & ADVERTISE_PAUSE_ASYM) { if (remote_adv & ADVERTISE_PAUSE_CAP) { bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX; } else if (remote_adv & ADVERTISE_PAUSE_ASYM) { bp->flow_ctrl = FLOW_CTRL_RX; } } else { if (remote_adv & ADVERTISE_PAUSE_CAP) { bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX; } } } else if (local_adv & ADVERTISE_PAUSE_ASYM) { if ((remote_adv & ADVERTISE_PAUSE_CAP) && (remote_adv & ADVERTISE_PAUSE_ASYM)) { bp->flow_ctrl = FLOW_CTRL_TX; } } } static int bnx2_5708s_linkup(struct bnx2 *bp) { u32 val; bp->link_up = 1; bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val); switch (val & BCM5708S_1000X_STAT1_SPEED_MASK) { case BCM5708S_1000X_STAT1_SPEED_10: bp->line_speed = SPEED_10; break; case BCM5708S_1000X_STAT1_SPEED_100: bp->line_speed = SPEED_100; break; case BCM5708S_1000X_STAT1_SPEED_1G: bp->line_speed = SPEED_1000; break; case BCM5708S_1000X_STAT1_SPEED_2G5: bp->line_speed = SPEED_2500; break; } if (val & BCM5708S_1000X_STAT1_FD) bp->duplex = DUPLEX_FULL; else bp->duplex = DUPLEX_HALF; return 0; } static int bnx2_5706s_linkup(struct bnx2 *bp) { u32 bmcr, local_adv, remote_adv, common; bp->link_up = 1; bp->line_speed = SPEED_1000; bnx2_read_phy(bp, MII_BMCR, &bmcr); if (bmcr & BMCR_FULLDPLX) { bp->duplex = DUPLEX_FULL; } else { bp->duplex = DUPLEX_HALF; } if (!(bmcr & BMCR_ANENABLE)) { return 0; } bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); bnx2_read_phy(bp, MII_LPA, &remote_adv); common = local_adv & remote_adv; if (common & (ADVERTISE_1000XHALF | ADVERTISE_1000XFULL)) { if (common & ADVERTISE_1000XFULL) { bp->duplex = DUPLEX_FULL; } else { bp->duplex = DUPLEX_HALF; } } return 0; } static int bnx2_copper_linkup(struct bnx2 *bp) { u32 bmcr; bnx2_read_phy(bp, MII_BMCR, &bmcr); if (bmcr & BMCR_ANENABLE) { u32 local_adv, remote_adv, common; bnx2_read_phy(bp, MII_CTRL1000, &local_adv); bnx2_read_phy(bp, MII_STAT1000, &remote_adv); common = local_adv & (remote_adv >> 2); if (common & ADVERTISE_1000FULL) { bp->line_speed = SPEED_1000; bp->duplex = DUPLEX_FULL; } else if (common & ADVERTISE_1000HALF) { bp->line_speed = SPEED_1000; bp->duplex = DUPLEX_HALF; } else { bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); bnx2_read_phy(bp, MII_LPA, &remote_adv); common = local_adv & remote_adv; if (common & ADVERTISE_100FULL) { bp->line_speed = SPEED_100; bp->duplex = DUPLEX_FULL; } else if (common & ADVERTISE_100HALF) { bp->line_speed = SPEED_100; bp->duplex = DUPLEX_HALF; } else if (common & ADVERTISE_10FULL) { bp->line_speed = SPEED_10; bp->duplex = DUPLEX_FULL; } else if (common & ADVERTISE_10HALF) { bp->line_speed = SPEED_10; bp->duplex = DUPLEX_HALF; } else { bp->line_speed = 0; bp->link_up = 0; } } } else { if (bmcr & BMCR_SPEED100) { bp->line_speed = SPEED_100; } else { bp->line_speed = SPEED_10; } if (bmcr & BMCR_FULLDPLX) { bp->duplex = DUPLEX_FULL; } else { bp->duplex = DUPLEX_HALF; } } return 0; } static int bnx2_set_mac_link(struct bnx2 *bp) { u32 val; REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x2620); if (bp->link_up && (bp->line_speed == SPEED_1000) && (bp->duplex == DUPLEX_HALF)) { REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x26ff); } /* Configure the EMAC mode register. */ val = REG_RD(bp, BNX2_EMAC_MODE); val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | BNX2_EMAC_MODE_25G); if (bp->link_up) { switch (bp->line_speed) { case SPEED_10: if (CHIP_NUM(bp) == CHIP_NUM_5708) { val |= BNX2_EMAC_MODE_PORT_MII_10; break; } /* fall through */ case SPEED_100: val |= BNX2_EMAC_MODE_PORT_MII; break; case SPEED_2500: val |= BNX2_EMAC_MODE_25G; /* fall through */ case SPEED_1000: val |= BNX2_EMAC_MODE_PORT_GMII; break; } } else { val |= BNX2_EMAC_MODE_PORT_GMII; } /* Set the MAC to operate in the appropriate duplex mode. */ if (bp->duplex == DUPLEX_HALF) val |= BNX2_EMAC_MODE_HALF_DUPLEX; REG_WR(bp, BNX2_EMAC_MODE, val); /* Enable/disable rx PAUSE. */ bp->rx_mode &= ~BNX2_EMAC_RX_MODE_FLOW_EN; if (bp->flow_ctrl & FLOW_CTRL_RX) bp->rx_mode |= BNX2_EMAC_RX_MODE_FLOW_EN; REG_WR(bp, BNX2_EMAC_RX_MODE, bp->rx_mode); /* Enable/disable tx PAUSE. */ val = REG_RD(bp, BNX2_EMAC_TX_MODE); val &= ~BNX2_EMAC_TX_MODE_FLOW_EN; if (bp->flow_ctrl & FLOW_CTRL_TX) val |= BNX2_EMAC_TX_MODE_FLOW_EN; REG_WR(bp, BNX2_EMAC_TX_MODE, val); /* Acknowledge the interrupt. */ REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE); return 0; } static int bnx2_set_link(struct bnx2 *bp) { u32 bmsr; u8 link_up; if (bp->loopback == MAC_LOOPBACK) { bp->link_up = 1; return 0; } link_up = bp->link_up; bnx2_read_phy(bp, MII_BMSR, &bmsr); bnx2_read_phy(bp, MII_BMSR, &bmsr); if ((bp->phy_flags & PHY_SERDES_FLAG) && (CHIP_NUM(bp) == CHIP_NUM_5706)) { u32 val; val = REG_RD(bp, BNX2_EMAC_STATUS); if (val & BNX2_EMAC_STATUS_LINK) bmsr |= BMSR_LSTATUS; else bmsr &= ~BMSR_LSTATUS; } if (bmsr & BMSR_LSTATUS) { bp->link_up = 1; if (bp->phy_flags & PHY_SERDES_FLAG) { if (CHIP_NUM(bp) == CHIP_NUM_5706) bnx2_5706s_linkup(bp); else if (CHIP_NUM(bp) == CHIP_NUM_5708) bnx2_5708s_linkup(bp); } else { bnx2_copper_linkup(bp); } bnx2_resolve_flow_ctrl(bp); } else { if ((bp->phy_flags & PHY_SERDES_FLAG) && (bp->autoneg & AUTONEG_SPEED)) { u32 bmcr; bnx2_read_phy(bp, MII_BMCR, &bmcr); if (!(bmcr & BMCR_ANENABLE)) { bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANENABLE); } } bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; bp->link_up = 0; } if (bp->link_up != link_up) { bnx2_report_link(bp); } bnx2_set_mac_link(bp); return 0; } static int bnx2_reset_phy(struct bnx2 *bp) { int i; u32 reg; bnx2_write_phy(bp, MII_BMCR, BMCR_RESET); #define PHY_RESET_MAX_WAIT 100 for (i = 0; i < PHY_RESET_MAX_WAIT; i++) { udelay(10); bnx2_read_phy(bp, MII_BMCR, ®); if (!(reg & BMCR_RESET)) { udelay(20); break; } } if (i == PHY_RESET_MAX_WAIT) { return -EBUSY; } return 0; } static u32 bnx2_phy_get_pause_adv(struct bnx2 *bp) { u32 adv = 0; if ((bp->req_flow_ctrl & (FLOW_CTRL_RX | FLOW_CTRL_TX)) == (FLOW_CTRL_RX | FLOW_CTRL_TX)) { if (bp->phy_flags & PHY_SERDES_FLAG) { adv = ADVERTISE_1000XPAUSE; } else { adv = ADVERTISE_PAUSE_CAP; } } else if (bp->req_flow_ctrl & FLOW_CTRL_TX) { if (bp->phy_flags & PHY_SERDES_FLAG) { adv = ADVERTISE_1000XPSE_ASYM; } else { adv = ADVERTISE_PAUSE_ASYM; } } else if (bp->req_flow_ctrl & FLOW_CTRL_RX) { if (bp->phy_flags & PHY_SERDES_FLAG) { adv = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM; } else { adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; } } return adv; } static int bnx2_setup_serdes_phy(struct bnx2 *bp) { u32 adv, bmcr, up1; u32 new_adv = 0; if (!(bp->autoneg & AUTONEG_SPEED)) { u32 new_bmcr; int force_link_down = 0; if (CHIP_NUM(bp) == CHIP_NUM_5708) { bnx2_read_phy(bp, BCM5708S_UP1, &up1); if (up1 & BCM5708S_UP1_2G5) { up1 &= ~BCM5708S_UP1_2G5; bnx2_write_phy(bp, BCM5708S_UP1, up1); force_link_down = 1; } } bnx2_read_phy(bp, MII_ADVERTISE, &adv); adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF); bnx2_read_phy(bp, MII_BMCR, &bmcr); new_bmcr = bmcr & ~BMCR_ANENABLE; new_bmcr |= BMCR_SPEED1000; if (bp->req_duplex == DUPLEX_FULL) { adv |= ADVERTISE_1000XFULL; new_bmcr |= BMCR_FULLDPLX; } else { adv |= ADVERTISE_1000XHALF; new_bmcr &= ~BMCR_FULLDPLX; } if ((new_bmcr != bmcr) || (force_link_down)) { /* Force a link down visible on the other side */ if (bp->link_up) { bnx2_write_phy(bp, MII_ADVERTISE, adv & ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF)); bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); bp->link_up = 0; bnx2_write_phy(bp, MII_BMCR, new_bmcr); } bnx2_write_phy(bp, MII_ADVERTISE, adv); bnx2_write_phy(bp, MII_BMCR, new_bmcr); } return 0; } if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) { bnx2_read_phy(bp, BCM5708S_UP1, &up1); up1 |= BCM5708S_UP1_2G5; bnx2_write_phy(bp, BCM5708S_UP1, up1); } if (bp->advertising & ADVERTISED_1000baseT_Full) new_adv |= ADVERTISE_1000XFULL; new_adv |= bnx2_phy_get_pause_adv(bp); bnx2_read_phy(bp, MII_ADVERTISE, &adv); bnx2_read_phy(bp, MII_BMCR, &bmcr); bp->serdes_an_pending = 0; if ((adv != new_adv) || ((bmcr & BMCR_ANENABLE) == 0)) { /* Force a link down visible on the other side */ if (bp->link_up) { int i; bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); for (i = 0; i < 110; i++) { udelay(100); } } bnx2_write_phy(bp, MII_ADVERTISE, new_adv); bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); #if 0 if (CHIP_NUM(bp) == CHIP_NUM_5706) { /* Speed up link-up time when the link partner * does not autonegotiate which is very common * in blade servers. Some blade servers use * IPMI for kerboard input and it's important * to minimize link disruptions. Autoneg. involves * exchanging base pages plus 3 next pages and * normally completes in about 120 msec. */ bp->current_interval = SERDES_AN_TIMEOUT; bp->serdes_an_pending = 1; mod_timer(&bp->timer, jiffies + bp->current_interval); } #endif } return 0; } #define ETHTOOL_ALL_FIBRE_SPEED \ (ADVERTISED_1000baseT_Full) #define ETHTOOL_ALL_COPPER_SPEED \ (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \ ADVERTISED_1000baseT_Full) #define PHY_ALL_10_100_SPEED (ADVERTISE_10HALF | ADVERTISE_10FULL | \ ADVERTISE_100HALF | ADVERTISE_100FULL | ADVERTISE_CSMA) #define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL) static int bnx2_setup_copper_phy(struct bnx2 *bp) { u32 bmcr; u32 new_bmcr; bnx2_read_phy(bp, MII_BMCR, &bmcr); if (bp->autoneg & AUTONEG_SPEED) { u32 adv_reg, adv1000_reg; u32 new_adv_reg = 0; u32 new_adv1000_reg = 0; bnx2_read_phy(bp, MII_ADVERTISE, &adv_reg); adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg); adv1000_reg &= PHY_ALL_1000_SPEED; if (bp->advertising & ADVERTISED_10baseT_Half) new_adv_reg |= ADVERTISE_10HALF; if (bp->advertising & ADVERTISED_10baseT_Full) new_adv_reg |= ADVERTISE_10FULL; if (bp->advertising & ADVERTISED_100baseT_Half) new_adv_reg |= ADVERTISE_100HALF; if (bp->advertising & ADVERTISED_100baseT_Full) new_adv_reg |= ADVERTISE_100FULL; if (bp->advertising & ADVERTISED_1000baseT_Full) new_adv1000_reg |= ADVERTISE_1000FULL; new_adv_reg |= ADVERTISE_CSMA; new_adv_reg |= bnx2_phy_get_pause_adv(bp); if ((adv1000_reg != new_adv1000_reg) || (adv_reg != new_adv_reg) || ((bmcr & BMCR_ANENABLE) == 0)) { bnx2_write_phy(bp, MII_ADVERTISE, new_adv_reg); bnx2_write_phy(bp, MII_CTRL1000, new_adv1000_reg); bnx2_write_phy(bp, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE); } else if (bp->link_up) { /* Flow ctrl may have changed from auto to forced */ /* or vice-versa. */ bnx2_resolve_flow_ctrl(bp); bnx2_set_mac_link(bp); } return 0; } new_bmcr = 0; if (bp->req_line_speed == SPEED_100) { new_bmcr |= BMCR_SPEED100; } if (bp->req_duplex == DUPLEX_FULL) { new_bmcr |= BMCR_FULLDPLX; } if (new_bmcr != bmcr) { u32 bmsr; int i = 0; bnx2_read_phy(bp, MII_BMSR, &bmsr); bnx2_read_phy(bp, MII_BMSR, &bmsr); if (bmsr & BMSR_LSTATUS) { /* Force link down */ bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); do { udelay(100); bnx2_read_phy(bp, MII_BMSR, &bmsr); bnx2_read_phy(bp, MII_BMSR, &bmsr); i++; } while ((bmsr & BMSR_LSTATUS) && (i < 620)); } bnx2_write_phy(bp, MII_BMCR, new_bmcr); /* Normally, the new speed is setup after the link has * gone down and up again. In some cases, link will not go * down so we need to set up the new speed here. */ if (bmsr & BMSR_LSTATUS) { bp->line_speed = bp->req_line_speed; bp->duplex = bp->req_duplex; bnx2_resolve_flow_ctrl(bp); bnx2_set_mac_link(bp); } } return 0; } static int bnx2_setup_phy(struct bnx2 *bp) { if (bp->loopback == MAC_LOOPBACK) return 0; if (bp->phy_flags & PHY_SERDES_FLAG) { return (bnx2_setup_serdes_phy(bp)); } else { return (bnx2_setup_copper_phy(bp)); } } static int bnx2_init_5708s_phy(struct bnx2 *bp) { u32 val; bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG3); bnx2_write_phy(bp, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE); bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG); bnx2_read_phy(bp, BCM5708S_1000X_CTL1, &val); val |= BCM5708S_1000X_CTL1_FIBER_MODE | BCM5708S_1000X_CTL1_AUTODET_EN; bnx2_write_phy(bp, BCM5708S_1000X_CTL1, val); bnx2_read_phy(bp, BCM5708S_1000X_CTL2, &val); val |= BCM5708S_1000X_CTL2_PLLEL_DET_EN; bnx2_write_phy(bp, BCM5708S_1000X_CTL2, val); if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) { bnx2_read_phy(bp, BCM5708S_UP1, &val); val |= BCM5708S_UP1_2G5; bnx2_write_phy(bp, BCM5708S_UP1, val); } if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || (CHIP_ID(bp) == CHIP_ID_5708_B0) || (CHIP_ID(bp) == CHIP_ID_5708_B1)) { /* increase tx signal amplitude */ bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_TX_MISC); bnx2_read_phy(bp, BCM5708S_TX_ACTL1, &val); val &= ~BCM5708S_TX_ACTL1_DRIVER_VCM; bnx2_write_phy(bp, BCM5708S_TX_ACTL1, val); bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG); } val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) & BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK; if (val) { u32 is_backplane; is_backplane = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG); if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) { bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_TX_MISC); bnx2_write_phy(bp, BCM5708S_TX_ACTL3, val); bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG); } } return 0; } static int bnx2_init_5706s_phy(struct bnx2 *bp) { u32 val; bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; if (CHIP_NUM(bp) == CHIP_NUM_5706) { REG_WR(bp, BNX2_MISC_UNUSED0, 0x300); } bnx2_write_phy(bp, 0x18, 0x7); bnx2_read_phy(bp, 0x18, &val); bnx2_write_phy(bp, 0x18, val & ~0x4007); bnx2_write_phy(bp, 0x1c, 0x6c00); bnx2_read_phy(bp, 0x1c, &val); bnx2_write_phy(bp, 0x1c, (val & 0x3fd) | 0xec00); return 0; } static int bnx2_init_copper_phy(struct bnx2 *bp) { u32 val; bp->phy_flags |= PHY_CRC_FIX_FLAG; if (bp->phy_flags & PHY_CRC_FIX_FLAG) { bnx2_write_phy(bp, 0x18, 0x0c00); bnx2_write_phy(bp, 0x17, 0x000a); bnx2_write_phy(bp, 0x15, 0x310b); bnx2_write_phy(bp, 0x17, 0x201f); bnx2_write_phy(bp, 0x15, 0x9506); bnx2_write_phy(bp, 0x17, 0x401f); bnx2_write_phy(bp, 0x15, 0x14e2); bnx2_write_phy(bp, 0x18, 0x0400); } bnx2_write_phy(bp, 0x18, 0x7); bnx2_read_phy(bp, 0x18, &val); bnx2_write_phy(bp, 0x18, val & ~0x4007); bnx2_read_phy(bp, 0x10, &val); bnx2_write_phy(bp, 0x10, val & ~0x1); /* ethernet@wirespeed */ bnx2_write_phy(bp, 0x18, 0x7007); bnx2_read_phy(bp, 0x18, &val); bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4)); return 0; } static int bnx2_init_phy(struct bnx2 *bp) { u32 val; int rc = 0; bp->phy_flags &= ~PHY_INT_MODE_MASK_FLAG; bp->phy_flags |= PHY_INT_MODE_LINK_READY_FLAG; REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK); bnx2_reset_phy(bp); bnx2_read_phy(bp, MII_PHYSID1, &val); bp->phy_id = val << 16; bnx2_read_phy(bp, MII_PHYSID2, &val); bp->phy_id |= val & 0xffff; if (bp->phy_flags & PHY_SERDES_FLAG) { if (CHIP_NUM(bp) == CHIP_NUM_5706) rc = bnx2_init_5706s_phy(bp); else if (CHIP_NUM(bp) == CHIP_NUM_5708) rc = bnx2_init_5708s_phy(bp); } else { rc = bnx2_init_copper_phy(bp); } bnx2_setup_phy(bp); return rc; } static int bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent) { int i; u32 val; bp->fw_wr_seq++; msg_data |= bp->fw_wr_seq; REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data); /* wait for an acknowledgement. */ for (i = 0; i < (FW_ACK_TIME_OUT_MS / 50); i++) { mdelay(50); val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB); if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ)) break; } if ((msg_data & BNX2_DRV_MSG_DATA) == BNX2_DRV_MSG_DATA_WAIT0) return 0; /* If we timed out, inform the firmware that this is the case. */ if ((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) { if (!silent) printf("fw sync timeout, reset code = %x\n", (unsigned int) msg_data); msg_data &= ~BNX2_DRV_MSG_CODE; msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT; REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data); return -EBUSY; } if ((val & BNX2_FW_MSG_STATUS_MASK) != BNX2_FW_MSG_STATUS_OK) return -EIO; return 0; } static void bnx2_init_context(struct bnx2 *bp) { u32 vcid; vcid = 96; while (vcid) { u32 vcid_addr, pcid_addr, offset; vcid--; if (CHIP_ID(bp) == CHIP_ID_5706_A0) { u32 new_vcid; vcid_addr = GET_PCID_ADDR(vcid); if (vcid & 0x8) { new_vcid = 0x60 + (vcid & 0xf0) + (vcid & 0x7); } else { new_vcid = vcid; } pcid_addr = GET_PCID_ADDR(new_vcid); } else { vcid_addr = GET_CID_ADDR(vcid); pcid_addr = vcid_addr; } REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00); REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); /* Zero out the context. */ for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) { CTX_WR(bp, 0x00, offset, 0); } REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr); REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); } } static int bnx2_alloc_bad_rbuf(struct bnx2 *bp) { u16 good_mbuf[512]; u32 good_mbuf_cnt; u32 val; REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE); good_mbuf_cnt = 0; /* Allocate a bunch of mbufs and save the good ones in an array. */ val = REG_RD_IND(bp, BNX2_RBUF_STATUS1); while (val & BNX2_RBUF_STATUS1_FREE_COUNT) { REG_WR_IND(bp, BNX2_RBUF_COMMAND, BNX2_RBUF_COMMAND_ALLOC_REQ); val = REG_RD_IND(bp, BNX2_RBUF_FW_BUF_ALLOC); val &= BNX2_RBUF_FW_BUF_ALLOC_VALUE; /* The addresses with Bit 9 set are bad memory blocks. */ if (!(val & (1 << 9))) { good_mbuf[good_mbuf_cnt] = (u16) val; good_mbuf_cnt++; } val = REG_RD_IND(bp, BNX2_RBUF_STATUS1); } /* Free the good ones back to the mbuf pool thus discarding * all the bad ones. */ while (good_mbuf_cnt) { good_mbuf_cnt--; val = good_mbuf[good_mbuf_cnt]; val = (val << 9) | val | 1; REG_WR_IND(bp, BNX2_RBUF_FW_BUF_FREE, val); } return 0; } static void bnx2_set_mac_addr(struct bnx2 *bp) { u32 val; u8 *mac_addr = bp->nic->node_addr; val = (mac_addr[0] << 8) | mac_addr[1]; REG_WR(bp, BNX2_EMAC_MAC_MATCH0, val); val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | (mac_addr[4] << 8) | mac_addr[5]; REG_WR(bp, BNX2_EMAC_MAC_MATCH1, val); } static void bnx2_set_rx_mode(struct nic *nic __unused) { struct bnx2 *bp = &bnx2; u32 rx_mode, sort_mode; int i; rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS | BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN; if (!(bp->flags & ASF_ENABLE_FLAG)) { rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; } /* Accept all multicasts */ for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) { REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4), 0xffffffff); } sort_mode |= BNX2_RPM_SORT_USER0_MC_EN; if (rx_mode != bp->rx_mode) { bp->rx_mode = rx_mode; REG_WR(bp, BNX2_EMAC_RX_MODE, rx_mode); } REG_WR(bp, BNX2_RPM_SORT_USER0, 0x0); REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode); REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA); } static void load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len, u32 rv2p_proc) { unsigned int i; u32 val; for (i = 0; i < rv2p_code_len; i += 8) { REG_WR(bp, BNX2_RV2P_INSTR_HIGH, *rv2p_code); rv2p_code++; REG_WR(bp, BNX2_RV2P_INSTR_LOW, *rv2p_code); rv2p_code++; if (rv2p_proc == RV2P_PROC1) { val = (i / 8) | BNX2_RV2P_PROC1_ADDR_CMD_RDWR; REG_WR(bp, BNX2_RV2P_PROC1_ADDR_CMD, val); } else { val = (i / 8) | BNX2_RV2P_PROC2_ADDR_CMD_RDWR; REG_WR(bp, BNX2_RV2P_PROC2_ADDR_CMD, val); } } /* Reset the processor, un-stall is done later. */ if (rv2p_proc == RV2P_PROC1) { REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC1_RESET); } else { REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET); } } static void load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw) { u32 offset; u32 val; /* Halt the CPU. */ val = REG_RD_IND(bp, cpu_reg->mode); val |= cpu_reg->mode_value_halt; REG_WR_IND(bp, cpu_reg->mode, val); REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear); /* Load the Text area. */ offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base); if (fw->text) { unsigned int j; for (j = 0; j < (fw->text_len / 4); j++, offset += 4) { REG_WR_IND(bp, offset, fw->text[j]); } } /* Load the Data area. */ offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base); if (fw->data) { unsigned int j; for (j = 0; j < (fw->data_len / 4); j++, offset += 4) { REG_WR_IND(bp, offset, fw->data[j]); } } /* Load the SBSS area. */ offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base); if (fw->sbss) { unsigned int j; for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) { REG_WR_IND(bp, offset, fw->sbss[j]); } } /* Load the BSS area. */ offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base); if (fw->bss) { unsigned int j; for (j = 0; j < (fw->bss_len/4); j++, offset += 4) { REG_WR_IND(bp, offset, fw->bss[j]); } } /* Load the Read-Only area. */ offset = cpu_reg->spad_base + (fw->rodata_addr - cpu_reg->mips_view_base); if (fw->rodata) { unsigned int j; for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) { REG_WR_IND(bp, offset, fw->rodata[j]); } } /* Clear the pre-fetch instruction. */ REG_WR_IND(bp, cpu_reg->inst, 0); REG_WR_IND(bp, cpu_reg->pc, fw->start_addr); /* Start the CPU. */ val = REG_RD_IND(bp, cpu_reg->mode); val &= ~cpu_reg->mode_value_halt; REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear); REG_WR_IND(bp, cpu_reg->mode, val); } static void bnx2_init_cpus(struct bnx2 *bp) { struct cpu_reg cpu_reg; struct fw_info fw; /* Unfortunately, it looks like we need to load the firmware * before the card will work properly. That means this driver * will be huge by Etherboot standards (approx. 50K compressed). */ /* Initialize the RV2P processor. */ load_rv2p_fw(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), RV2P_PROC1); load_rv2p_fw(bp, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2), RV2P_PROC2); /* Initialize the RX Processor. */ cpu_reg.mode = BNX2_RXP_CPU_MODE; cpu_reg.mode_value_halt = BNX2_RXP_CPU_MODE_SOFT_HALT; cpu_reg.mode_value_sstep = BNX2_RXP_CPU_MODE_STEP_ENA; cpu_reg.state = BNX2_RXP_CPU_STATE; cpu_reg.state_value_clear = 0xffffff; cpu_reg.gpr0 = BNX2_RXP_CPU_REG_FILE; cpu_reg.evmask = BNX2_RXP_CPU_EVENT_MASK; cpu_reg.pc = BNX2_RXP_CPU_PROGRAM_COUNTER; cpu_reg.inst = BNX2_RXP_CPU_INSTRUCTION; cpu_reg.bp = BNX2_RXP_CPU_HW_BREAKPOINT; cpu_reg.spad_base = BNX2_RXP_SCRATCH; cpu_reg.mips_view_base = 0x8000000; fw.ver_major = bnx2_RXP_b06FwReleaseMajor; fw.ver_minor = bnx2_RXP_b06FwReleaseMinor; fw.ver_fix = bnx2_RXP_b06FwReleaseFix; fw.start_addr = bnx2_RXP_b06FwStartAddr; fw.text_addr = bnx2_RXP_b06FwTextAddr; fw.text_len = bnx2_RXP_b06FwTextLen; fw.text_index = 0; fw.text = bnx2_RXP_b06FwText; fw.data_addr = bnx2_RXP_b06FwDataAddr; fw.data_len = bnx2_RXP_b06FwDataLen; fw.data_index = 0; fw.data = bnx2_RXP_b06FwData; fw.sbss_addr = bnx2_RXP_b06FwSbssAddr; fw.sbss_len = bnx2_RXP_b06FwSbssLen; fw.sbss_index = 0; fw.sbss = bnx2_RXP_b06FwSbss; fw.bss_addr = bnx2_RXP_b06FwBssAddr; fw.bss_len = bnx2_RXP_b06FwBssLen; fw.bss_index = 0; fw.bss = bnx2_RXP_b06FwBss; fw.rodata_addr = bnx2_RXP_b06FwRodataAddr; fw.rodata_len = bnx2_RXP_b06FwRodataLen; fw.rodata_index = 0; fw.rodata = bnx2_RXP_b06FwRodata; load_cpu_fw(bp, &cpu_reg, &fw); /* Initialize the TX Processor. */ cpu_reg.mode = BNX2_TXP_CPU_MODE; cpu_reg.mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT; cpu_reg.mode_value_sstep = BNX2_TXP_CPU_MODE_STEP_ENA; cpu_reg.state = BNX2_TXP_CPU_STATE; cpu_reg.state_value_clear = 0xffffff; cpu_reg.gpr0 = BNX2_TXP_CPU_REG_FILE; cpu_reg.evmask = BNX2_TXP_CPU_EVENT_MASK; cpu_reg.pc = BNX2_TXP_CPU_PROGRAM_COUNTER; cpu_reg.inst = BNX2_TXP_CPU_INSTRUCTION; cpu_reg.bp = BNX2_TXP_CPU_HW_BREAKPOINT; cpu_reg.spad_base = BNX2_TXP_SCRATCH; cpu_reg.mips_view_base = 0x8000000; fw.ver_major = bnx2_TXP_b06FwReleaseMajor; fw.ver_minor = bnx2_TXP_b06FwReleaseMinor; fw.ver_fix = bnx2_TXP_b06FwReleaseFix; fw.start_addr = bnx2_TXP_b06FwStartAddr; fw.text_addr = bnx2_TXP_b06FwTextAddr; fw.text_len = bnx2_TXP_b06FwTextLen; fw.text_index = 0; fw.text = bnx2_TXP_b06FwText; fw.data_addr = bnx2_TXP_b06FwDataAddr; fw.data_len = bnx2_TXP_b06FwDataLen; fw.data_index = 0; fw.data = bnx2_TXP_b06FwData; fw.sbss_addr = bnx2_TXP_b06FwSbssAddr; fw.sbss_len = bnx2_TXP_b06FwSbssLen; fw.sbss_index = 0; fw.sbss = bnx2_TXP_b06FwSbss; fw.bss_addr = bnx2_TXP_b06FwBssAddr; fw.bss_len = bnx2_TXP_b06FwBssLen; fw.bss_index = 0; fw.bss = bnx2_TXP_b06FwBss; fw.rodata_addr = bnx2_TXP_b06FwRodataAddr; fw.rodata_len = bnx2_TXP_b06FwRodataLen; fw.rodata_index = 0; fw.rodata = bnx2_TXP_b06FwRodata; load_cpu_fw(bp, &cpu_reg, &fw); /* Initialize the TX Patch-up Processor. */ cpu_reg.mode = BNX2_TPAT_CPU_MODE; cpu_reg.mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT; cpu_reg.mode_value_sstep = BNX2_TPAT_CPU_MODE_STEP_ENA; cpu_reg.state = BNX2_TPAT_CPU_STATE; cpu_reg.state_value_clear = 0xffffff; cpu_reg.gpr0 = BNX2_TPAT_CPU_REG_FILE; cpu_reg.evmask = BNX2_TPAT_CPU_EVENT_MASK; cpu_reg.pc = BNX2_TPAT_CPU_PROGRAM_COUNTER; cpu_reg.inst = BNX2_TPAT_CPU_INSTRUCTION; cpu_reg.bp = BNX2_TPAT_CPU_HW_BREAKPOINT; cpu_reg.spad_base = BNX2_TPAT_SCRATCH; cpu_reg.mips_view_base = 0x8000000; fw.ver_major = bnx2_TPAT_b06FwReleaseMajor; fw.ver_minor = bnx2_TPAT_b06FwReleaseMinor; fw.ver_fix = bnx2_TPAT_b06FwReleaseFix; fw.start_addr = bnx2_TPAT_b06FwStartAddr; fw.text_addr = bnx2_TPAT_b06FwTextAddr; fw.text_len = bnx2_TPAT_b06FwTextLen; fw.text_index = 0; fw.text = bnx2_TPAT_b06FwText; fw.data_addr = bnx2_TPAT_b06FwDataAddr; fw.data_len = bnx2_TPAT_b06FwDataLen; fw.data_index = 0; fw.data = bnx2_TPAT_b06FwData; fw.sbss_addr = bnx2_TPAT_b06FwSbssAddr; fw.sbss_len = bnx2_TPAT_b06FwSbssLen; fw.sbss_index = 0; fw.sbss = bnx2_TPAT_b06FwSbss; fw.bss_addr = bnx2_TPAT_b06FwBssAddr; fw.bss_len = bnx2_TPAT_b06FwBssLen; fw.bss_index = 0; fw.bss = bnx2_TPAT_b06FwBss; fw.rodata_addr = bnx2_TPAT_b06FwRodataAddr; fw.rodata_len = bnx2_TPAT_b06FwRodataLen; fw.rodata_index = 0; fw.rodata = bnx2_TPAT_b06FwRodata; load_cpu_fw(bp, &cpu_reg, &fw); /* Initialize the Completion Processor. */ cpu_reg.mode = BNX2_COM_CPU_MODE; cpu_reg.mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT; cpu_reg.mode_value_sstep = BNX2_COM_CPU_MODE_STEP_ENA; cpu_reg.state = BNX2_COM_CPU_STATE; cpu_reg.state_value_clear = 0xffffff; cpu_reg.gpr0 = BNX2_COM_CPU_REG_FILE; cpu_reg.evmask = BNX2_COM_CPU_EVENT_MASK; cpu_reg.pc = BNX2_COM_CPU_PROGRAM_COUNTER; cpu_reg.inst = BNX2_COM_CPU_INSTRUCTION; cpu_reg.bp = BNX2_COM_CPU_HW_BREAKPOINT; cpu_reg.spad_base = BNX2_COM_SCRATCH; cpu_reg.mips_view_base = 0x8000000; fw.ver_major = bnx2_COM_b06FwReleaseMajor; fw.ver_minor = bnx2_COM_b06FwReleaseMinor; fw.ver_fix = bnx2_COM_b06FwReleaseFix; fw.start_addr = bnx2_COM_b06FwStartAddr; fw.text_addr = bnx2_COM_b06FwTextAddr; fw.text_len = bnx2_COM_b06FwTextLen; fw.text_index = 0; fw.text = bnx2_COM_b06FwText; fw.data_addr = bnx2_COM_b06FwDataAddr; fw.data_len = bnx2_COM_b06FwDataLen; fw.data_index = 0; fw.data = bnx2_COM_b06FwData; fw.sbss_addr = bnx2_COM_b06FwSbssAddr; fw.sbss_len = bnx2_COM_b06FwSbssLen; fw.sbss_index = 0; fw.sbss = bnx2_COM_b06FwSbss; fw.bss_addr = bnx2_COM_b06FwBssAddr; fw.bss_len = bnx2_COM_b06FwBssLen; fw.bss_index = 0; fw.bss = bnx2_COM_b06FwBss; fw.rodata_addr = bnx2_COM_b06FwRodataAddr; fw.rodata_len = bnx2_COM_b06FwRodataLen; fw.rodata_index = 0; fw.rodata = bnx2_COM_b06FwRodata; load_cpu_fw(bp, &cpu_reg, &fw); } static int bnx2_set_power_state_0(struct bnx2 *bp) { u16 pmcsr; u32 val; pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr); pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, (pmcsr & ~PCI_PM_CTRL_STATE_MASK) | PCI_PM_CTRL_PME_STATUS); if (pmcsr & PCI_PM_CTRL_STATE_MASK) /* delay required during transition out of D3hot */ mdelay(20); val = REG_RD(bp, BNX2_EMAC_MODE); val |= BNX2_EMAC_MODE_MPKT_RCVD | BNX2_EMAC_MODE_ACPI_RCVD; val &= ~BNX2_EMAC_MODE_MPKT; REG_WR(bp, BNX2_EMAC_MODE, val); val = REG_RD(bp, BNX2_RPM_CONFIG); val &= ~BNX2_RPM_CONFIG_ACPI_ENA; REG_WR(bp, BNX2_RPM_CONFIG, val); return 0; } static void bnx2_enable_nvram_access(struct bnx2 *bp) { u32 val; val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE); /* Enable both bits, even on read. */ REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, val | BNX2_NVM_ACCESS_ENABLE_EN | BNX2_NVM_ACCESS_ENABLE_WR_EN); } static void bnx2_disable_nvram_access(struct bnx2 *bp) { u32 val; val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE); /* Disable both bits, even after read. */ REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, val & ~(BNX2_NVM_ACCESS_ENABLE_EN | BNX2_NVM_ACCESS_ENABLE_WR_EN)); } static int bnx2_init_nvram(struct bnx2 *bp) { u32 val; int j, entry_count, rc; struct flash_spec *flash; /* Determine the selected interface. */ val = REG_RD(bp, BNX2_NVM_CFG1); entry_count = sizeof(flash_table) / sizeof(struct flash_spec); rc = 0; if (val & 0x40000000) { /* Flash interface has been reconfigured */ for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) { if ((val & FLASH_BACKUP_STRAP_MASK) == (flash->config1 & FLASH_BACKUP_STRAP_MASK)) { bp->flash_info = flash; break; } } } else { u32 mask; /* Not yet been reconfigured */ if (val & (1 << 23)) mask = FLASH_BACKUP_STRAP_MASK; else mask = FLASH_STRAP_MASK; for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) { if ((val & mask) == (flash->strapping & mask)) { bp->flash_info = flash; /* Enable access to flash interface */ bnx2_enable_nvram_access(bp); /* Reconfigure the flash interface */ REG_WR(bp, BNX2_NVM_CFG1, flash->config1); REG_WR(bp, BNX2_NVM_CFG2, flash->config2); REG_WR(bp, BNX2_NVM_CFG3, flash->config3); REG_WR(bp, BNX2_NVM_WRITE1, flash->write1); /* Disable access to flash interface */ bnx2_disable_nvram_access(bp); break; } } } /* if (val & 0x40000000) */ if (j == entry_count) { bp->flash_info = NULL; printf("Unknown flash/EEPROM type.\n"); return -ENODEV; } val = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG2); val &= BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK; if (val) { bp->flash_size = val; } else { bp->flash_size = bp->flash_info->total_size; } return rc; } static int bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) { u32 val; int i, rc = 0; /* Wait for the current PCI transaction to complete before * issuing a reset. */ REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); udelay(5); /* Wait for the firmware to tell us it is ok to issue a reset. */ bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1); /* Deposit a driver reset signature so the firmware knows that * this is a soft reset. */ REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE, BNX2_DRV_RESET_SIGNATURE_MAGIC); /* Do a dummy read to force the chip to complete all current transaction * before we issue a reset. */ val = REG_RD(bp, BNX2_MISC_ID); val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP; /* Chip reset. */ REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val); if ((CHIP_ID(bp) == CHIP_ID_5706_A0) || (CHIP_ID(bp) == CHIP_ID_5706_A1)) mdelay(15); /* Reset takes approximate 30 usec */ for (i = 0; i < 10; i++) { val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG); if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) { break; } udelay(10); } if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) { printf("Chip reset did not complete\n"); return -EBUSY; } /* Make sure byte swapping is properly configured. */ val = REG_RD(bp, BNX2_PCI_SWAP_DIAG0); if (val != 0x01020304) { printf("Chip not in correct endian mode\n"); return -ENODEV; } /* Wait for the firmware to finish its initialization. */ rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code, 0); if (rc) { return rc; } if (CHIP_ID(bp) == CHIP_ID_5706_A0) { /* Adjust the voltage regular to two steps lower. The default * of this register is 0x0000000e. */ REG_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa); /* Remove bad rbuf memory from the free pool. */ rc = bnx2_alloc_bad_rbuf(bp); } return rc; } static void bnx2_disable(struct nic *nic __unused) { struct bnx2* bp = &bnx2; if (bp->regview) { bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_UNLOAD); iounmap(bp->regview); } } static int bnx2_init_chip(struct bnx2 *bp) { u32 val; int rc; /* Make sure the interrupt is not active. */ REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT); val = BNX2_DMA_CONFIG_DATA_BYTE_SWAP | BNX2_DMA_CONFIG_DATA_WORD_SWAP | #if __BYTE_ORDER == __BIG_ENDIAN BNX2_DMA_CONFIG_CNTL_BYTE_SWAP | #endif BNX2_DMA_CONFIG_CNTL_WORD_SWAP | DMA_READ_CHANS << 12 | DMA_WRITE_CHANS << 16; val |= (0x2 << 20) | (1 << 11); if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz == 133)) val |= (1 << 23); if ((CHIP_NUM(bp) == CHIP_NUM_5706) && (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & PCIX_FLAG)) val |= BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA; REG_WR(bp, BNX2_DMA_CONFIG, val); if (CHIP_ID(bp) == CHIP_ID_5706_A0) { val = REG_RD(bp, BNX2_TDMA_CONFIG); val |= BNX2_TDMA_CONFIG_ONE_DMA; REG_WR(bp, BNX2_TDMA_CONFIG, val); } if (bp->flags & PCIX_FLAG) { u16 val16; pci_read_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD, &val16); pci_write_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD, val16 & ~PCI_X_CMD_ERO); } REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE | BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE | BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE); /* Initialize context mapping and zero out the quick contexts. The * context block must have already been enabled. */ bnx2_init_context(bp); bnx2_init_nvram(bp); bnx2_init_cpus(bp); bnx2_set_mac_addr(bp); val = REG_RD(bp, BNX2_MQ_CONFIG); val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE; val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256; REG_WR(bp, BNX2_MQ_CONFIG, val); val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE); REG_WR(bp, BNX2_MQ_KNL_BYP_WIND_START, val); REG_WR(bp, BNX2_MQ_KNL_WIND_END, val); val = (BCM_PAGE_BITS - 8) << 24; REG_WR(bp, BNX2_RV2P_CONFIG, val); /* Configure page size. */ val = REG_RD(bp, BNX2_TBDR_CONFIG); val &= ~BNX2_TBDR_CONFIG_PAGE_SIZE; val |= (BCM_PAGE_BITS - 8) << 24 | 0x40; REG_WR(bp, BNX2_TBDR_CONFIG, val); val = bp->mac_addr[0] + (bp->mac_addr[1] << 8) + (bp->mac_addr[2] << 16) + bp->mac_addr[3] + (bp->mac_addr[4] << 8) + (bp->mac_addr[5] << 16); REG_WR(bp, BNX2_EMAC_BACKOFF_SEED, val); /* Program the MTU. Also include 4 bytes for CRC32. */ val = ETH_MAX_MTU + ETH_HLEN + 4; if (val > (MAX_ETHERNET_PACKET_SIZE + 4)) val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA; REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val); bp->last_status_idx = 0; bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE; /* Set up how to generate a link change interrupt. */ REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK); REG_WR(bp, BNX2_HC_STATUS_ADDR_L, (u64) bp->status_blk_mapping & 0xffffffff); REG_WR(bp, BNX2_HC_STATUS_ADDR_H, (u64) bp->status_blk_mapping >> 32); REG_WR(bp, BNX2_HC_STATISTICS_ADDR_L, (u64) bp->stats_blk_mapping & 0xffffffff); REG_WR(bp, BNX2_HC_STATISTICS_ADDR_H, (u64) bp->stats_blk_mapping >> 32); REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP, (bp->tx_quick_cons_trip_int << 16) | bp->tx_quick_cons_trip); REG_WR(bp, BNX2_HC_RX_QUICK_CONS_TRIP, (bp->rx_quick_cons_trip_int << 16) | bp->rx_quick_cons_trip); REG_WR(bp, BNX2_HC_COMP_PROD_TRIP, (bp->comp_prod_trip_int << 16) | bp->comp_prod_trip); REG_WR(bp, BNX2_HC_TX_TICKS, (bp->tx_ticks_int << 16) | bp->tx_ticks); REG_WR(bp, BNX2_HC_RX_TICKS, (bp->rx_ticks_int << 16) | bp->rx_ticks); REG_WR(bp, BNX2_HC_COM_TICKS, (bp->com_ticks_int << 16) | bp->com_ticks); REG_WR(bp, BNX2_HC_CMD_TICKS, (bp->cmd_ticks_int << 16) | bp->cmd_ticks); REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00); REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ if (CHIP_ID(bp) == CHIP_ID_5706_A1) REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_COLLECT_STATS); else { REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_RX_TMR_MODE | BNX2_HC_CONFIG_TX_TMR_MODE | BNX2_HC_CONFIG_COLLECT_STATS); } /* Clear internal stats counters. */ REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW); REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE); if (REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_FEATURE) & BNX2_PORT_FEATURE_ASF_ENABLED) bp->flags |= ASF_ENABLE_FLAG; /* Initialize the receive filter. */ bnx2_set_rx_mode(bp->nic); rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET, 0); REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff); REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS); udelay(20); bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND); return rc; } static void bnx2_init_tx_ring(struct bnx2 *bp) { struct tx_bd *txbd; u32 val; txbd = &bp->tx_desc_ring[MAX_TX_DESC_CNT]; /* Etherboot lives below 4GB, so hi is always 0 */ txbd->tx_bd_haddr_hi = 0; txbd->tx_bd_haddr_lo = bp->tx_desc_mapping; bp->tx_prod = 0; bp->tx_cons = 0; bp->hw_tx_cons = 0; bp->tx_prod_bseq = 0; val = BNX2_L2CTX_TYPE_TYPE_L2; val |= BNX2_L2CTX_TYPE_SIZE_L2; CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TYPE, val); val = BNX2_L2CTX_CMD_TYPE_TYPE_L2; val |= 8 << 16; CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_CMD_TYPE, val); /* Etherboot lives below 4GB, so hi is always 0 */ CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_HI, 0); val = (u64) bp->tx_desc_mapping & 0xffffffff; CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_LO, val); } static void bnx2_init_rx_ring(struct bnx2 *bp) { struct rx_bd *rxbd; unsigned int i; u16 prod, ring_prod; u32 val; bp->rx_buf_use_size = RX_BUF_USE_SIZE; bp->rx_buf_size = RX_BUF_SIZE; ring_prod = prod = bp->rx_prod = 0; bp->rx_cons = 0; bp->hw_rx_cons = 0; bp->rx_prod_bseq = 0; memset(bnx2_bss.rx_buf, 0, sizeof(bnx2_bss.rx_buf)); rxbd = &bp->rx_desc_ring[0]; for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) { rxbd->rx_bd_len = bp->rx_buf_use_size; rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END; } rxbd->rx_bd_haddr_hi = 0; rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping & 0xffffffff; val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE; val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; val |= 0x02 << 8; CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val); /* Etherboot doesn't use memory above 4GB, so this is always 0 */ CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, 0); val = bp->rx_desc_mapping & 0xffffffff; CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val); for (i = 0; (int) i < bp->rx_ring_size; i++) { rxbd = &bp->rx_desc_ring[RX_RING_IDX(ring_prod)]; rxbd->rx_bd_haddr_hi = 0; rxbd->rx_bd_haddr_lo = virt_to_bus(&bnx2_bss.rx_buf[ring_prod][0]); bp->rx_prod_bseq += bp->rx_buf_use_size; prod = NEXT_RX_BD(prod); ring_prod = RX_RING_IDX(prod); } bp->rx_prod = prod; REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, bp->rx_prod); REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq); } static int bnx2_reset_nic(struct bnx2 *bp, u32 reset_code) { int rc; rc = bnx2_reset_chip(bp, reset_code); if (rc) { return rc; } bnx2_init_chip(bp); bnx2_init_tx_ring(bp); bnx2_init_rx_ring(bp); return 0; } static int bnx2_init_nic(struct bnx2 *bp) { int rc; if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0) return rc; bnx2_init_phy(bp); bnx2_set_link(bp); return 0; } static int bnx2_init_board(struct pci_device *pdev, struct nic *nic) { unsigned long bnx2reg_base, bnx2reg_len; struct bnx2 *bp = &bnx2; int rc; u32 reg; bp->flags = 0; bp->phy_flags = 0; /* enable device (incl. PCI PM wakeup), and bus-mastering */ adjust_pci_device(pdev); nic->ioaddr = pdev->ioaddr & ~3; nic->irqno = 0; rc = 0; bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); if (bp->pm_cap == 0) { printf("Cannot find power management capability, aborting.\n"); rc = -EIO; goto err_out_disable; } bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); if (bp->pcix_cap == 0) { printf("Cannot find PCIX capability, aborting.\n"); rc = -EIO; goto err_out_disable; } bp->pdev = pdev; bp->nic = nic; bnx2reg_base = pci_bar_start(pdev, PCI_BASE_ADDRESS_0); bnx2reg_len = MB_GET_CID_ADDR(17); bp->regview = ioremap(bnx2reg_base, bnx2reg_len); if (!bp->regview) { printf("Cannot map register space, aborting.\n"); rc = -EIO; goto err_out_disable; } /* Configure byte swap and enable write to the reg_window registers. * Rely on CPU to do target byte swapping on big endian systems * The chip's target access swapping will not swap all accesses */ pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP); bnx2_set_power_state_0(bp); bp->chip_id = REG_RD(bp, BNX2_MISC_ID); /* Get bus information. */ reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS); if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) { u32 clkreg; bp->flags |= PCIX_FLAG; clkreg = REG_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS); clkreg &= BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET; switch (clkreg) { case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ: bp->bus_speed_mhz = 133; break; case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ: bp->bus_speed_mhz = 100; break; case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ: case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ: bp->bus_speed_mhz = 66; break; case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ: case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ: bp->bus_speed_mhz = 50; break; case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW: case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ: case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ: bp->bus_speed_mhz = 33; break; } } else { if (reg & BNX2_PCICFG_MISC_STATUS_M66EN) bp->bus_speed_mhz = 66; else bp->bus_speed_mhz = 33; } if (reg & BNX2_PCICFG_MISC_STATUS_32BIT_DET) bp->flags |= PCI_32BIT_FLAG; /* 5706A0 may falsely detect SERR and PERR. */ if (CHIP_ID(bp) == CHIP_ID_5706_A0) { reg = REG_RD(bp, PCI_COMMAND); reg &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY); REG_WR(bp, PCI_COMMAND, reg); } else if ((CHIP_ID(bp) == CHIP_ID_5706_A1) && !(bp->flags & PCIX_FLAG)) { printf("5706 A1 can only be used in a PCIX bus, aborting.\n"); goto err_out_disable; } bnx2_init_nvram(bp); reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE); if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) == BNX2_SHM_HDR_SIGNATURE_SIG) bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0); else bp->shmem_base = HOST_VIEW_SHMEM_BASE; /* Get the permanent MAC address. First we need to make sure the * firmware is actually running. */ reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE); if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) != BNX2_DEV_INFO_SIGNATURE_MAGIC) { printf("Firmware not running, aborting.\n"); rc = -ENODEV; goto err_out_disable; } bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV); reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER); bp->mac_addr[0] = (u8) (reg >> 8); bp->mac_addr[1] = (u8) reg; reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER); bp->mac_addr[2] = (u8) (reg >> 24); bp->mac_addr[3] = (u8) (reg >> 16); bp->mac_addr[4] = (u8) (reg >> 8); bp->mac_addr[5] = (u8) reg; bp->tx_ring_size = MAX_TX_DESC_CNT; bp->rx_ring_size = RX_BUF_CNT; bp->rx_max_ring_idx = MAX_RX_DESC_CNT; bp->rx_offset = RX_OFFSET; bp->tx_quick_cons_trip_int = 20; bp->tx_quick_cons_trip = 20; bp->tx_ticks_int = 80; bp->tx_ticks = 80; bp->rx_quick_cons_trip_int = 6; bp->rx_quick_cons_trip = 6; bp->rx_ticks_int = 18; bp->rx_ticks = 18; bp->stats_ticks = 1000000 & 0xffff00; bp->phy_addr = 1; /* No need for WOL support in Etherboot */ bp->flags |= NO_WOL_FLAG; /* Disable WOL support if we are running on a SERDES chip. */ if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { bp->phy_flags |= PHY_SERDES_FLAG; if (CHIP_NUM(bp) == CHIP_NUM_5708) { bp->phy_addr = 2; reg = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG); if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G) bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG; } } if (CHIP_ID(bp) == CHIP_ID_5706_A0) { bp->tx_quick_cons_trip_int = bp->tx_quick_cons_trip; bp->tx_ticks_int = bp->tx_ticks; bp->rx_quick_cons_trip_int = bp->rx_quick_cons_trip; bp->rx_ticks_int = bp->rx_ticks; bp->comp_prod_trip_int = bp->comp_prod_trip; bp->com_ticks_int = bp->com_ticks; bp->cmd_ticks_int = bp->cmd_ticks; } bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL; bp->req_line_speed = 0; if (bp->phy_flags & PHY_SERDES_FLAG) { bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG); reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK; if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) { bp->autoneg = 0; bp->req_line_speed = bp->line_speed = SPEED_1000; bp->req_duplex = DUPLEX_FULL; } } else { bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg; } bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX; /* Disable driver heartbeat checking */ REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE); REG_RD_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB); return 0; err_out_disable: bnx2_disable(nic); return rc; } static void bnx2_transmit(struct nic *nic, const char *dst_addr, unsigned int type, unsigned int size, const char *packet) { /* Sometimes the nic will be behind by a frame. Using two transmit * buffers prevents us from timing out in that case. */ static struct eth_frame { uint8_t dst_addr[ETH_ALEN]; uint8_t src_addr[ETH_ALEN]; uint16_t type; uint8_t data [ETH_FRAME_LEN - ETH_HLEN]; } frame[2]; static int frame_idx = 0; /* send the packet to destination */ struct tx_bd *txbd; struct bnx2 *bp = &bnx2; u16 prod, ring_prod; u16 hw_cons; int i = 0; prod = bp->tx_prod; ring_prod = TX_RING_IDX(prod); hw_cons = bp->status_blk->status_tx_quick_consumer_index0; if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { hw_cons++; } while((hw_cons != prod) && (hw_cons != (PREV_TX_BD(prod)))) { mdelay(10); /* give the nic a chance */ //poll_interruptions(); if (++i > 500) { /* timeout 5s for transmit */ printf("transmit timed out\n"); bnx2_disable(bp->nic); bnx2_init_board(bp->pdev, bp->nic); return; } } if (i != 0) { printf("#"); } /* Copy the packet to the our local buffer */ memcpy(&frame[frame_idx].dst_addr, dst_addr, ETH_ALEN); memcpy(&frame[frame_idx].src_addr, nic->node_addr, ETH_ALEN); frame[frame_idx].type = htons(type); memset(&frame[frame_idx].data, 0, sizeof(frame[frame_idx].data)); memcpy(&frame[frame_idx].data, packet, size); /* Setup the ring buffer entry to transmit */ txbd = &bp->tx_desc_ring[ring_prod]; txbd->tx_bd_haddr_hi = 0; /* Etherboot runs under 4GB */ txbd->tx_bd_haddr_lo = virt_to_bus(&frame[frame_idx]); txbd->tx_bd_mss_nbytes = (size + ETH_HLEN); txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END; /* Advance to the next entry */ prod = NEXT_TX_BD(prod); frame_idx ^= 1; bp->tx_prod_bseq += (size + ETH_HLEN); REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod); REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); wmb(); bp->tx_prod = prod; } static int bnx2_poll_link(struct bnx2 *bp) { u32 new_link_state, old_link_state, emac_status; new_link_state = bp->status_blk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE; old_link_state = bp->status_blk->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE; if (!new_link_state && !old_link_state) { /* For some reason the card doesn't always update the link * status bits properly. Kick the stupid thing and try again. */ u32 bmsr; bnx2_read_phy(bp, MII_BMSR, &bmsr); bnx2_read_phy(bp, MII_BMSR, &bmsr); if ((bp->phy_flags & PHY_SERDES_FLAG) && (CHIP_NUM(bp) == CHIP_NUM_5706)) { REG_RD(bp, BNX2_EMAC_STATUS); } new_link_state = bp->status_blk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE; old_link_state = bp->status_blk->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE; /* Okay, for some reason the above doesn't work with some * switches (like HP ProCurve). If the above doesn't work, * check the MAC directly to see if we have a link. Perhaps we * should always check the MAC instead probing the MII. */ if (!new_link_state && !old_link_state) { emac_status = REG_RD(bp, BNX2_EMAC_STATUS); if (emac_status & BNX2_EMAC_STATUS_LINK_CHANGE) { /* Acknowledge the link change */ REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE); } else if (emac_status & BNX2_EMAC_STATUS_LINK) { new_link_state = !old_link_state; } } } if (new_link_state != old_link_state) { if (new_link_state) { REG_WR(bp, BNX2_PCICFG_STATUS_BIT_SET_CMD, STATUS_ATTN_BITS_LINK_STATE); } else { REG_WR(bp, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD, STATUS_ATTN_BITS_LINK_STATE); } bnx2_set_link(bp); /* This is needed to take care of transient status * during link changes. */ REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); REG_RD(bp, BNX2_HC_COMMAND); } return bp->link_up; } static int bnx2_poll(struct nic* nic, int retrieve) { struct bnx2 *bp = &bnx2; struct rx_bd *cons_bd, *prod_bd; u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod; struct l2_fhdr *rx_hdr; int result = 0; unsigned int len; unsigned char *data; u32 status; #if 0 if ((bp->status_blk->status_idx == bp->last_status_idx) && (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) & BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) { bp->last_status_idx = bp->status_blk->status_idx; REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx); return 0; } #endif if ((bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) && !retrieve) return 1; if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) { hw_cons = bp->hw_rx_cons = bp->status_blk->status_rx_quick_consumer_index0; if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) { hw_cons++; } sw_cons = bp->rx_cons; sw_prod = bp->rx_prod; rmb(); if (sw_cons != hw_cons) { sw_ring_cons = RX_RING_IDX(sw_cons); sw_ring_prod = RX_RING_IDX(sw_prod); data = bus_to_virt(bp->rx_desc_ring[sw_ring_cons].rx_bd_haddr_lo); rx_hdr = (struct l2_fhdr *)data; len = rx_hdr->l2_fhdr_pkt_len - 4; if ((len > (ETH_MAX_MTU + ETH_HLEN)) || ((status = rx_hdr->l2_fhdr_status) & (L2_FHDR_ERRORS_BAD_CRC | L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT | L2_FHDR_ERRORS_TOO_SHORT | L2_FHDR_ERRORS_GIANT_FRAME))) { result = 0; } else { nic->packetlen = len; memcpy(nic->packet, data + bp->rx_offset, len); result = 1; } /* Reuse the buffer */ bp->rx_prod_bseq += bp->rx_buf_use_size; if (sw_cons != sw_prod) { cons_bd = &bp->rx_desc_ring[sw_ring_cons]; prod_bd = &bp->rx_desc_ring[sw_ring_prod]; prod_bd->rx_bd_haddr_hi = 0; /* Etherboot runs under 4GB */ prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo; } sw_cons = NEXT_RX_BD(sw_cons); sw_prod = NEXT_RX_BD(sw_prod); } bp->rx_cons = sw_cons; bp->rx_prod = sw_prod; REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, bp->rx_prod); REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq); wmb(); } bnx2_poll_link(bp); #if 0 bp->last_status_idx = bp->status_blk->status_idx; rmb(); REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx); REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); #endif return result; } static void bnx2_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE: break; case ENABLE: break; case FORCE: break; } } static struct nic_operations bnx2_operations = { .connect = dummy_connect, .poll = bnx2_poll, .transmit = bnx2_transmit, .irq = bnx2_irq, }; static int bnx2_probe(struct nic *nic, struct pci_device *pdev) { struct bnx2 *bp = &bnx2; int i, rc; if (pdev == 0) return 0; memset(bp, 0, sizeof(*bp)); rc = bnx2_init_board(pdev, nic); if (rc < 0) { return 0; } /* nic->disable = bnx2_disable; nic->transmit = bnx2_transmit; nic->poll = bnx2_poll; nic->irq = bnx2_irq; */ nic->nic_op = &bnx2_operations; memcpy(nic->node_addr, bp->mac_addr, ETH_ALEN); printf("Ethernet addr: %s\n", eth_ntoa( nic->node_addr ) ); printf("Broadcom NetXtreme II (%c%d) PCI%s %s %dMHz\n", (int) ((CHIP_ID(bp) & 0xf000) >> 12) + 'A', (int) ((CHIP_ID(bp) & 0x0ff0) >> 4), ((bp->flags & PCIX_FLAG) ? "-X" : ""), ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"), bp->bus_speed_mhz); bnx2_set_power_state_0(bp); bnx2_disable_int(bp); bnx2_alloc_mem(bp); rc = bnx2_init_nic(bp); if (rc) { return 0; } bnx2_poll_link(bp); for(i = 0; !bp->link_up && (i < VALID_LINK_TIMEOUT*100); i++) { mdelay(1); bnx2_poll_link(bp); } #if 1 if (!bp->link_up){ printf("Valid link not established\n"); goto err_out_disable; } #endif return 1; err_out_disable: bnx2_disable(nic); return 0; } static struct pci_device_id bnx2_nics[] = { PCI_ROM(0x14e4, 0x164a, "bnx2-5706", "Broadcom NetXtreme II BCM5706", 0), PCI_ROM(0x14e4, 0x164c, "bnx2-5708", "Broadcom NetXtreme II BCM5708", 0), PCI_ROM(0x14e4, 0x16aa, "bnx2-5706S", "Broadcom NetXtreme II BCM5706S", 0), PCI_ROM(0x14e4, 0x16ac, "bnx2-5708S", "Broadcom NetXtreme II BCM5708S", 0), }; PCI_DRIVER ( bnx2_driver, bnx2_nics, PCI_NO_CLASS ); DRIVER ( "BNX2", nic_driver, pci_driver, bnx2_driver, bnx2_probe, bnx2_disable ); /* static struct pci_driver bnx2_driver __pci_driver = { .type = NIC_DRIVER, .name = "BNX2", .probe = bnx2_probe, .ids = bnx2_nics, .id_count = sizeof(bnx2_nics)/sizeof(bnx2_nics[0]), .class = 0, }; */ debian/grub-extras/disabled/gpxe/src/drivers/net/atl1e.c0000664000000000000000000013204512524662415020366 0ustar /* * Copyright(c) 2007 Atheros Corporation. All rights reserved. * * Derived from Intel e1000 driver * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. * * Modified for gPXE, October 2009 by Joshua Oreman . * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 * Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include "atl1e.h" /* User-tweakable parameters: */ #define TX_DESC_COUNT 32 /* TX descriptors, minimum 32 */ #define RX_MEM_SIZE 8192 /* RX area size, minimum 8kb */ #define MAX_FRAME_SIZE 1500 /* Maximum MTU supported, minimum 1500 */ /* Arcane parameters: */ #define PREAMBLE_LEN 7 #define RX_JUMBO_THRESH ((MAX_FRAME_SIZE + ETH_HLEN + \ VLAN_HLEN + ETH_FCS_LEN + 7) >> 3) #define IMT_VAL 100 /* interrupt moderator timer, us */ #define ICT_VAL 50000 /* interrupt clear timer, us */ #define SMB_TIMER 200000 #define RRD_THRESH 1 /* packets to queue before interrupt */ #define TPD_BURST 5 #define TPD_THRESH (TX_DESC_COUNT / 2) #define RX_COUNT_DOWN 4 #define TX_COUNT_DOWN (IMT_VAL * 4 / 3) #define DMAR_DLY_CNT 15 #define DMAW_DLY_CNT 4 #define PCI_DEVICE_ID_ATTANSIC_L1E 0x1026 /* * atl1e_pci_tbl - PCI Device ID Table * * Wildcard entries (PCI_ANY_ID) should come last * Last entry must be all 0s * * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, * Class, Class Mask, private data (not used) } */ static struct pci_device_id atl1e_pci_tbl[] = { PCI_ROM(0x1969, 0x1026, "atl1e_26", "Attansic L1E 0x1026", 0), PCI_ROM(0x1969, 0x1066, "atl1e_66", "Attansic L1E 0x1066", 0), }; static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter); static const u16 atl1e_rx_page_vld_regs[AT_PAGE_NUM_PER_QUEUE] = { REG_HOST_RXF0_PAGE0_VLD, REG_HOST_RXF0_PAGE1_VLD }; static const u16 atl1e_rx_page_lo_addr_regs[AT_PAGE_NUM_PER_QUEUE] = { REG_HOST_RXF0_PAGE0_LO, REG_HOST_RXF0_PAGE1_LO }; static const u16 atl1e_rx_page_write_offset_regs[AT_PAGE_NUM_PER_QUEUE] = { REG_HOST_RXF0_MB0_LO, REG_HOST_RXF0_MB1_LO }; static const u16 atl1e_pay_load_size[] = { 128, 256, 512, 1024, 2048, 4096, }; /* * atl1e_irq_enable - Enable default interrupt generation settings * @adapter: board private structure */ static inline void atl1e_irq_enable(struct atl1e_adapter *adapter) { AT_WRITE_REG(&adapter->hw, REG_ISR, 0); AT_WRITE_REG(&adapter->hw, REG_IMR, IMR_NORMAL_MASK); AT_WRITE_FLUSH(&adapter->hw); } /* * atl1e_irq_disable - Mask off interrupt generation on the NIC * @adapter: board private structure */ static inline void atl1e_irq_disable(struct atl1e_adapter *adapter) { AT_WRITE_REG(&adapter->hw, REG_IMR, 0); AT_WRITE_FLUSH(&adapter->hw); } /* * atl1e_irq_reset - reset interrupt confiure on the NIC * @adapter: board private structure */ static inline void atl1e_irq_reset(struct atl1e_adapter *adapter) { AT_WRITE_REG(&adapter->hw, REG_ISR, 0); AT_WRITE_REG(&adapter->hw, REG_IMR, 0); AT_WRITE_FLUSH(&adapter->hw); } static void atl1e_reset(struct atl1e_adapter *adapter) { atl1e_down(adapter); atl1e_up(adapter); } static int atl1e_check_link(struct atl1e_adapter *adapter) { struct atl1e_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; int err = 0; u16 speed, duplex, phy_data; /* MII_BMSR must read twise */ atl1e_read_phy_reg(hw, MII_BMSR, &phy_data); atl1e_read_phy_reg(hw, MII_BMSR, &phy_data); if ((phy_data & BMSR_LSTATUS) == 0) { /* link down */ if (netdev_link_ok(netdev)) { /* old link state: Up */ u32 value; /* disable rx */ value = AT_READ_REG(hw, REG_MAC_CTRL); value &= ~MAC_CTRL_RX_EN; AT_WRITE_REG(hw, REG_MAC_CTRL, value); adapter->link_speed = SPEED_0; DBG("atl1e: %s link is down\n", netdev->name); netdev_link_down(netdev); } } else { /* Link Up */ err = atl1e_get_speed_and_duplex(hw, &speed, &duplex); if (err) return err; /* link result is our setting */ if (adapter->link_speed != speed || adapter->link_duplex != duplex) { adapter->link_speed = speed; adapter->link_duplex = duplex; atl1e_setup_mac_ctrl(adapter); DBG("atl1e: %s link is up, %d Mbps, %s duplex\n", netdev->name, adapter->link_speed, adapter->link_duplex == FULL_DUPLEX ? "full" : "half"); netdev_link_up(netdev); } } return 0; } static int atl1e_mdio_read(struct net_device *netdev, int phy_id __unused, int reg_num) { struct atl1e_adapter *adapter = netdev_priv(netdev); u16 result; atl1e_read_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, &result); return result; } static void atl1e_mdio_write(struct net_device *netdev, int phy_id __unused, int reg_num, int val) { struct atl1e_adapter *adapter = netdev_priv(netdev); atl1e_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val); } static void atl1e_setup_pcicmd(struct pci_device *pdev) { u16 cmd; pci_read_config_word(pdev, PCI_COMMAND, &cmd); cmd |= (PCI_COMMAND_MEM | PCI_COMMAND_MASTER); pci_write_config_word(pdev, PCI_COMMAND, cmd); /* * some motherboards BIOS(PXE/EFI) driver may set PME * while they transfer control to OS (Windows/Linux) * so we should clear this bit before NIC work normally */ pci_write_config_dword(pdev, REG_PM_CTRLSTAT, 0); mdelay(1); } /* * atl1e_sw_init - Initialize general software structures (struct atl1e_adapter) * @adapter: board private structure to initialize * * atl1e_sw_init initializes the Adapter private data structure. * Fields are initialized based on PCI device information and * OS network device settings (MTU size). */ static int atl1e_sw_init(struct atl1e_adapter *adapter) { struct atl1e_hw *hw = &adapter->hw; struct pci_device *pdev = adapter->pdev; u32 phy_status_data = 0; u8 rev_id = 0; adapter->link_speed = SPEED_0; /* hardware init */ adapter->link_duplex = FULL_DUPLEX; /* PCI config space info */ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS); /* nic type */ if (rev_id >= 0xF0) { hw->nic_type = athr_l2e_revB; } else { if (phy_status_data & PHY_STATUS_100M) hw->nic_type = athr_l1e; else hw->nic_type = athr_l2e_revA; } phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS); hw->emi_ca = !!(phy_status_data & PHY_STATUS_EMI_CA); hw->phy_configured = 0; /* need confirm */ hw->dmar_block = atl1e_dma_req_1024; hw->dmaw_block = atl1e_dma_req_1024; netdev_link_down(adapter->netdev); return 0; } /* * atl1e_clean_tx_ring - free all Tx buffers for device close * @adapter: board private structure */ static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter) { struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *) &adapter->tx_ring; struct atl1e_tx_buffer *tx_buffer = NULL; u16 index, ring_count = tx_ring->count; if (tx_ring->desc == NULL || tx_ring->tx_buffer == NULL) return; for (index = 0; index < ring_count; index++) { tx_buffer = &tx_ring->tx_buffer[index]; if (tx_buffer->iob) { netdev_tx_complete(adapter->netdev, tx_buffer->iob); tx_buffer->dma = 0; tx_buffer->iob = NULL; } } /* Zero out Tx-buffers */ memset(tx_ring->desc, 0, sizeof(struct atl1e_tpd_desc) * ring_count); memset(tx_ring->tx_buffer, 0, sizeof(struct atl1e_tx_buffer) * ring_count); } /* * atl1e_clean_rx_ring - Free rx-reservation iobs * @adapter: board private structure */ static void atl1e_clean_rx_ring(struct atl1e_adapter *adapter) { struct atl1e_rx_ring *rx_ring = (struct atl1e_rx_ring *)&adapter->rx_ring; struct atl1e_rx_page_desc *rx_page_desc = &rx_ring->rx_page_desc; u16 j; if (adapter->ring_vir_addr == NULL) return; /* Zero out the descriptor ring */ for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) { if (rx_page_desc->rx_page[j].addr != NULL) { memset(rx_page_desc->rx_page[j].addr, 0, rx_ring->real_page_size); } } } static void atl1e_cal_ring_size(struct atl1e_adapter *adapter, u32 *ring_size) { *ring_size = ((u32)(adapter->tx_ring.count * sizeof(struct atl1e_tpd_desc) + 7 /* tx ring, qword align */ + adapter->rx_ring.real_page_size * AT_PAGE_NUM_PER_QUEUE + 31 /* rx ring, 32 bytes align */ + (1 + AT_PAGE_NUM_PER_QUEUE) * sizeof(u32) + 3)); /* tx, rx cmd, dword align */ } static void atl1e_init_ring_resources(struct atl1e_adapter *adapter) { struct atl1e_tx_ring *tx_ring = NULL; struct atl1e_rx_ring *rx_ring = NULL; tx_ring = &adapter->tx_ring; rx_ring = &adapter->rx_ring; rx_ring->real_page_size = adapter->rx_ring.page_size + MAX_FRAME_SIZE + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN; rx_ring->real_page_size = (rx_ring->real_page_size + 31) & ~31; atl1e_cal_ring_size(adapter, &adapter->ring_size); adapter->ring_vir_addr = NULL; adapter->rx_ring.desc = NULL; return; } /* * Read / Write Ptr Initialize: */ static void atl1e_init_ring_ptrs(struct atl1e_adapter *adapter) { struct atl1e_tx_ring *tx_ring = NULL; struct atl1e_rx_ring *rx_ring = NULL; struct atl1e_rx_page_desc *rx_page_desc = NULL; int j; tx_ring = &adapter->tx_ring; rx_ring = &adapter->rx_ring; rx_page_desc = &rx_ring->rx_page_desc; tx_ring->next_to_use = 0; tx_ring->next_to_clean = 0; rx_page_desc->rx_using = 0; rx_page_desc->rx_nxseq = 0; for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) { *rx_page_desc->rx_page[j].write_offset_addr = 0; rx_page_desc->rx_page[j].read_offset = 0; } } /* * atl1e_free_ring_resources - Free Tx / RX descriptor Resources * @adapter: board private structure * * Free all transmit software resources */ static void atl1e_free_ring_resources(struct atl1e_adapter *adapter) { atl1e_clean_tx_ring(adapter); atl1e_clean_rx_ring(adapter); if (adapter->ring_vir_addr) { free_dma(adapter->ring_vir_addr, adapter->ring_size); adapter->ring_vir_addr = NULL; adapter->ring_dma = 0; } if (adapter->tx_ring.tx_buffer) { free(adapter->tx_ring.tx_buffer); adapter->tx_ring.tx_buffer = NULL; } } /* * atl1e_setup_mem_resources - allocate Tx / RX descriptor resources * @adapter: board private structure * * Return 0 on success, negative on failure */ static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter) { struct atl1e_tx_ring *tx_ring; struct atl1e_rx_ring *rx_ring; struct atl1e_rx_page_desc *rx_page_desc; int size, j; u32 offset = 0; int err = 0; if (adapter->ring_vir_addr != NULL) return 0; /* alloced already */ tx_ring = &adapter->tx_ring; rx_ring = &adapter->rx_ring; /* real ring DMA buffer */ size = adapter->ring_size; adapter->ring_vir_addr = malloc_dma(adapter->ring_size, 32); if (adapter->ring_vir_addr == NULL) { DBG("atl1e: out of memory allocating %d bytes for %s ring\n", adapter->ring_size, adapter->netdev->name); return -ENOMEM; } adapter->ring_dma = virt_to_bus(adapter->ring_vir_addr); memset(adapter->ring_vir_addr, 0, adapter->ring_size); rx_page_desc = &rx_ring->rx_page_desc; /* Init TPD Ring */ tx_ring->dma = (adapter->ring_dma + 7) & ~7; offset = tx_ring->dma - adapter->ring_dma; tx_ring->desc = (struct atl1e_tpd_desc *) (adapter->ring_vir_addr + offset); size = sizeof(struct atl1e_tx_buffer) * (tx_ring->count); tx_ring->tx_buffer = zalloc(size); if (tx_ring->tx_buffer == NULL) { DBG("atl1e: out of memory allocating %d bytes for %s txbuf\n", size, adapter->netdev->name); err = -ENOMEM; goto failed; } /* Init RXF-Pages */ offset += (sizeof(struct atl1e_tpd_desc) * tx_ring->count); offset = (offset + 31) & ~31; for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) { rx_page_desc->rx_page[j].dma = adapter->ring_dma + offset; rx_page_desc->rx_page[j].addr = adapter->ring_vir_addr + offset; offset += rx_ring->real_page_size; } /* Init CMB dma address */ tx_ring->cmb_dma = adapter->ring_dma + offset; tx_ring->cmb = (u32 *)(adapter->ring_vir_addr + offset); offset += sizeof(u32); for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) { rx_page_desc->rx_page[j].write_offset_dma = adapter->ring_dma + offset; rx_page_desc->rx_page[j].write_offset_addr = adapter->ring_vir_addr + offset; offset += sizeof(u32); } if (offset > adapter->ring_size) { DBG("atl1e: ring miscalculation! need %d > %d bytes\n", offset, adapter->ring_size); err = -EINVAL; goto failed; } return 0; failed: atl1e_free_ring_resources(adapter); return err; } static inline void atl1e_configure_des_ring(const struct atl1e_adapter *adapter) { struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw; struct atl1e_rx_ring *rx_ring = (struct atl1e_rx_ring *)&adapter->rx_ring; struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *)&adapter->tx_ring; struct atl1e_rx_page_desc *rx_page_desc = NULL; int j; AT_WRITE_REG(hw, REG_DESC_BASE_ADDR_HI, 0); AT_WRITE_REG(hw, REG_TPD_BASE_ADDR_LO, tx_ring->dma); AT_WRITE_REG(hw, REG_TPD_RING_SIZE, (u16)(tx_ring->count)); AT_WRITE_REG(hw, REG_HOST_TX_CMB_LO, tx_ring->cmb_dma); rx_page_desc = &rx_ring->rx_page_desc; /* RXF Page Physical address / Page Length */ AT_WRITE_REG(hw, REG_RXF0_BASE_ADDR_HI, 0); for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) { u32 page_phy_addr; u32 offset_phy_addr; page_phy_addr = rx_page_desc->rx_page[j].dma; offset_phy_addr = rx_page_desc->rx_page[j].write_offset_dma; AT_WRITE_REG(hw, atl1e_rx_page_lo_addr_regs[j], page_phy_addr); AT_WRITE_REG(hw, atl1e_rx_page_write_offset_regs[j], offset_phy_addr); AT_WRITE_REGB(hw, atl1e_rx_page_vld_regs[j], 1); } /* Page Length */ AT_WRITE_REG(hw, REG_HOST_RXFPAGE_SIZE, rx_ring->page_size); /* Load all of base address above */ AT_WRITE_REG(hw, REG_LOAD_PTR, 1); return; } static inline void atl1e_configure_tx(struct atl1e_adapter *adapter) { struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw; u32 dev_ctrl_data = 0; u32 max_pay_load = 0; u32 jumbo_thresh = 0; u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */ /* configure TXQ param */ if (hw->nic_type != athr_l2e_revB) { extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN; jumbo_thresh = MAX_FRAME_SIZE + extra_size; AT_WRITE_REG(hw, REG_TX_EARLY_TH, (jumbo_thresh + 7) >> 3); } dev_ctrl_data = AT_READ_REG(hw, REG_DEVICE_CTRL); max_pay_load = ((dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT)) & DEVICE_CTRL_MAX_PAYLOAD_MASK; if (max_pay_load < hw->dmaw_block) hw->dmaw_block = max_pay_load; max_pay_load = ((dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT)) & DEVICE_CTRL_MAX_RREQ_SZ_MASK; if (max_pay_load < hw->dmar_block) hw->dmar_block = max_pay_load; if (hw->nic_type != athr_l2e_revB) AT_WRITE_REGW(hw, REG_TXQ_CTRL + 2, atl1e_pay_load_size[hw->dmar_block]); /* enable TXQ */ AT_WRITE_REGW(hw, REG_TXQ_CTRL, ((TPD_BURST & TXQ_CTRL_NUM_TPD_BURST_MASK) << TXQ_CTRL_NUM_TPD_BURST_SHIFT) | TXQ_CTRL_ENH_MODE | TXQ_CTRL_EN); return; } static inline void atl1e_configure_rx(struct atl1e_adapter *adapter) { struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw; u32 rxf_len = 0; u32 rxf_low = 0; u32 rxf_high = 0; u32 rxf_thresh_data = 0; u32 rxq_ctrl_data = 0; if (hw->nic_type != athr_l2e_revB) { AT_WRITE_REGW(hw, REG_RXQ_JMBOSZ_RRDTIM, (u16)((RX_JUMBO_THRESH & RXQ_JMBOSZ_TH_MASK) << RXQ_JMBOSZ_TH_SHIFT | (1 & RXQ_JMBO_LKAH_MASK) << RXQ_JMBO_LKAH_SHIFT)); rxf_len = AT_READ_REG(hw, REG_SRAM_RXF_LEN); rxf_high = rxf_len * 4 / 5; rxf_low = rxf_len / 5; rxf_thresh_data = ((rxf_high & RXQ_RXF_PAUSE_TH_HI_MASK) << RXQ_RXF_PAUSE_TH_HI_SHIFT) | ((rxf_low & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT); AT_WRITE_REG(hw, REG_RXQ_RXF_PAUSE_THRESH, rxf_thresh_data); } /* RRS */ AT_WRITE_REG(hw, REG_IDT_TABLE, 0); AT_WRITE_REG(hw, REG_BASE_CPU_NUMBER, 0); rxq_ctrl_data |= RXQ_CTRL_PBA_ALIGN_32 | RXQ_CTRL_CUT_THRU_EN | RXQ_CTRL_EN; AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data); return; } static inline void atl1e_configure_dma(struct atl1e_adapter *adapter) { struct atl1e_hw *hw = &adapter->hw; u32 dma_ctrl_data = 0; dma_ctrl_data = DMA_CTRL_RXCMB_EN; dma_ctrl_data |= (((u32)hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK) << DMA_CTRL_DMAR_BURST_LEN_SHIFT; dma_ctrl_data |= (((u32)hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK) << DMA_CTRL_DMAW_BURST_LEN_SHIFT; dma_ctrl_data |= DMA_CTRL_DMAR_REQ_PRI | DMA_CTRL_DMAR_OUT_ORDER; dma_ctrl_data |= (DMAR_DLY_CNT & DMA_CTRL_DMAR_DLY_CNT_MASK) << DMA_CTRL_DMAR_DLY_CNT_SHIFT; dma_ctrl_data |= (DMAW_DLY_CNT & DMA_CTRL_DMAW_DLY_CNT_MASK) << DMA_CTRL_DMAW_DLY_CNT_SHIFT; AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data); return; } static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter) { u32 value; struct atl1e_hw *hw = &adapter->hw; /* Config MAC CTRL Register */ value = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN ; if (FULL_DUPLEX == adapter->link_duplex) value |= MAC_CTRL_DUPLX; value |= ((u32)((SPEED_1000 == adapter->link_speed) ? MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100) << MAC_CTRL_SPEED_SHIFT); value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW); value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD); value |= ((PREAMBLE_LEN & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); value |= MAC_CTRL_BC_EN; value |= MAC_CTRL_MC_ALL_EN; AT_WRITE_REG(hw, REG_MAC_CTRL, value); } /* * atl1e_configure - Configure Transmit&Receive Unit after Reset * @adapter: board private structure * * Configure the Tx /Rx unit of the MAC after a reset. */ static int atl1e_configure(struct atl1e_adapter *adapter) { struct atl1e_hw *hw = &adapter->hw; u32 intr_status_data = 0; /* clear interrupt status */ AT_WRITE_REG(hw, REG_ISR, ~0); /* 1. set MAC Address */ atl1e_hw_set_mac_addr(hw); /* 2. Init the Multicast HASH table (clear) */ AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0); AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); /* 3. Clear any WOL status */ AT_WRITE_REG(hw, REG_WOL_CTRL, 0); /* 4. Descripter Ring BaseMem/Length/Read ptr/Write ptr * TPD Ring/SMB/RXF0 Page CMBs, they use the same * High 32bits memory */ atl1e_configure_des_ring(adapter); /* 5. set Interrupt Moderator Timer */ AT_WRITE_REGW(hw, REG_IRQ_MODU_TIMER_INIT, IMT_VAL); AT_WRITE_REGW(hw, REG_IRQ_MODU_TIMER2_INIT, IMT_VAL); AT_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_LED_MODE | MASTER_CTRL_ITIMER_EN | MASTER_CTRL_ITIMER2_EN); /* 6. rx/tx threshold to trig interrupt */ AT_WRITE_REGW(hw, REG_TRIG_RRD_THRESH, RRD_THRESH); AT_WRITE_REGW(hw, REG_TRIG_TPD_THRESH, TPD_THRESH); AT_WRITE_REGW(hw, REG_TRIG_RXTIMER, RX_COUNT_DOWN); AT_WRITE_REGW(hw, REG_TRIG_TXTIMER, TX_COUNT_DOWN); /* 7. set Interrupt Clear Timer */ AT_WRITE_REGW(hw, REG_CMBDISDMA_TIMER, ICT_VAL); /* 8. set MTU */ AT_WRITE_REG(hw, REG_MTU, MAX_FRAME_SIZE + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN); /* 9. config TXQ early tx threshold */ atl1e_configure_tx(adapter); /* 10. config RXQ */ atl1e_configure_rx(adapter); /* 11. config DMA Engine */ atl1e_configure_dma(adapter); /* 12. smb timer to trig interrupt */ AT_WRITE_REG(hw, REG_SMB_STAT_TIMER, SMB_TIMER); intr_status_data = AT_READ_REG(hw, REG_ISR); if ((intr_status_data & ISR_PHY_LINKDOWN) != 0) { DBG("atl1e: configure failed, PCIE phy link down\n"); return -1; } AT_WRITE_REG(hw, REG_ISR, 0x7fffffff); return 0; } static inline void atl1e_clear_phy_int(struct atl1e_adapter *adapter) { u16 phy_data; atl1e_read_phy_reg(&adapter->hw, MII_INT_STATUS, &phy_data); } static int atl1e_clean_tx_irq(struct atl1e_adapter *adapter) { struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *) &adapter->tx_ring; struct atl1e_tx_buffer *tx_buffer = NULL; u16 hw_next_to_clean = AT_READ_REGW(&adapter->hw, REG_TPD_CONS_IDX); u16 next_to_clean = tx_ring->next_to_clean; while (next_to_clean != hw_next_to_clean) { tx_buffer = &tx_ring->tx_buffer[next_to_clean]; tx_buffer->dma = 0; if (tx_buffer->iob) { netdev_tx_complete(adapter->netdev, tx_buffer->iob); tx_buffer->iob = NULL; } if (++next_to_clean == tx_ring->count) next_to_clean = 0; } tx_ring->next_to_clean = next_to_clean; return 1; } static struct atl1e_rx_page *atl1e_get_rx_page(struct atl1e_adapter *adapter) { struct atl1e_rx_page_desc *rx_page_desc = (struct atl1e_rx_page_desc *) &adapter->rx_ring.rx_page_desc; u8 rx_using = rx_page_desc->rx_using; return (struct atl1e_rx_page *)&(rx_page_desc->rx_page[rx_using]); } static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter) { struct net_device *netdev = adapter->netdev; struct atl1e_rx_ring *rx_ring = (struct atl1e_rx_ring *) &adapter->rx_ring; struct atl1e_rx_page_desc *rx_page_desc = (struct atl1e_rx_page_desc *) &rx_ring->rx_page_desc; struct io_buffer *iob = NULL; struct atl1e_rx_page *rx_page = atl1e_get_rx_page(adapter); u32 packet_size, write_offset; struct atl1e_recv_ret_status *prrs; write_offset = *(rx_page->write_offset_addr); if (rx_page->read_offset >= write_offset) return; do { /* get new packet's rrs */ prrs = (struct atl1e_recv_ret_status *) (rx_page->addr + rx_page->read_offset); /* check sequence number */ if (prrs->seq_num != rx_page_desc->rx_nxseq) { DBG("atl1e %s: RX sequence number error (%d != %d)\n", netdev->name, prrs->seq_num, rx_page_desc->rx_nxseq); rx_page_desc->rx_nxseq++; goto fatal_err; } rx_page_desc->rx_nxseq++; /* error packet */ if (prrs->pkt_flag & RRS_IS_ERR_FRAME) { if (prrs->err_flag & (RRS_ERR_BAD_CRC | RRS_ERR_DRIBBLE | RRS_ERR_CODE | RRS_ERR_TRUNC)) { /* hardware error, discard this packet */ netdev_rx_err(netdev, NULL, EIO); goto skip_pkt; } } packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) & RRS_PKT_SIZE_MASK) - ETH_FCS_LEN; iob = alloc_iob(packet_size + NET_IP_ALIGN); if (iob == NULL) { DBG("atl1e %s: dropping packet under memory pressure\n", netdev->name); goto skip_pkt; } iob_reserve(iob, NET_IP_ALIGN); memcpy(iob->data, (u8 *)(prrs + 1), packet_size); iob_put(iob, packet_size); netdev_rx(netdev, iob); skip_pkt: /* skip current packet whether it's ok or not. */ rx_page->read_offset += (((u32)((prrs->word1 >> RRS_PKT_SIZE_SHIFT) & RRS_PKT_SIZE_MASK) + sizeof(struct atl1e_recv_ret_status) + 31) & 0xFFFFFFE0); if (rx_page->read_offset >= rx_ring->page_size) { /* mark this page clean */ u16 reg_addr; u8 rx_using; rx_page->read_offset = *(rx_page->write_offset_addr) = 0; rx_using = rx_page_desc->rx_using; reg_addr = atl1e_rx_page_vld_regs[rx_using]; AT_WRITE_REGB(&adapter->hw, reg_addr, 1); rx_page_desc->rx_using ^= 1; rx_page = atl1e_get_rx_page(adapter); } write_offset = *(rx_page->write_offset_addr); } while (rx_page->read_offset < write_offset); return; fatal_err: if (!netdev_link_ok(adapter->netdev)) atl1e_reset(adapter); } /* * atl1e_poll - poll for completed transmissions and received packets * @netdev: network device */ static void atl1e_poll(struct net_device *netdev) { struct atl1e_adapter *adapter = netdev_priv(netdev); struct atl1e_hw *hw = &adapter->hw; int max_ints = 64; u32 status; do { status = AT_READ_REG(hw, REG_ISR); if ((status & IMR_NORMAL_MASK) == 0) break; /* link event */ if (status & ISR_GPHY) atl1e_clear_phy_int(adapter); /* Ack ISR */ AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT); /* check if PCIE PHY Link down */ if (status & ISR_PHY_LINKDOWN) { DBG("atl1e: PCI-E PHY link down: %x\n", status); if (netdev_link_ok(adapter->netdev)) { /* reset MAC */ atl1e_irq_reset(adapter); atl1e_reset(adapter); break; } } /* check if DMA read/write error */ if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) { DBG("atl1e: PCI-E DMA RW error: %x\n", status); atl1e_irq_reset(adapter); atl1e_reset(adapter); break; } /* link event */ if (status & (ISR_GPHY | ISR_MANUAL)) { atl1e_check_link(adapter); break; } /* transmit event */ if (status & ISR_TX_EVENT) atl1e_clean_tx_irq(adapter); if (status & ISR_RX_EVENT) atl1e_clean_rx_irq(adapter); } while (--max_ints > 0); /* re-enable Interrupt*/ AT_WRITE_REG(&adapter->hw, REG_ISR, 0); return; } static inline u16 atl1e_tpd_avail(struct atl1e_adapter *adapter) { struct atl1e_tx_ring *tx_ring = &adapter->tx_ring; u16 next_to_use = 0; u16 next_to_clean = 0; next_to_clean = tx_ring->next_to_clean; next_to_use = tx_ring->next_to_use; return (u16)(next_to_clean > next_to_use) ? (next_to_clean - next_to_use - 1) : (tx_ring->count + next_to_clean - next_to_use - 1); } /* * get next usable tpd * Note: should call atl1e_tdp_avail to make sure * there is enough tpd to use */ static struct atl1e_tpd_desc *atl1e_get_tpd(struct atl1e_adapter *adapter) { struct atl1e_tx_ring *tx_ring = &adapter->tx_ring; u16 next_to_use = 0; next_to_use = tx_ring->next_to_use; if (++tx_ring->next_to_use == tx_ring->count) tx_ring->next_to_use = 0; memset(&tx_ring->desc[next_to_use], 0, sizeof(struct atl1e_tpd_desc)); return (struct atl1e_tpd_desc *)&tx_ring->desc[next_to_use]; } static struct atl1e_tx_buffer * atl1e_get_tx_buffer(struct atl1e_adapter *adapter, struct atl1e_tpd_desc *tpd) { struct atl1e_tx_ring *tx_ring = &adapter->tx_ring; return &tx_ring->tx_buffer[tpd - tx_ring->desc]; } static void atl1e_tx_map(struct atl1e_adapter *adapter, struct io_buffer *iob, struct atl1e_tpd_desc *tpd) { struct atl1e_tx_buffer *tx_buffer = NULL; u16 buf_len = iob_len(iob); tx_buffer = atl1e_get_tx_buffer(adapter, tpd); tx_buffer->iob = iob; tx_buffer->length = buf_len; tx_buffer->dma = virt_to_bus(iob->data); tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); tpd->word2 = ((tpd->word2 & ~TPD_BUFLEN_MASK) | ((cpu_to_le32(buf_len) & TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT)); tpd->word3 |= 1 << TPD_EOP_SHIFT; } static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count __unused, struct atl1e_tpd_desc *tpd __unused) { struct atl1e_tx_ring *tx_ring = &adapter->tx_ring; wmb(); AT_WRITE_REG(&adapter->hw, REG_MB_TPD_PROD_IDX, tx_ring->next_to_use); } static int atl1e_xmit_frame(struct net_device *netdev, struct io_buffer *iob) { struct atl1e_adapter *adapter = netdev_priv(netdev); u16 tpd_req = 1; struct atl1e_tpd_desc *tpd; if (!netdev_link_ok(netdev)) { return -EINVAL; } if (atl1e_tpd_avail(adapter) < tpd_req) { return -EBUSY; } tpd = atl1e_get_tpd(adapter); atl1e_tx_map(adapter, iob, tpd); atl1e_tx_queue(adapter, tpd_req, tpd); return 0; } int atl1e_up(struct atl1e_adapter *adapter) { struct net_device *netdev = adapter->netdev; int err = 0; u32 val; /* hardware has been reset, we need to reload some things */ err = atl1e_init_hw(&adapter->hw); if (err) { return -EIO; } atl1e_init_ring_ptrs(adapter); memcpy(adapter->hw.mac_addr, netdev->ll_addr, ETH_ALEN); if (atl1e_configure(adapter) != 0) { return -EIO; } atl1e_irq_disable(adapter); val = AT_READ_REG(&adapter->hw, REG_MASTER_CTRL); AT_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, val | MASTER_CTRL_MANUAL_INT); return err; } void atl1e_irq(struct net_device *netdev, int enable) { struct atl1e_adapter *adapter = netdev_priv(netdev); if (enable) atl1e_irq_enable(adapter); else atl1e_irq_disable(adapter); } void atl1e_down(struct atl1e_adapter *adapter) { struct net_device *netdev = adapter->netdev; /* reset MAC to disable all RX/TX */ atl1e_reset_hw(&adapter->hw); mdelay(1); netdev_link_down(netdev); adapter->link_speed = SPEED_0; adapter->link_duplex = -1; atl1e_clean_tx_ring(adapter); atl1e_clean_rx_ring(adapter); } /* * atl1e_open - Called when a network interface is made active * @netdev: network interface device structure * * Returns 0 on success, negative value on failure * * The open entry point is called when a network interface is made * active by the system (IFF_UP). At this point all resources needed * for transmit and receive operations are allocated, the interrupt * handler is registered with the OS, the watchdog timer is started, * and the stack is notified that the interface is ready. */ static int atl1e_open(struct net_device *netdev) { struct atl1e_adapter *adapter = netdev_priv(netdev); int err; /* allocate rx/tx dma buffer & descriptors */ atl1e_init_ring_resources(adapter); err = atl1e_setup_ring_resources(adapter); if (err) return err; err = atl1e_up(adapter); if (err) goto err_up; return 0; err_up: atl1e_free_ring_resources(adapter); atl1e_reset_hw(&adapter->hw); return err; } /* * atl1e_close - Disables a network interface * @netdev: network interface device structure * * Returns 0, this is not allowed to fail * * The close entry point is called when an interface is de-activated * by the OS. The hardware is still under the drivers control, but * needs to be disabled. A global MAC reset is issued to stop the * hardware, and all transmit and receive resources are freed. */ static void atl1e_close(struct net_device *netdev) { struct atl1e_adapter *adapter = netdev_priv(netdev); atl1e_down(adapter); atl1e_free_ring_resources(adapter); } static struct net_device_operations atl1e_netdev_ops = { .open = atl1e_open, .close = atl1e_close, .transmit = atl1e_xmit_frame, .poll = atl1e_poll, .irq = atl1e_irq, }; static void atl1e_init_netdev(struct net_device *netdev, struct pci_device *pdev) { netdev_init(netdev, &atl1e_netdev_ops); netdev->dev = &pdev->dev; pci_set_drvdata(pdev, netdev); } /* * atl1e_probe - Device Initialization Routine * @pdev: PCI device information struct * @ent: entry in atl1e_pci_tbl * * Returns 0 on success, negative on failure * * atl1e_probe initializes an adapter identified by a pci_device structure. * The OS initialization, configuring of the adapter private structure, * and a hardware reset occur. */ static int atl1e_probe(struct pci_device *pdev, const struct pci_device_id *ent __unused) { struct net_device *netdev; struct atl1e_adapter *adapter = NULL; static int cards_found; int err = 0; adjust_pci_device(pdev); netdev = alloc_etherdev(sizeof(struct atl1e_adapter)); if (netdev == NULL) { err = -ENOMEM; DBG("atl1e: out of memory allocating net_device\n"); goto err; } atl1e_init_netdev(netdev, pdev); adapter = netdev_priv(netdev); adapter->bd_number = cards_found; adapter->netdev = netdev; adapter->pdev = pdev; adapter->hw.adapter = adapter; if (!pdev->membase) { err = -EIO; DBG("atl1e: cannot map device registers\n"); goto err_free_netdev; } adapter->hw.hw_addr = bus_to_virt(pdev->membase); /* init mii data */ adapter->mii.dev = netdev; adapter->mii.mdio_read = atl1e_mdio_read; adapter->mii.mdio_write = atl1e_mdio_write; adapter->mii.phy_id_mask = 0x1f; adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK; /* get user settings */ adapter->tx_ring.count = TX_DESC_COUNT; adapter->rx_ring.page_size = RX_MEM_SIZE; atl1e_setup_pcicmd(pdev); /* setup the private structure */ err = atl1e_sw_init(adapter); if (err) { DBG("atl1e: private data init failed\n"); goto err_free_netdev; } /* Init GPHY as early as possible due to power saving issue */ atl1e_phy_init(&adapter->hw); /* reset the controller to * put the device in a known good starting state */ err = atl1e_reset_hw(&adapter->hw); if (err) { err = -EIO; goto err_free_netdev; } /* This may have been run by a zero-wait timer around now... unclear. */ atl1e_restart_autoneg(&adapter->hw); if (atl1e_read_mac_addr(&adapter->hw) != 0) { DBG("atl1e: cannot read MAC address from EEPROM\n"); err = -EIO; goto err_free_netdev; } memcpy(netdev->hw_addr, adapter->hw.perm_mac_addr, ETH_ALEN); memcpy(netdev->ll_addr, adapter->hw.mac_addr, ETH_ALEN); DBG("atl1e: Attansic L1E Ethernet controller on %s, " "%02x:%02x:%02x:%02x:%02x:%02x\n", adapter->netdev->name, adapter->hw.mac_addr[0], adapter->hw.mac_addr[1], adapter->hw.mac_addr[2], adapter->hw.mac_addr[3], adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]); err = register_netdev(netdev); if (err) { DBG("atl1e: cannot register network device\n"); goto err_free_netdev; } netdev_link_down(netdev); cards_found++; return 0; err_free_netdev: netdev_nullify(netdev); netdev_put(netdev); err: return err; } /* * atl1e_remove - Device Removal Routine * @pdev: PCI device information struct * * atl1e_remove is called by the PCI subsystem to alert the driver * that it should release a PCI device. The could be caused by a * Hot-Plug event, or because the driver is going to be removed from * memory. */ static void atl1e_remove(struct pci_device *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct atl1e_adapter *adapter = netdev_priv(netdev); unregister_netdev(netdev); atl1e_free_ring_resources(adapter); atl1e_force_ps(&adapter->hw); netdev_nullify(netdev); netdev_put(netdev); } struct pci_driver atl1e_driver __pci_driver = { .ids = atl1e_pci_tbl, .id_count = (sizeof(atl1e_pci_tbl) / sizeof(atl1e_pci_tbl[0])), .probe = atl1e_probe, .remove = atl1e_remove, }; /********** Hardware-level functions: **********/ /* * check_eeprom_exist * return 0 if eeprom exist */ int atl1e_check_eeprom_exist(struct atl1e_hw *hw) { u32 value; value = AT_READ_REG(hw, REG_SPI_FLASH_CTRL); if (value & SPI_FLASH_CTRL_EN_VPD) { value &= ~SPI_FLASH_CTRL_EN_VPD; AT_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value); } value = AT_READ_REGW(hw, REG_PCIE_CAP_LIST); return ((value & 0xFF00) == 0x6C00) ? 0 : 1; } void atl1e_hw_set_mac_addr(struct atl1e_hw *hw) { u32 value; /* * 00-0B-6A-F6-00-DC * 0: 6AF600DC 1: 000B * low dword */ value = (((u32)hw->mac_addr[2]) << 24) | (((u32)hw->mac_addr[3]) << 16) | (((u32)hw->mac_addr[4]) << 8) | (((u32)hw->mac_addr[5])) ; AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value); /* hight dword */ value = (((u32)hw->mac_addr[0]) << 8) | (((u32)hw->mac_addr[1])) ; AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value); } /* * atl1e_get_permanent_address * return 0 if get valid mac address, */ static int atl1e_get_permanent_address(struct atl1e_hw *hw) { u32 addr[2]; u32 i; u32 twsi_ctrl_data; u8 eth_addr[ETH_ALEN]; /* init */ addr[0] = addr[1] = 0; if (!atl1e_check_eeprom_exist(hw)) { /* eeprom exist */ twsi_ctrl_data = AT_READ_REG(hw, REG_TWSI_CTRL); twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART; AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data); for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) { mdelay(10); twsi_ctrl_data = AT_READ_REG(hw, REG_TWSI_CTRL); if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0) break; } if (i >= AT_TWSI_EEPROM_TIMEOUT) return AT_ERR_TIMEOUT; } /* maybe MAC-address is from BIOS */ addr[0] = AT_READ_REG(hw, REG_MAC_STA_ADDR); addr[1] = AT_READ_REG(hw, REG_MAC_STA_ADDR + 4); *(u32 *) ð_addr[2] = swap32(addr[0]); *(u16 *) ð_addr[0] = swap16(*(u16 *)&addr[1]); memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN); return 0; } void atl1e_force_ps(struct atl1e_hw *hw) { AT_WRITE_REGW(hw, REG_GPHY_CTRL, GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET); } /* * Reads the adapter's MAC address from the EEPROM * * hw - Struct containing variables accessed by shared code */ int atl1e_read_mac_addr(struct atl1e_hw *hw) { int err = 0; err = atl1e_get_permanent_address(hw); if (err) return AT_ERR_EEPROM; memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr)); return 0; } /* * Reads the value from a PHY register * hw - Struct containing variables accessed by shared code * reg_addr - address of the PHY register to read */ int atl1e_read_phy_reg(struct atl1e_hw *hw, u16 reg_addr, u16 *phy_data) { u32 val; int i; val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT | MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT; AT_WRITE_REG(hw, REG_MDIO_CTRL, val); wmb(); for (i = 0; i < MDIO_WAIT_TIMES; i++) { udelay(2); val = AT_READ_REG(hw, REG_MDIO_CTRL); if (!(val & (MDIO_START | MDIO_BUSY))) break; wmb(); } if (!(val & (MDIO_START | MDIO_BUSY))) { *phy_data = (u16)val; return 0; } return AT_ERR_PHY; } /* * Writes a value to a PHY register * hw - Struct containing variables accessed by shared code * reg_addr - address of the PHY register to write * data - data to write to the PHY */ int atl1e_write_phy_reg(struct atl1e_hw *hw, u32 reg_addr, u16 phy_data) { int i; u32 val; val = ((u32)(phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT | (reg_addr&MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT | MDIO_SUP_PREAMBLE | MDIO_START | MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT; AT_WRITE_REG(hw, REG_MDIO_CTRL, val); wmb(); for (i = 0; i < MDIO_WAIT_TIMES; i++) { udelay(2); val = AT_READ_REG(hw, REG_MDIO_CTRL); if (!(val & (MDIO_START | MDIO_BUSY))) break; wmb(); } if (!(val & (MDIO_START | MDIO_BUSY))) return 0; return AT_ERR_PHY; } /* * atl1e_init_pcie - init PCIE module */ static void atl1e_init_pcie(struct atl1e_hw *hw) { u32 value; /* comment 2lines below to save more power when sususpend value = LTSSM_TEST_MODE_DEF; AT_WRITE_REG(hw, REG_LTSSM_TEST_MODE, value); */ /* pcie flow control mode change */ value = AT_READ_REG(hw, 0x1008); value |= 0x8000; AT_WRITE_REG(hw, 0x1008, value); } /* * Configures PHY autoneg and flow control advertisement settings * * hw - Struct containing variables accessed by shared code */ static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw) { s32 ret_val; u16 mii_autoneg_adv_reg; u16 mii_1000t_ctrl_reg; if (0 != hw->mii_autoneg_adv_reg) return 0; /* Read the MII Auto-Neg Advertisement Register (Address 4/9). */ mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK; mii_1000t_ctrl_reg = MII_AT001_CR_1000T_DEFAULT_CAP_MASK; /* * First we clear all the 10/100 mb speed bits in the Auto-Neg * Advertisement Register (Address 4) and the 1000 mb speed bits in * the 1000Base-T control Register (Address 9). */ mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK; mii_1000t_ctrl_reg &= ~MII_AT001_CR_1000T_SPEED_MASK; /* Assume auto-detect media type */ mii_autoneg_adv_reg |= (MII_AR_10T_HD_CAPS | MII_AR_10T_FD_CAPS | MII_AR_100TX_HD_CAPS | MII_AR_100TX_FD_CAPS); if (hw->nic_type == athr_l1e) { mii_1000t_ctrl_reg |= MII_AT001_CR_1000T_FD_CAPS; } /* flow control fixed to enable all */ mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE); hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg; hw->mii_1000t_ctrl_reg = mii_1000t_ctrl_reg; ret_val = atl1e_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg); if (ret_val) return ret_val; if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) { ret_val = atl1e_write_phy_reg(hw, MII_AT001_CR, mii_1000t_ctrl_reg); if (ret_val) return ret_val; } return 0; } /* * Resets the PHY and make all config validate * * hw - Struct containing variables accessed by shared code * * Sets bit 15 and 12 of the MII control regiser (for F001 bug) */ int atl1e_phy_commit(struct atl1e_hw *hw) { int ret_val; u16 phy_data; phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG; ret_val = atl1e_write_phy_reg(hw, MII_BMCR, phy_data); if (ret_val) { u32 val; int i; /************************************** * pcie serdes link may be down ! **************************************/ for (i = 0; i < 25; i++) { mdelay(1); val = AT_READ_REG(hw, REG_MDIO_CTRL); if (!(val & (MDIO_START | MDIO_BUSY))) break; } if (0 != (val & (MDIO_START | MDIO_BUSY))) { DBG("atl1e: PCI-E link down for at least 25ms\n"); return ret_val; } DBG("atl1e: PCI-E link up after %d ms\n", i); } return 0; } int atl1e_phy_init(struct atl1e_hw *hw) { s32 ret_val; u16 phy_val; if (hw->phy_configured) { if (hw->re_autoneg) { hw->re_autoneg = 0; return atl1e_restart_autoneg(hw); } return 0; } /* RESET GPHY Core */ AT_WRITE_REGW(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT); mdelay(2); AT_WRITE_REGW(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT | GPHY_CTRL_EXT_RESET); mdelay(2); /* patches */ /* p1. eable hibernation mode */ ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0xB); if (ret_val) return ret_val; ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0xBC00); if (ret_val) return ret_val; /* p2. set Class A/B for all modes */ ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0); if (ret_val) return ret_val; phy_val = 0x02ef; /* remove Class AB */ /* phy_val = hw->emi_ca ? 0x02ef : 0x02df; */ ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, phy_val); if (ret_val) return ret_val; /* p3. 10B ??? */ ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x12); if (ret_val) return ret_val; ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x4C04); if (ret_val) return ret_val; /* p4. 1000T power */ ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x4); if (ret_val) return ret_val; ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x8BBB); if (ret_val) return ret_val; ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x5); if (ret_val) return ret_val; ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x2C46); if (ret_val) return ret_val; mdelay(1); /*Enable PHY LinkChange Interrupt */ ret_val = atl1e_write_phy_reg(hw, MII_INT_CTRL, 0xC00); if (ret_val) { DBG("atl1e: Error enable PHY linkChange Interrupt\n"); return ret_val; } /* setup AutoNeg parameters */ ret_val = atl1e_phy_setup_autoneg_adv(hw); if (ret_val) { DBG("atl1e: Error Setting up Auto-Negotiation\n"); return ret_val; } /* SW.Reset & En-Auto-Neg to restart Auto-Neg*/ DBG("atl1e: Restarting Auto-Neg"); ret_val = atl1e_phy_commit(hw); if (ret_val) { DBG("atl1e: Error Resetting the phy"); return ret_val; } hw->phy_configured = 1; return 0; } /* * Reset the transmit and receive units; mask and clear all interrupts. * hw - Struct containing variables accessed by shared code * return : 0 or idle status (if error) */ int atl1e_reset_hw(struct atl1e_hw *hw) { struct atl1e_adapter *adapter = hw->adapter; struct pci_device *pdev = adapter->pdev; int timeout = 0; u32 idle_status_data = 0; u16 pci_cfg_cmd_word = 0; /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */ pci_read_config_word(pdev, PCI_COMMAND, &pci_cfg_cmd_word); if ((pci_cfg_cmd_word & (PCI_COMMAND_IO | PCI_COMMAND_MEM | PCI_COMMAND_MASTER)) != (PCI_COMMAND_IO | PCI_COMMAND_MEM | PCI_COMMAND_MASTER)) { pci_cfg_cmd_word |= (PCI_COMMAND_IO | PCI_COMMAND_MEM | PCI_COMMAND_MASTER); pci_write_config_word(pdev, PCI_COMMAND, pci_cfg_cmd_word); } /* * Issue Soft Reset to the MAC. This will reset the chip's * transmit, receive, DMA. It will not effect * the current PCI configuration. The global reset bit is self- * clearing, and should clear within a microsecond. */ AT_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_LED_MODE | MASTER_CTRL_SOFT_RST); wmb(); mdelay(1); /* Wait at least 10ms for All module to be Idle */ for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { idle_status_data = AT_READ_REG(hw, REG_IDLE_STATUS); if (idle_status_data == 0) break; mdelay(1); } if (timeout >= AT_HW_MAX_IDLE_DELAY) { DBG("atl1e: MAC reset timeout\n"); return AT_ERR_TIMEOUT; } return 0; } /* * Performs basic configuration of the adapter. * * hw - Struct containing variables accessed by shared code * Assumes that the controller has previously been reset and is in a * post-reset uninitialized state. Initializes multicast table, * and Calls routines to setup link * Leaves the transmit and receive units disabled and uninitialized. */ int atl1e_init_hw(struct atl1e_hw *hw) { s32 ret_val = 0; atl1e_init_pcie(hw); /* Zero out the Multicast HASH table */ /* clear the old settings from the multicast hash table */ AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0); AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); ret_val = atl1e_phy_init(hw); return ret_val; } /* * Detects the current speed and duplex settings of the hardware. * * hw - Struct containing variables accessed by shared code * speed - Speed of the connection * duplex - Duplex setting of the connection */ int atl1e_get_speed_and_duplex(struct atl1e_hw *hw, u16 *speed, u16 *duplex) { int err; u16 phy_data; /* Read PHY Specific Status Register (17) */ err = atl1e_read_phy_reg(hw, MII_AT001_PSSR, &phy_data); if (err) return err; if (!(phy_data & MII_AT001_PSSR_SPD_DPLX_RESOLVED)) return AT_ERR_PHY_RES; switch (phy_data & MII_AT001_PSSR_SPEED) { case MII_AT001_PSSR_1000MBS: *speed = SPEED_1000; break; case MII_AT001_PSSR_100MBS: *speed = SPEED_100; break; case MII_AT001_PSSR_10MBS: *speed = SPEED_10; break; default: return AT_ERR_PHY_SPEED; break; } if (phy_data & MII_AT001_PSSR_DPLX) *duplex = FULL_DUPLEX; else *duplex = HALF_DUPLEX; return 0; } int atl1e_restart_autoneg(struct atl1e_hw *hw) { int err = 0; err = atl1e_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg); if (err) return err; if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) { err = atl1e_write_phy_reg(hw, MII_AT001_CR, hw->mii_1000t_ctrl_reg); if (err) return err; } err = atl1e_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); return err; } debian/grub-extras/disabled/gpxe/src/drivers/net/3c595.h0000664000000000000000000003312012524662415020127 0ustar /* * Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. 2. The name * of the author may not be used to endorse or promote products derived from * this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * October 2, 1994 Modified by: Andres Vega Garcia INRIA - Sophia Antipolis, France e-mail: avega@sophia.inria.fr finger: avega@pax.inria.fr */ FILE_LICENCE ( BSD3 ); /* * Created from if_epreg.h by Fred Gray (fgray@rice.edu) to support the * 3c590 family. */ /* * Modified by Shusuke Nisiyama * for etherboot * Mar. 14, 2000 */ /* * Ethernet software status per interface. */ /* * Some global constants */ #define TX_INIT_RATE 16 #define TX_INIT_MAX_RATE 64 #define RX_INIT_LATENCY 64 #define RX_INIT_EARLY_THRESH 64 #define MIN_RX_EARLY_THRESHF 16 /* not less than ether_header */ #define MIN_RX_EARLY_THRESHL 4 #define EEPROMSIZE 0x40 #define MAX_EEPROMBUSY 1000 #define VX_LAST_TAG 0xd7 #define VX_MAX_BOARDS 16 #define VX_ID_PORT 0x100 /* * some macros to acces long named fields */ #define BASE (eth_nic_base) /* * Commands to read/write EEPROM trough EEPROM command register (Window 0, * Offset 0xa) */ #define EEPROM_CMD_RD 0x0080 /* Read: Address required (5 bits) */ #define EEPROM_CMD_WR 0x0040 /* Write: Address required (5 bits) */ #define EEPROM_CMD_ERASE 0x00c0 /* Erase: Address required (5 bits) */ #define EEPROM_CMD_EWEN 0x0030 /* Erase/Write Enable: No data required */ #define EEPROM_BUSY (1<<15) /* * Some short functions, worth to let them be a macro */ /************************************************************************** * * * These define the EEPROM data structure. They are used in the probe * function to verify the existence of the adapter after having sent * the ID_Sequence. * * There are others but only the ones we use are defined here. * **************************************************************************/ #define EEPROM_NODE_ADDR_0 0x0 /* Word */ #define EEPROM_NODE_ADDR_1 0x1 /* Word */ #define EEPROM_NODE_ADDR_2 0x2 /* Word */ #define EEPROM_PROD_ID 0x3 /* 0x9[0-f]50 */ #define EEPROM_MFG_ID 0x7 /* 0x6d50 */ #define EEPROM_ADDR_CFG 0x8 /* Base addr */ #define EEPROM_RESOURCE_CFG 0x9 /* IRQ. Bits 12-15 */ #define EEPROM_OEM_ADDR_0 0xa /* Word */ #define EEPROM_OEM_ADDR_1 0xb /* Word */ #define EEPROM_OEM_ADDR_2 0xc /* Word */ #define EEPROM_SOFT_INFO_2 0xf /* Software information 2 */ #define NO_RX_OVN_ANOMALY (1<<5) /************************************************************************** * * * These are the registers for the 3Com 3c509 and their bit patterns when * * applicable. They have been taken out the the "EtherLink III Parallel * * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual * * from 3com. * * * **************************************************************************/ #define VX_COMMAND 0x0e /* Write. BASE+0x0e is always a * command reg. */ #define VX_STATUS 0x0e /* Read. BASE+0x0e is always status * reg. */ #define VX_WINDOW 0x0f /* Read. BASE+0x0f is always window * reg. */ /* * Window 0 registers. Setup. */ /* Write */ #define VX_W0_EEPROM_DATA 0x0c #define VX_W0_EEPROM_COMMAND 0x0a #define VX_W0_RESOURCE_CFG 0x08 #define VX_W0_ADDRESS_CFG 0x06 #define VX_W0_CONFIG_CTRL 0x04 /* Read */ #define VX_W0_PRODUCT_ID 0x02 #define VX_W0_MFG_ID 0x00 /* * Window 1 registers. Operating Set. */ /* Write */ #define VX_W1_TX_PIO_WR_2 0x02 #define VX_W1_TX_PIO_WR_1 0x00 /* Read */ #define VX_W1_FREE_TX 0x0c #define VX_W1_TX_STATUS 0x0b /* byte */ #define VX_W1_TIMER 0x0a /* byte */ #define VX_W1_RX_STATUS 0x08 #define VX_W1_RX_PIO_RD_2 0x02 #define VX_W1_RX_PIO_RD_1 0x00 /* * Window 2 registers. Station Address Setup/Read */ /* Read/Write */ #define VX_W2_ADDR_5 0x05 #define VX_W2_ADDR_4 0x04 #define VX_W2_ADDR_3 0x03 #define VX_W2_ADDR_2 0x02 #define VX_W2_ADDR_1 0x01 #define VX_W2_ADDR_0 0x00 /* * Window 3 registers. FIFO Management. */ /* Read */ #define VX_W3_INTERNAL_CFG 0x00 #define VX_W3_RESET_OPT 0x08 #define VX_W3_FREE_TX 0x0c #define VX_W3_FREE_RX 0x0a /* * Window 4 registers. Diagnostics. */ /* Read/Write */ #define VX_W4_MEDIA_TYPE 0x0a #define VX_W4_CTRLR_STATUS 0x08 #define VX_W4_NET_DIAG 0x06 #define VX_W4_FIFO_DIAG 0x04 #define VX_W4_HOST_DIAG 0x02 #define VX_W4_TX_DIAG 0x00 /* * Window 5 Registers. Results and Internal status. */ /* Read */ #define VX_W5_READ_0_MASK 0x0c #define VX_W5_INTR_MASK 0x0a #define VX_W5_RX_FILTER 0x08 #define VX_W5_RX_EARLY_THRESH 0x06 #define VX_W5_TX_AVAIL_THRESH 0x02 #define VX_W5_TX_START_THRESH 0x00 /* * Window 6 registers. Statistics. */ /* Read/Write */ #define TX_TOTAL_OK 0x0c #define RX_TOTAL_OK 0x0a #define TX_DEFERRALS 0x08 #define RX_FRAMES_OK 0x07 #define TX_FRAMES_OK 0x06 #define RX_OVERRUNS 0x05 #define TX_COLLISIONS 0x04 #define TX_AFTER_1_COLLISION 0x03 #define TX_AFTER_X_COLLISIONS 0x02 #define TX_NO_SQE 0x01 #define TX_CD_LOST 0x00 /**************************************** * * Register definitions. * ****************************************/ /* * Command register. All windows. * * 16 bit register. * 15-11: 5-bit code for command to be executed. * 10-0: 11-bit arg if any. For commands with no args; * this can be set to anything. */ #define GLOBAL_RESET (unsigned short) 0x0000 /* Wait at least 1ms * after issuing */ #define WINDOW_SELECT (unsigned short) (0x1<<11) #define START_TRANSCEIVER (unsigned short) (0x2<<11) /* Read ADDR_CFG reg to * determine whether * this is needed. If * so; wait 800 uSec * before using trans- * ceiver. */ #define RX_DISABLE (unsigned short) (0x3<<11) /* state disabled on * power-up */ #define RX_ENABLE (unsigned short) (0x4<<11) #define RX_RESET (unsigned short) (0x5<<11) #define RX_DISCARD_TOP_PACK (unsigned short) (0x8<<11) #define TX_ENABLE (unsigned short) (0x9<<11) #define TX_DISABLE (unsigned short) (0xa<<11) #define TX_RESET (unsigned short) (0xb<<11) #define REQ_INTR (unsigned short) (0xc<<11) /* * The following C_* acknowledge the various interrupts. Some of them don't * do anything. See the manual. */ #define ACK_INTR (unsigned short) (0x6800) # define C_INTR_LATCH (unsigned short) (ACK_INTR|0x1) # define C_CARD_FAILURE (unsigned short) (ACK_INTR|0x2) # define C_TX_COMPLETE (unsigned short) (ACK_INTR|0x4) # define C_TX_AVAIL (unsigned short) (ACK_INTR|0x8) # define C_RX_COMPLETE (unsigned short) (ACK_INTR|0x10) # define C_RX_EARLY (unsigned short) (ACK_INTR|0x20) # define C_INT_RQD (unsigned short) (ACK_INTR|0x40) # define C_UPD_STATS (unsigned short) (ACK_INTR|0x80) #define SET_INTR_MASK (unsigned short) (0xe<<11) #define SET_RD_0_MASK (unsigned short) (0xf<<11) #define SET_RX_FILTER (unsigned short) (0x10<<11) # define FIL_INDIVIDUAL (unsigned short) (0x1) # define FIL_MULTICAST (unsigned short) (0x02) # define FIL_BRDCST (unsigned short) (0x04) # define FIL_PROMISC (unsigned short) (0x08) #define SET_RX_EARLY_THRESH (unsigned short) (0x11<<11) #define SET_TX_AVAIL_THRESH (unsigned short) (0x12<<11) #define SET_TX_START_THRESH (unsigned short) (0x13<<11) #define STATS_ENABLE (unsigned short) (0x15<<11) #define STATS_DISABLE (unsigned short) (0x16<<11) #define STOP_TRANSCEIVER (unsigned short) (0x17<<11) /* * Status register. All windows. * * 15-13: Window number(0-7). * 12: Command_in_progress. * 11: reserved. * 10: reserved. * 9: reserved. * 8: reserved. * 7: Update Statistics. * 6: Interrupt Requested. * 5: RX Early. * 4: RX Complete. * 3: TX Available. * 2: TX Complete. * 1: Adapter Failure. * 0: Interrupt Latch. */ #define S_INTR_LATCH (unsigned short) (0x1) #define S_CARD_FAILURE (unsigned short) (0x2) #define S_TX_COMPLETE (unsigned short) (0x4) #define S_TX_AVAIL (unsigned short) (0x8) #define S_RX_COMPLETE (unsigned short) (0x10) #define S_RX_EARLY (unsigned short) (0x20) #define S_INT_RQD (unsigned short) (0x40) #define S_UPD_STATS (unsigned short) (0x80) #define S_COMMAND_IN_PROGRESS (unsigned short) (0x1000) #define VX_BUSY_WAIT while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS) /* Address Config. Register. * Window 0/Port 06 */ #define ACF_CONNECTOR_BITS 14 #define ACF_CONNECTOR_UTP 0 #define ACF_CONNECTOR_AUI 1 #define ACF_CONNECTOR_BNC 3 #define INTERNAL_CONNECTOR_BITS 20 #define INTERNAL_CONNECTOR_MASK 0x01700000 /* * FIFO Registers. RX Status. * * 15: Incomplete or FIFO empty. * 14: 1: Error in RX Packet 0: Incomplete or no error. * 13-11: Type of error. * 1000 = Overrun. * 1011 = Run Packet Error. * 1100 = Alignment Error. * 1101 = CRC Error. * 1001 = Oversize Packet Error (>1514 bytes) * 0010 = Dribble Bits. * (all other error codes, no errors.) * * 10-0: RX Bytes (0-1514) */ #define ERR_INCOMPLETE (unsigned short) (0x8000) #define ERR_RX (unsigned short) (0x4000) #define ERR_MASK (unsigned short) (0x7800) #define ERR_OVERRUN (unsigned short) (0x4000) #define ERR_RUNT (unsigned short) (0x5800) #define ERR_ALIGNMENT (unsigned short) (0x6000) #define ERR_CRC (unsigned short) (0x6800) #define ERR_OVERSIZE (unsigned short) (0x4800) #define ERR_DRIBBLE (unsigned short) (0x1000) /* * TX Status. * * Reports the transmit status of a completed transmission. Writing this * register pops the transmit completion stack. * * Window 1/Port 0x0b. * * 7: Complete * 6: Interrupt on successful transmission requested. * 5: Jabber Error (TP Only, TX Reset required. ) * 4: Underrun (TX Reset required. ) * 3: Maximum Collisions. * 2: TX Status Overflow. * 1-0: Undefined. * */ #define TXS_COMPLETE 0x80 #define TXS_INTR_REQ 0x40 #define TXS_JABBER 0x20 #define TXS_UNDERRUN 0x10 #define TXS_MAX_COLLISION 0x8 #define TXS_STATUS_OVERFLOW 0x4 #define RS_AUI (1<<5) #define RS_BNC (1<<4) #define RS_UTP (1<<3) #define RS_T4 (1<<0) #define RS_TX (1<<1) #define RS_FX (1<<2) #define RS_MII (1<<6) /* * FIFO Status (Window 4) * * Supports FIFO diagnostics * * Window 4/Port 0x04.1 * * 15: 1=RX receiving (RO). Set when a packet is being received * into the RX FIFO. * 14: Reserved * 13: 1=RX underrun (RO). Generates Adapter Failure interrupt. * Requires RX Reset or Global Reset command to recover. * It is generated when you read past the end of a packet - * reading past what has been received so far will give bad * data. * 12: 1=RX status overrun (RO). Set when there are already 8 * packets in the RX FIFO. While this bit is set, no additional * packets are received. Requires no action on the part of * the host. The condition is cleared once a packet has been * read out of the RX FIFO. * 11: 1=RX overrun (RO). Set when the RX FIFO is full (there * may not be an overrun packet yet). While this bit is set, * no additional packets will be received (some additional * bytes can still be pending between the wire and the RX * FIFO). Requires no action on the part of the host. The * condition is cleared once a few bytes have been read out * from the RX FIFO. * 10: 1=TX overrun (RO). Generates adapter failure interrupt. * Requires TX Reset or Global Reset command to recover. * Disables Transmitter. * 9-8: Unassigned. * 7-0: Built in self test bits for the RX and TX FIFO's. */ #define FIFOS_RX_RECEIVING (unsigned short) 0x8000 #define FIFOS_RX_UNDERRUN (unsigned short) 0x2000 #define FIFOS_RX_STATUS_OVERRUN (unsigned short) 0x1000 #define FIFOS_RX_OVERRUN (unsigned short) 0x0800 #define FIFOS_TX_OVERRUN (unsigned short) 0x0400 /* * Misc defines for various things. */ #define TAG_ADAPTER 0xd0 #define ACTIVATE_ADAPTER_TO_CONFIG 0xff #define ENABLE_DRQ_IRQ 0x0001 #define MFG_ID 0x506d /* `TCM' */ #define PROD_ID 0x5090 #define GO_WINDOW(x) outw(WINDOW_SELECT|(x),BASE+VX_COMMAND) #define JABBER_GUARD_ENABLE 0x40 #define LINKBEAT_ENABLE 0x80 #define ENABLE_UTP (JABBER_GUARD_ENABLE | LINKBEAT_ENABLE) #define DISABLE_UTP 0x0 #define RX_BYTES_MASK (unsigned short) (0x07ff) #define RX_ERROR 0x4000 #define RX_INCOMPLETE 0x8000 #define TX_INDICATE 1<<15 #define is_eeprom_busy(b) (inw((b)+VX_W0_EEPROM_COMMAND)&EEPROM_BUSY) #define VX_IOSIZE 0x20 #define VX_CONNECTORS 8 /* * Local variables: * c-basic-offset: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/3c90x.h0000664000000000000000000002625512524662415020240 0ustar /* * 3c90x.c -- This file implements the 3c90x driver for etherboot. Written * by Greg Beeley, Greg.Beeley@LightSys.org. Modified by Steve Smith, * Steve.Smith@Juno.Com. Alignment bug fix Neil Newell (nn@icenoir.net). * * Port from etherboot to gPXE API, implementation of tx/rx ring support * by Thomas Miletich, thomas.miletich@gmail.com * Thanks to Marty Connor and Stefan Hajnoczi for their help and feedback. * * This program Copyright (C) 1999 LightSys Technology Services, Inc. * Portions Copyright (C) 1999 Steve Smith * * This program may be re-distributed in source or binary form, modified, * sold, or copied for any purpose, provided that the above copyright message * and this text are included with all source copies or derivative works, and * provided that the above copyright message and this text are included in the * documentation of any binary-only distributions. This program is distributed * WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR A PARTICULAR * PURPOSE or MERCHANTABILITY. Please read the associated documentation * "3c90x.txt" before compiling and using this driver. * * -------- * * Program written with the assistance of the 3com documentation for * the 3c905B-TX card, as well as with some assistance from the 3c59x * driver Donald Becker wrote for the Linux kernel, and with some assistance * from the remainder of the Etherboot distribution. * * REVISION HISTORY: * * v0.10 1-26-1998 GRB Initial implementation. * v0.90 1-27-1998 GRB System works. * v1.00pre1 2-11-1998 GRB Got prom boot issue fixed. * v2.0 9-24-1999 SCS Modified for 3c905 (from 3c905b code) * Re-wrote poll and transmit for * better error recovery and heavy * network traffic operation * v2.01 5-26-2003 NN Fixed driver alignment issue which * caused system lockups if driver structures * not 8-byte aligned. * v2.02 11-28-2007 GSt Got polling working again by replacing * "for(i=0;i<40000;i++);" with "mdelay(1);" * * * indent options: indent -kr -i8 3c90x.c */ FILE_LICENCE ( BSD2 ); #ifndef __3C90X_H_ #define __3C90X_H_ static struct net_device_operations a3c90x_operations; #define XCVR_MAGIC (0x5A00) /* Register definitions for the 3c905 */ enum Registers { regPowerMgmtCtrl_w = 0x7c, /* 905B Revision Only */ regUpMaxBurst_w = 0x7a, /* 905B Revision Only */ regDnMaxBurst_w = 0x78, /* 905B Revision Only */ regDebugControl_w = 0x74, /* 905B Revision Only */ regDebugData_l = 0x70, /* 905B Revision Only */ regRealTimeCnt_l = 0x40, /* Universal */ regUpBurstThresh_b = 0x3e, /* 905B Revision Only */ regUpPoll_b = 0x3d, /* 905B Revision Only */ regUpPriorityThresh_b = 0x3c, /* 905B Revision Only */ regUpListPtr_l = 0x38, /* Universal */ regCountdown_w = 0x36, /* Universal */ regFreeTimer_w = 0x34, /* Universal */ regUpPktStatus_l = 0x30, /* Universal with Exception, pg 130 */ regTxFreeThresh_b = 0x2f, /* 90X Revision Only */ regDnPoll_b = 0x2d, /* 905B Revision Only */ regDnPriorityThresh_b = 0x2c, /* 905B Revision Only */ regDnBurstThresh_b = 0x2a, /* 905B Revision Only */ regDnListPtr_l = 0x24, /* Universal with Exception, pg 107 */ regDmaCtrl_l = 0x20, /* Universal with Exception, pg 106 */ /* */ regIntStatusAuto_w = 0x1e, /* 905B Revision Only */ regTxStatus_b = 0x1b, /* Universal with Exception, pg 113 */ regTimer_b = 0x1a, /* Universal */ regTxPktId_b = 0x18, /* 905B Revision Only */ regCommandIntStatus_w = 0x0e, /* Universal (Command Variations) */ }; /* following are windowed registers */ enum Registers7 { regPowerMgmtEvent_7_w = 0x0c, /* 905B Revision Only */ regVlanEtherType_7_w = 0x04, /* 905B Revision Only */ regVlanMask_7_w = 0x00, /* 905B Revision Only */ }; enum Registers6 { regBytesXmittedOk_6_w = 0x0c, /* Universal */ regBytesRcvdOk_6_w = 0x0a, /* Universal */ regUpperFramesOk_6_b = 0x09, /* Universal */ regFramesDeferred_6_b = 0x08, /* Universal */ regFramesRecdOk_6_b = 0x07, /* Universal with Exceptions, pg 142 */ regFramesXmittedOk_6_b = 0x06, /* Universal */ regRxOverruns_6_b = 0x05, /* Universal */ regLateCollisions_6_b = 0x04, /* Universal */ regSingleCollisions_6_b = 0x03, /* Universal */ regMultipleCollisions_6_b = 0x02, /* Universal */ regSqeErrors_6_b = 0x01, /* Universal */ regCarrierLost_6_b = 0x00, /* Universal */ }; enum Registers5 { regIndicationEnable_5_w = 0x0c, /* Universal */ regInterruptEnable_5_w = 0x0a, /* Universal */ regTxReclaimThresh_5_b = 0x09, /* 905B Revision Only */ regRxFilter_5_b = 0x08, /* Universal */ regRxEarlyThresh_5_w = 0x06, /* Universal */ regTxStartThresh_5_w = 0x00, /* Universal */ }; enum Registers4 { regUpperBytesOk_4_b = 0x0d, /* Universal */ regBadSSD_4_b = 0x0c, /* Universal */ regMediaStatus_4_w = 0x0a, /* Universal with Exceptions, pg 201 */ regPhysicalMgmt_4_w = 0x08, /* Universal */ regNetworkDiagnostic_4_w = 0x06, /* Universal with Exceptions, pg 203 */ regFifoDiagnostic_4_w = 0x04, /* Universal with Exceptions, pg 196 */ regVcoDiagnostic_4_w = 0x02, /* Undocumented? */ }; enum Registers3 { regTxFree_3_w = 0x0c, /* Universal */ regRxFree_3_w = 0x0a, /* Universal with Exceptions, pg 125 */ regResetMediaOptions_3_w = 0x08, /* Media Options on B Revision, */ /* Reset Options on Non-B Revision */ regMacControl_3_w = 0x06, /* Universal with Exceptions, pg 199 */ regMaxPktSize_3_w = 0x04, /* 905B Revision Only */ regInternalConfig_3_l = 0x00, /* Universal, different bit */ /* definitions, pg 59 */ }; enum Registers2 { regResetOptions_2_w = 0x0c, /* 905B Revision Only */ regStationMask_2_3w = 0x06, /* Universal with Exceptions, pg 127 */ regStationAddress_2_3w = 0x00, /* Universal with Exceptions, pg 127 */ }; enum Registers1 { regRxStatus_1_w = 0x0a, /* 90X Revision Only, Pg 126 */ }; enum Registers0 { regEepromData_0_w = 0x0c, /* Universal */ regEepromCommand_0_w = 0x0a, /* Universal */ regBiosRomData_0_b = 0x08, /* 905B Revision Only */ regBiosRomAddr_0_l = 0x04, /* 905B Revision Only */ }; /* The names for the eight register windows */ enum Windows { winNone = 0xff, winPowerVlan7 = 0x07, winStatistics6 = 0x06, winTxRxControl5 = 0x05, winDiagnostics4 = 0x04, winTxRxOptions3 = 0x03, winAddressing2 = 0x02, winUnused1 = 0x01, winEepromBios0 = 0x00, }; /* Command definitions for the 3c90X */ enum Commands { cmdGlobalReset = 0x00, /* Universal with Exceptions, pg 151 */ cmdSelectRegisterWindow = 0x01, /* Universal */ cmdEnableDcConverter = 0x02, /* */ cmdRxDisable = 0x03, /* */ cmdRxEnable = 0x04, /* Universal */ cmdRxReset = 0x05, /* Universal */ cmdStallCtl = 0x06, /* Universal */ cmdTxEnable = 0x09, /* Universal */ cmdTxDisable = 0x0A, /* */ cmdTxReset = 0x0B, /* Universal */ cmdRequestInterrupt = 0x0C, /* */ cmdAcknowledgeInterrupt = 0x0D, /* Universal */ cmdSetInterruptEnable = 0x0E, /* Universal */ cmdSetIndicationEnable = 0x0F, /* Universal */ cmdSetRxFilter = 0x10, /* Universal */ cmdSetRxEarlyThresh = 0x11, /* */ cmdSetTxStartThresh = 0x13, /* */ cmdStatisticsEnable = 0x15, /* */ cmdStatisticsDisable = 0x16, /* */ cmdDisableDcConverter = 0x17, /* */ cmdSetTxReclaimThresh = 0x18, /* */ cmdSetHashFilterBit = 0x19, /* */ }; enum FrameStartHeader { fshTxIndicate = 0x8000, fshDnComplete = 0x10000, }; enum UpDownDesc { upLastFrag = (1 << 31), downLastFrag = (1 << 31), }; enum UpPktStatus { upComplete = (1 << 15), upError = (1 << 14), }; enum Stalls { upStall = 0x00, upUnStall = 0x01, dnStall = 0x02, dnUnStall = 0x03, }; enum Resources { resRxRing = 0x00, resTxRing = 0x02, resRxIOBuf = 0x04 }; enum eeprom { eepromBusy = (1 << 15), eepromRead = ((0x02) << 6), eepromRead_556 = 0x230, eepromHwAddrOffset = 0x0a, }; /* Bit 4 is only used in revison B and upwards */ enum linktype { link10BaseT = 0x00, linkAUI = 0x01, link10Base2 = 0x03, link100BaseFX = 0x05, linkMII = 0x06, linkAutoneg = 0x08, linkExternalMII = 0x09, }; /* Values for int status register bitmask */ #define INT_INTERRUPTLATCH (1<<0) #define INT_HOSTERROR (1<<1) #define INT_TXCOMPLETE (1<<2) #define INT_RXCOMPLETE (1<<4) #define INT_RXEARLY (1<<5) #define INT_INTREQUESTED (1<<6) #define INT_UPDATESTATS (1<<7) #define INT_LINKEVENT (1<<8) #define INT_DNCOMPLETE (1<<9) #define INT_UPCOMPLETE (1<<10) #define INT_CMDINPROGRESS (1<<12) #define INT_WINDOWNUMBER (7<<13) /* Buffer sizes */ #define TX_RING_SIZE 8 #define RX_RING_SIZE 8 #define TX_RING_ALIGN 16 #define RX_RING_ALIGN 16 #define RX_BUF_SIZE 1536 /* Timeouts for eeprom and command completion */ /* Timeout 1 second, to be save */ #define EEPROM_TIMEOUT 1 * 1000 * 1000 /* TX descriptor */ struct TXD { volatile unsigned int DnNextPtr; volatile unsigned int FrameStartHeader; volatile unsigned int DataAddr; volatile unsigned int DataLength; } __attribute__ ((aligned(8))); /* 64-bit aligned for bus mastering */ /* RX descriptor */ struct RXD { volatile unsigned int UpNextPtr; volatile unsigned int UpPktStatus; volatile unsigned int DataAddr; volatile unsigned int DataLength; } __attribute__ ((aligned(8))); /* 64-bit aligned for bus mastering */ /* Private NIC dats */ struct INF_3C90X { unsigned int is3c556; unsigned char isBrev; unsigned char CurrentWindow; unsigned int IOAddr; unsigned short eeprom[0x21]; unsigned int tx_cur; /* current entry in tx_ring */ unsigned int tx_cnt; /* current number of used tx descriptors */ unsigned int tx_tail; /* entry of last finished packet */ unsigned int rx_cur; struct TXD *tx_ring; struct RXD *rx_ring; struct io_buffer *tx_iobuf[TX_RING_SIZE]; struct io_buffer *rx_iobuf[RX_RING_SIZE]; struct nvs_device nvs; }; #endif debian/grub-extras/disabled/gpxe/src/drivers/net/prism2_pci.c0000664000000000000000000000305312524662415021423 0ustar /************************************************************************** Etherboot - BOOTP/TFTP Bootstrap Program Prism2 NIC driver for Etherboot Wrapper for prism2_pci Written by Michael Brown of Fen Systems Ltd $Id$ ***************************************************************************/ /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #define WLAN_HOSTIF WLAN_PCI #include "prism2.c" static int prism2_pci_probe ( struct nic *nic, struct pci_device *pci ) { hfa384x_t *hw = &hw_global; printf ( "Prism2.5 has registers at %#lx\n", pci->membase ); hw->membase = ioremap ( pci->membase, 0x100 ); nic->ioaddr = pci->membase; nic->irqno = 0; return prism2_probe ( nic, hw ); } static void prism2_pci_disable ( struct nic *nic ) { prism2_disable ( nic ); } static struct pci_device_id prism2_pci_nics[] = { PCI_ROM(0x1260, 0x3873, "prism2_pci", "Harris Semiconductor Prism2.5 clone", 0), PCI_ROM(0x1260, 0x3873, "hwp01170", "ActionTec HWP01170", 0), PCI_ROM(0x1260, 0x3873, "dwl520", "DLink DWL-520", 0), }; PCI_DRIVER ( prism2_pci_driver, prism2_pci_nics, PCI_NO_CLASS ); DRIVER ( "Prism2/PCI", nic_driver, pci_driver, prism2_pci_driver, prism2_pci_probe, prism2_pci_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/3c529.c0000664000000000000000000000312512524662415020121 0ustar /* * Split out from 3c509.c to make build process more sane * */ FILE_LICENCE ( BSD2 ); #include "etherboot.h" #include #include /* for ISA_ROM */ #include "nic.h" #include "3c509.h" /* * Several other pieces of the MCA support code were shamelessly * borrowed from the Linux kernel source. * * MCA support added by Adam Fritzler (mid@auk.cx) * * Generalised out of the 3c529 driver and into a bus type by Michael * Brown * */ static int t529_probe ( struct nic *nic, struct mca_device *mca ) { /* Retrieve NIC parameters from MCA device parameters */ nic->ioaddr = ( ( mca->pos[4] & 0xfc ) | 0x02 ) << 8; nic->irqno = mca->pos[5] & 0x0f; printf ( "3c529 board found on MCA at %#hx IRQ %d -", nic->ioaddr, nic->irqno ); /* Hand off to generic t5x9 probe routine */ return t5x9_probe ( nic, MCA_ID ( mca ), 0xffff ); } static void t529_disable ( struct nic *nic, struct mca_device *mca __unused ) { t5x9_disable ( nic ); } static struct mca_device_id el3_mca_adapters[] = { { "3Com 3c529 EtherLink III (10base2)", 0x627c }, { "3Com 3c529 EtherLink III (10baseT)", 0x627d }, { "3Com 3c529 EtherLink III (test mode)", 0x62db }, { "3Com 3c529 EtherLink III (TP or coax)", 0x62f6 }, { "3Com 3c529 EtherLink III (TP)", 0x62f7 }, }; MCA_DRIVER ( t529_driver, el3_mca_adapters ); DRIVER ( "3c529", nic_driver, mca_driver, t529_driver, t529_probe, t529_disable ); ISA_ROM( "3c529", "3c529 == MCA 3c509" ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/dmfe.c0000664000000000000000000007707712524662415020310 0ustar /************************************************************************** * * dmfe.c -- Etherboot device driver for the Davicom * DM9102/DM9102A/DM9102A+DM9801/DM9102A+DM9802 NIC fast ethernet card * * Written 2003-2003 by Timothy Legge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Portions of this code based on: * * dmfe.c: A Davicom DM9102/DM9102A/DM9102A+DM9801/DM9102A+DM9802 * NIC fast ethernet driver for Linux. * Copyright (C) 1997 Sten Wang * (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved. * * * REVISION HISTORY: * ================ * v1.0 10-02-2004 timlegge Boots ltsp needs cleanup * * Indent Options: indent -kr -i8 * * ***************************************************************************/ FILE_LICENCE ( GPL2_OR_LATER ); /* to get some global routines like printf */ #include "etherboot.h" /* to get the interface to the body of the program */ #include "nic.h" /* to get the PCI support functions, if this is a PCI NIC */ #include #include /* #define EDEBUG 1 */ #ifdef EDEBUG #define dprintf(x) printf x #else #define dprintf(x) #endif /* Condensed operations for readability. */ #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) /* Board/System/Debug information/definition ---------------- */ #define PCI_DM9132_ID 0x91321282 /* Davicom DM9132 ID */ #define PCI_DM9102_ID 0x91021282 /* Davicom DM9102 ID */ #define PCI_DM9100_ID 0x91001282 /* Davicom DM9100 ID */ #define PCI_DM9009_ID 0x90091282 /* Davicom DM9009 ID */ #define DM9102_IO_SIZE 0x80 #define DM9102A_IO_SIZE 0x100 #define TX_MAX_SEND_CNT 0x1 /* Maximum tx packet per time */ #define TX_DESC_CNT 0x10 /* Allocated Tx descriptors */ #define RX_DESC_CNT 0x20 /* Allocated Rx descriptors */ #define TX_FREE_DESC_CNT (TX_DESC_CNT - 2) /* Max TX packet count */ #define TX_WAKE_DESC_CNT (TX_DESC_CNT - 3) /* TX wakeup count */ #define DESC_ALL_CNT (TX_DESC_CNT + RX_DESC_CNT) #define TX_BUF_ALLOC 0x600 #define RX_ALLOC_SIZE 0x620 #define DM910X_RESET 1 #define CR0_DEFAULT 0x00E00000 /* TX & RX burst mode */ #define CR6_DEFAULT 0x00080000 /* HD */ #define CR7_DEFAULT 0x180c1 #define CR15_DEFAULT 0x06 /* TxJabber RxWatchdog */ #define TDES0_ERR_MASK 0x4302 /* TXJT, LC, EC, FUE */ #define MAX_PACKET_SIZE 1514 #define DMFE_MAX_MULTICAST 14 #define RX_COPY_SIZE 100 #define MAX_CHECK_PACKET 0x8000 #define DM9801_NOISE_FLOOR 8 #define DM9802_NOISE_FLOOR 5 #define DMFE_10MHF 0 #define DMFE_100MHF 1 #define DMFE_10MFD 4 #define DMFE_100MFD 5 #define DMFE_AUTO 8 #define DMFE_1M_HPNA 0x10 #define DMFE_TXTH_72 0x400000 /* TX TH 72 byte */ #define DMFE_TXTH_96 0x404000 /* TX TH 96 byte */ #define DMFE_TXTH_128 0x0000 /* TX TH 128 byte */ #define DMFE_TXTH_256 0x4000 /* TX TH 256 byte */ #define DMFE_TXTH_512 0x8000 /* TX TH 512 byte */ #define DMFE_TXTH_1K 0xC000 /* TX TH 1K byte */ #define DMFE_TIMER_WUT (jiffies + HZ * 1) /* timer wakeup time : 1 second */ #define DMFE_TX_TIMEOUT ((3*HZ)/2) /* tx packet time-out time 1.5 s" */ #define DMFE_TX_KICK (HZ/2) /* tx packet Kick-out time 0.5 s" */ #define DMFE_DBUG(dbug_now, msg, value) if (dmfe_debug || (dbug_now)) printk(KERN_ERR DRV_NAME ": %s %lx\n", (msg), (long) (value)) #define SHOW_MEDIA_TYPE(mode) printk(KERN_ERR DRV_NAME ": Change Speed to %sMhz %s duplex\n",mode & 1 ?"100":"10", mode & 4 ? "full":"half"); /* CR9 definition: SROM/MII */ #define CR9_SROM_READ 0x4800 #define CR9_SRCS 0x1 #define CR9_SRCLK 0x2 #define CR9_CRDOUT 0x8 #define SROM_DATA_0 0x0 #define SROM_DATA_1 0x4 #define PHY_DATA_1 0x20000 #define PHY_DATA_0 0x00000 #define MDCLKH 0x10000 #define PHY_POWER_DOWN 0x800 #define SROM_V41_CODE 0x14 #define SROM_CLK_WRITE(data, ioaddr) outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5); #define __CHK_IO_SIZE(pci_id, dev_rev) ( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x02000030) ) ? DM9102A_IO_SIZE: DM9102_IO_SIZE #define CHK_IO_SIZE(pci_dev, dev_rev) __CHK_IO_SIZE(((pci_dev)->device << 16) | (pci_dev)->vendor, dev_rev) /* Sten Check */ #define DEVICE net_device /* Structure/enum declaration ------------------------------- */ struct tx_desc { u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */ void * tx_buf_ptr; /* Data for us */ struct tx_desc * next_tx_desc; } __attribute__ ((aligned(32))); struct rx_desc { u32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */ void * rx_skb_ptr; /* Data for us */ struct rx_desc * next_rx_desc; } __attribute__ ((aligned(32))); static struct dmfe_private { u32 chip_id; /* Chip vendor/Device ID */ u32 chip_revision; /* Chip revision */ u32 cr0_data; // u32 cr5_data; u32 cr6_data; u32 cr7_data; u32 cr15_data; u16 HPNA_command; /* For HPNA register 16 */ u16 HPNA_timer; /* For HPNA remote device check */ u16 NIC_capability; /* NIC media capability */ u16 PHY_reg4; /* Saved Phyxcer register 4 value */ u8 HPNA_present; /* 0:none, 1:DM9801, 2:DM9802 */ u8 chip_type; /* Keep DM9102A chip type */ u8 media_mode; /* user specify media mode */ u8 op_mode; /* real work media mode */ u8 phy_addr; u8 dm910x_chk_mode; /* Operating mode check */ /* NIC SROM data */ unsigned char srom[128]; /* Etherboot Only */ u8 cur_tx; u8 cur_rx; } dfx; static struct dmfe_private *db; enum dmfe_offsets { DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20, DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48, DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 = 0x70, DCR15 = 0x78 }; enum dmfe_CR6_bits { CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80, CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000, CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000 }; /* Global variable declaration ----------------------------- */ static struct nic_operations dmfe_operations; static unsigned char dmfe_media_mode = DMFE_AUTO; static u32 dmfe_cr6_user_set; /* For module input parameter */ static u8 chkmode = 1; static u8 HPNA_mode; /* Default: Low Power/High Speed */ static u8 HPNA_rx_cmd; /* Default: Disable Rx remote command */ static u8 HPNA_tx_cmd; /* Default: Don't issue remote command */ static u8 HPNA_NoiseFloor; /* Default: HPNA NoiseFloor */ static u8 SF_mode; /* Special Function: 1:VLAN, 2:RX Flow Control 4: TX pause packet */ /********************************************** * Descriptor Ring and Buffer defination ***********************************************/ struct { struct tx_desc txd[TX_DESC_CNT] __attribute__ ((aligned(32))); unsigned char txb[TX_BUF_ALLOC * TX_DESC_CNT] __attribute__ ((aligned(32))); struct rx_desc rxd[RX_DESC_CNT] __attribute__ ((aligned(32))); unsigned char rxb[RX_ALLOC_SIZE * RX_DESC_CNT] __attribute__ ((aligned(32))); } dmfe_bufs __shared; #define txd dmfe_bufs.txd #define txb dmfe_bufs.txb #define rxd dmfe_bufs.rxd #define rxb dmfe_bufs.rxb /* NIC specific static variables go here */ static long int BASE; static u16 read_srom_word(long ioaddr, int offset); static void dmfe_init_dm910x(struct nic *nic); static void dmfe_descriptor_init(struct nic *, unsigned long ioaddr); static void update_cr6(u32, unsigned long); static void send_filter_frame(struct nic *nic); static void dm9132_id_table(struct nic *nic); static u16 phy_read(unsigned long, u8, u8, u32); static void phy_write(unsigned long, u8, u8, u16, u32); static void phy_write_1bit(unsigned long, u32); static u16 phy_read_1bit(unsigned long); static void dmfe_set_phyxcer(struct nic *nic); static void dmfe_parse_srom(struct nic *nic); static void dmfe_program_DM9801(struct nic *nic, int); static void dmfe_program_DM9802(struct nic *nic); static void dmfe_reset(struct nic *nic) { /* system variable init */ db->cr6_data = CR6_DEFAULT | dmfe_cr6_user_set; db->NIC_capability = 0xf; /* All capability */ db->PHY_reg4 = 0x1e0; /* CR6 operation mode decision */ if (!chkmode || (db->chip_id == PCI_DM9132_ID) || (db->chip_revision >= 0x02000030)) { db->cr6_data |= DMFE_TXTH_256; db->cr0_data = CR0_DEFAULT; db->dm910x_chk_mode = 4; /* Enter the normal mode */ } else { db->cr6_data |= CR6_SFT; /* Store & Forward mode */ db->cr0_data = 0; db->dm910x_chk_mode = 1; /* Enter the check mode */ } /* Initilize DM910X board */ dmfe_init_dm910x(nic); return; } /* Initilize DM910X board * Reset DM910X board * Initilize TX/Rx descriptor chain structure * Send the set-up frame * Enable Tx/Rx machine */ static void dmfe_init_dm910x(struct nic *nic) { unsigned long ioaddr = BASE; /* Reset DM910x MAC controller */ outl(DM910X_RESET, ioaddr + DCR0); /* RESET MAC */ udelay(100); outl(db->cr0_data, ioaddr + DCR0); udelay(5); /* Phy addr : DM910(A)2/DM9132/9801, phy address = 1 */ db->phy_addr = 1; /* Parser SROM and media mode */ dmfe_parse_srom(nic); db->media_mode = dmfe_media_mode; /* RESET Phyxcer Chip by GPR port bit 7 */ outl(0x180, ioaddr + DCR12); /* Let bit 7 output port */ if (db->chip_id == PCI_DM9009_ID) { outl(0x80, ioaddr + DCR12); /* Issue RESET signal */ mdelay(300); /* Delay 300 ms */ } outl(0x0, ioaddr + DCR12); /* Clear RESET signal */ /* Process Phyxcer Media Mode */ if (!(db->media_mode & 0x10)) /* Force 1M mode */ dmfe_set_phyxcer(nic); /* Media Mode Process */ if (!(db->media_mode & DMFE_AUTO)) db->op_mode = db->media_mode; /* Force Mode */ /* Initiliaze Transmit/Receive decriptor and CR3/4 */ dmfe_descriptor_init(nic, ioaddr); /* tx descriptor start pointer */ outl(virt_to_le32desc(&txd[0]), ioaddr + DCR4); /* TX DESC address */ /* rx descriptor start pointer */ outl(virt_to_le32desc(&rxd[0]), ioaddr + DCR3); /* RX DESC address */ /* Init CR6 to program DM910x operation */ update_cr6(db->cr6_data, ioaddr); /* Send setup frame */ if (db->chip_id == PCI_DM9132_ID) { dm9132_id_table(nic); /* DM9132 */ } else { send_filter_frame(nic); /* DM9102/DM9102A */ } /* Init CR7, interrupt active bit */ db->cr7_data = CR7_DEFAULT; outl(db->cr7_data, ioaddr + DCR7); /* Init CR15, Tx jabber and Rx watchdog timer */ outl(db->cr15_data, ioaddr + DCR15); /* Enable DM910X Tx/Rx function */ db->cr6_data |= CR6_RXSC | CR6_TXSC | 0x40000; update_cr6(db->cr6_data, ioaddr); } #ifdef EDEBUG void hex_dump(const char *data, const unsigned int len); #endif /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int dmfe_poll(struct nic *nic, int retrieve) { u32 rdes0; int entry = db->cur_rx % RX_DESC_CNT; int rxlen; rdes0 = le32_to_cpu(rxd[entry].rdes0); if (rdes0 & 0x80000000) return 0; if (!retrieve) return 1; if ((rdes0 & 0x300) != 0x300) { /* A packet without First/Last flag */ printf("strange Packet\n"); rxd[entry].rdes0 = cpu_to_le32(0x80000000); return 0; } else { /* A packet with First/Last flag */ rxlen = ((rdes0 >> 16) & 0x3fff) - 4; /* error summary bit check */ if (rdes0 & 0x8000) { printf("Error\n"); return 0; } if (!(rdes0 & 0x8000) || ((db->cr6_data & CR6_PM) && (rxlen > 6))) { if (db->dm910x_chk_mode & 1) printf("Silly check mode\n"); nic->packetlen = rxlen; memcpy(nic->packet, rxb + (entry * RX_ALLOC_SIZE), nic->packetlen); } } rxd[entry].rdes0 = cpu_to_le32(0x80000000); db->cur_rx++; return 1; } static void dmfe_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void dmfe_transmit(struct nic *nic, const char *dest, /* Destination */ unsigned int type, /* Type */ unsigned int size, /* size */ const char *packet) /* Packet */ { u16 nstype; u8 *ptxb; ptxb = &txb[db->cur_tx]; /* Stop Tx */ outl(0, BASE + DCR7); memcpy(ptxb, dest, ETH_ALEN); memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); nstype = htons((u16) type); memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); memcpy(ptxb + ETH_HLEN, packet, size); size += ETH_HLEN; while (size < ETH_ZLEN) ptxb[size++] = '\0'; /* setup the transmit descriptor */ txd[db->cur_tx].tdes1 = cpu_to_le32(0xe1000000 | size); txd[db->cur_tx].tdes0 = cpu_to_le32(0x80000000); /* give ownership to device */ /* immediate transmit demand */ outl(0x1, BASE + DCR1); outl(db->cr7_data, BASE + DCR7); /* Point to next TX descriptor */ db->cur_tx++; db->cur_tx = db->cur_tx % TX_DESC_CNT; } /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void dmfe_disable ( struct nic *nic __unused ) { /* Reset & stop DM910X board */ outl(DM910X_RESET, BASE + DCR0); udelay(5); phy_write(BASE, db->phy_addr, 0, 0x8000, db->chip_id); } /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside ***************************************************************************/ #define board_found 1 #define valid_link 0 static int dmfe_probe ( struct nic *nic, struct pci_device *pci ) { uint32_t dev_rev, pci_pmr; int i; if (pci->ioaddr == 0) return 0; BASE = pci->ioaddr; printf("dmfe.c: Vendor=0x%hX Device=0x%hX\n", pci->vendor, pci->device); /* Read Chip revision */ pci_read_config_dword(pci, PCI_REVISION_ID, &dev_rev); dprintf(("Revision %lX\n", dev_rev)); /* point to private storage */ db = &dfx; db->chip_id = ((u32) pci->device << 16) | pci->vendor; BASE = pci_bar_start(pci, PCI_BASE_ADDRESS_0); db->chip_revision = dev_rev; pci_read_config_dword(pci, 0x50, &pci_pmr); pci_pmr &= 0x70000; if ((pci_pmr == 0x10000) && (dev_rev == 0x02000031)) db->chip_type = 1; /* DM9102A E3 */ else db->chip_type = 0; dprintf(("Chip type : %d\n", db->chip_type)); /* read 64 word srom data */ for (i = 0; i < 64; i++) ((u16 *) db->srom)[i] = cpu_to_le16(read_srom_word(BASE, i)); /* Set Node address */ for (i = 0; i < 6; i++) nic->node_addr[i] = db->srom[20 + i]; /* Print out some hardware info */ DBG ( "%s: at ioaddr %4.4lx\n", eth_ntoa ( nic->node_addr ), BASE ); /* Set the card as PCI Bus Master */ adjust_pci_device(pci); dmfe_reset(nic); nic->irqno = 0; nic->ioaddr = pci->ioaddr; /* point to NIC specific routines */ nic->nic_op = &dmfe_operations; return 1; } /* * Initialize transmit/Receive descriptor * Using Chain structure, and allocate Tx/Rx buffer */ static void dmfe_descriptor_init(struct nic *nic __unused, unsigned long ioaddr) { int i; db->cur_tx = 0; db->cur_rx = 0; /* tx descriptor start pointer */ outl(virt_to_le32desc(&txd[0]), ioaddr + DCR4); /* TX DESC address */ /* rx descriptor start pointer */ outl(virt_to_le32desc(&rxd[0]), ioaddr + DCR3); /* RX DESC address */ /* Init Transmit chain */ for (i = 0; i < TX_DESC_CNT; i++) { txd[i].tx_buf_ptr = &txb[i]; txd[i].tdes0 = cpu_to_le32(0); txd[i].tdes1 = cpu_to_le32(0x81000000); /* IC, chain */ txd[i].tdes2 = cpu_to_le32(virt_to_bus(&txb[i])); txd[i].tdes3 = cpu_to_le32(virt_to_bus(&txd[i + 1])); txd[i].next_tx_desc = &txd[i + 1]; } /* Mark the last entry as wrapping the ring */ txd[i - 1].tdes3 = virt_to_le32desc(&txd[0]); txd[i - 1].next_tx_desc = &txd[0]; /* receive descriptor chain */ for (i = 0; i < RX_DESC_CNT; i++) { rxd[i].rx_skb_ptr = &rxb[i * RX_ALLOC_SIZE]; rxd[i].rdes0 = cpu_to_le32(0x80000000); rxd[i].rdes1 = cpu_to_le32(0x01000600); rxd[i].rdes2 = cpu_to_le32(virt_to_bus(&rxb[i * RX_ALLOC_SIZE])); rxd[i].rdes3 = cpu_to_le32(virt_to_bus(&rxd[i + 1])); rxd[i].next_rx_desc = &rxd[i + 1]; } /* Mark the last entry as wrapping the ring */ rxd[i - 1].rdes3 = cpu_to_le32(virt_to_bus(&rxd[0])); rxd[i - 1].next_rx_desc = &rxd[0]; } /* * Update CR6 value * Firstly stop DM910X , then written value and start */ static void update_cr6(u32 cr6_data, unsigned long ioaddr) { u32 cr6_tmp; cr6_tmp = cr6_data & ~0x2002; /* stop Tx/Rx */ outl(cr6_tmp, ioaddr + DCR6); udelay(5); outl(cr6_data, ioaddr + DCR6); udelay(5); } /* * Send a setup frame for DM9132 * This setup frame initilize DM910X addres filter mode */ static void dm9132_id_table(struct nic *nic __unused) { #ifdef LINUX u16 *addrptr; u8 dmi_addr[8]; unsigned long ioaddr = BASE + 0xc0; /* ID Table */ u32 hash_val; u16 i, hash_table[4]; #endif dprintf(("dm9132_id_table\n")); printf("FIXME: This function is broken. If you have this card contact " "Timothy Legge at the etherboot-user list\n"); #ifdef LINUX //DMFE_DBUG(0, "dm9132_id_table()", 0); /* Node address */ addrptr = (u16 *) nic->node_addr; outw(addrptr[0], ioaddr); ioaddr += 4; outw(addrptr[1], ioaddr); ioaddr += 4; outw(addrptr[2], ioaddr); ioaddr += 4; /* Clear Hash Table */ for (i = 0; i < 4; i++) hash_table[i] = 0x0; /* broadcast address */ hash_table[3] = 0x8000; /* the multicast address in Hash Table : 64 bits */ for (mcptr = mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f; hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16); } /* Write the hash table to MAC MD table */ for (i = 0; i < 4; i++, ioaddr += 4) outw(hash_table[i], ioaddr); #endif } /* * Send a setup frame for DM9102/DM9102A * This setup frame initilize DM910X addres filter mode */ static void send_filter_frame(struct nic *nic) { u8 *ptxb; int i; dprintf(("send_filter_frame\n")); /* point to the current txb incase multiple tx_rings are used */ ptxb = &txb[db->cur_tx]; /* construct perfect filter frame with mac address as first match and broadcast address for all others */ for (i = 0; i < 192; i++) ptxb[i] = 0xFF; ptxb[0] = nic->node_addr[0]; ptxb[1] = nic->node_addr[1]; ptxb[4] = nic->node_addr[2]; ptxb[5] = nic->node_addr[3]; ptxb[8] = nic->node_addr[4]; ptxb[9] = nic->node_addr[5]; /* prepare the setup frame */ txd[db->cur_tx].tdes1 = cpu_to_le32(0x890000c0); txd[db->cur_tx].tdes0 = cpu_to_le32(0x80000000); update_cr6(db->cr6_data | 0x2000, BASE); outl(0x1, BASE + DCR1); /* Issue Tx polling */ update_cr6(db->cr6_data, BASE); db->cur_tx++; } /* * Read one word data from the serial ROM */ static u16 read_srom_word(long ioaddr, int offset) { int i; u16 srom_data = 0; long cr9_ioaddr = ioaddr + DCR9; outl(CR9_SROM_READ, cr9_ioaddr); outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); /* Send the Read Command 110b */ SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr); /* Send the offset */ for (i = 5; i >= 0; i--) { srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0; SROM_CLK_WRITE(srom_data, cr9_ioaddr); } outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); for (i = 16; i > 0; i--) { outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr); udelay(5); srom_data = (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 : 0); outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); udelay(5); } outl(CR9_SROM_READ, cr9_ioaddr); return srom_data; } /* * Auto sense the media mode */ #if 0 /* not used */ static u8 dmfe_sense_speed(struct nic *nic __unused) { u8 ErrFlag = 0; u16 phy_mode; /* CR6 bit18=0, select 10/100M */ update_cr6((db->cr6_data & ~0x40000), BASE); phy_mode = phy_read(BASE, db->phy_addr, 1, db->chip_id); phy_mode = phy_read(BASE, db->phy_addr, 1, db->chip_id); if ((phy_mode & 0x24) == 0x24) { if (db->chip_id == PCI_DM9132_ID) /* DM9132 */ phy_mode = phy_read(BASE, db->phy_addr, 7, db->chip_id) & 0xf000; else /* DM9102/DM9102A */ phy_mode = phy_read(BASE, db->phy_addr, 17, db->chip_id) & 0xf000; /* printk(DRV_NAME ": Phy_mode %x ",phy_mode); */ switch (phy_mode) { case 0x1000: db->op_mode = DMFE_10MHF; break; case 0x2000: db->op_mode = DMFE_10MFD; break; case 0x4000: db->op_mode = DMFE_100MHF; break; case 0x8000: db->op_mode = DMFE_100MFD; break; default: db->op_mode = DMFE_10MHF; ErrFlag = 1; break; } } else { db->op_mode = DMFE_10MHF; //DMFE_DBUG(0, "Link Failed :", phy_mode); ErrFlag = 1; } return ErrFlag; } #endif /* * Set 10/100 phyxcer capability * AUTO mode : phyxcer register4 is NIC capability * Force mode: phyxcer register4 is the force media */ static void dmfe_set_phyxcer(struct nic *nic __unused) { u16 phy_reg; /* Select 10/100M phyxcer */ db->cr6_data &= ~0x40000; update_cr6(db->cr6_data, BASE); /* DM9009 Chip: Phyxcer reg18 bit12=0 */ if (db->chip_id == PCI_DM9009_ID) { phy_reg = phy_read(BASE, db->phy_addr, 18, db->chip_id) & ~0x1000; phy_write(BASE, db->phy_addr, 18, phy_reg, db->chip_id); } /* Phyxcer capability setting */ phy_reg = phy_read(BASE, db->phy_addr, 4, db->chip_id) & ~0x01e0; if (db->media_mode & DMFE_AUTO) { /* AUTO Mode */ phy_reg |= db->PHY_reg4; } else { /* Force Mode */ switch (db->media_mode) { case DMFE_10MHF: phy_reg |= 0x20; break; case DMFE_10MFD: phy_reg |= 0x40; break; case DMFE_100MHF: phy_reg |= 0x80; break; case DMFE_100MFD: phy_reg |= 0x100; break; } if (db->chip_id == PCI_DM9009_ID) phy_reg &= 0x61; } /* Write new capability to Phyxcer Reg4 */ if (!(phy_reg & 0x01e0)) { phy_reg |= db->PHY_reg4; db->media_mode |= DMFE_AUTO; } phy_write(BASE, db->phy_addr, 4, phy_reg, db->chip_id); /* Restart Auto-Negotiation */ if (db->chip_type && (db->chip_id == PCI_DM9102_ID)) phy_write(BASE, db->phy_addr, 0, 0x1800, db->chip_id); if (!db->chip_type) phy_write(BASE, db->phy_addr, 0, 0x1200, db->chip_id); } /* * Process op-mode * AUTO mode : PHY controller in Auto-negotiation Mode * Force mode: PHY controller in force mode with HUB * N-way force capability with SWITCH */ #if 0 /* not used */ static void dmfe_process_mode(struct nic *nic __unused) { u16 phy_reg; /* Full Duplex Mode Check */ if (db->op_mode & 0x4) db->cr6_data |= CR6_FDM; /* Set Full Duplex Bit */ else db->cr6_data &= ~CR6_FDM; /* Clear Full Duplex Bit */ /* Transciver Selection */ if (db->op_mode & 0x10) /* 1M HomePNA */ db->cr6_data |= 0x40000; /* External MII select */ else db->cr6_data &= ~0x40000; /* Internal 10/100 transciver */ update_cr6(db->cr6_data, BASE); /* 10/100M phyxcer force mode need */ if (!(db->media_mode & 0x18)) { /* Forece Mode */ phy_reg = phy_read(BASE, db->phy_addr, 6, db->chip_id); if (!(phy_reg & 0x1)) { /* parter without N-Way capability */ phy_reg = 0x0; switch (db->op_mode) { case DMFE_10MHF: phy_reg = 0x0; break; case DMFE_10MFD: phy_reg = 0x100; break; case DMFE_100MHF: phy_reg = 0x2000; break; case DMFE_100MFD: phy_reg = 0x2100; break; } phy_write(BASE, db->phy_addr, 0, phy_reg, db->chip_id); if (db->chip_type && (db->chip_id == PCI_DM9102_ID)) mdelay(20); phy_write(BASE, db->phy_addr, 0, phy_reg, db->chip_id); } } } #endif /* * Write a word to Phy register */ static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data, u32 chip_id) { u16 i; unsigned long ioaddr; if (chip_id == PCI_DM9132_ID) { ioaddr = iobase + 0x80 + offset * 4; outw(phy_data, ioaddr); } else { /* DM9102/DM9102A Chip */ ioaddr = iobase + DCR9; /* Send 33 synchronization clock to Phy controller */ for (i = 0; i < 35; i++) phy_write_1bit(ioaddr, PHY_DATA_1); /* Send start command(01) to Phy */ phy_write_1bit(ioaddr, PHY_DATA_0); phy_write_1bit(ioaddr, PHY_DATA_1); /* Send write command(01) to Phy */ phy_write_1bit(ioaddr, PHY_DATA_0); phy_write_1bit(ioaddr, PHY_DATA_1); /* Send Phy addres */ for (i = 0x10; i > 0; i = i >> 1) phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0); /* Send register addres */ for (i = 0x10; i > 0; i = i >> 1) phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0); /* written trasnition */ phy_write_1bit(ioaddr, PHY_DATA_1); phy_write_1bit(ioaddr, PHY_DATA_0); /* Write a word data to PHY controller */ for (i = 0x8000; i > 0; i >>= 1) phy_write_1bit(ioaddr, phy_data & i ? PHY_DATA_1 : PHY_DATA_0); } } /* * Read a word data from phy register */ static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, u32 chip_id) { int i; u16 phy_data; unsigned long ioaddr; if (chip_id == PCI_DM9132_ID) { /* DM9132 Chip */ ioaddr = iobase + 0x80 + offset * 4; phy_data = inw(ioaddr); } else { /* DM9102/DM9102A Chip */ ioaddr = iobase + DCR9; /* Send 33 synchronization clock to Phy controller */ for (i = 0; i < 35; i++) phy_write_1bit(ioaddr, PHY_DATA_1); /* Send start command(01) to Phy */ phy_write_1bit(ioaddr, PHY_DATA_0); phy_write_1bit(ioaddr, PHY_DATA_1); /* Send read command(10) to Phy */ phy_write_1bit(ioaddr, PHY_DATA_1); phy_write_1bit(ioaddr, PHY_DATA_0); /* Send Phy addres */ for (i = 0x10; i > 0; i = i >> 1) phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0); /* Send register addres */ for (i = 0x10; i > 0; i = i >> 1) phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0); /* Skip transition state */ phy_read_1bit(ioaddr); /* read 16bit data */ for (phy_data = 0, i = 0; i < 16; i++) { phy_data <<= 1; phy_data |= phy_read_1bit(ioaddr); } } return phy_data; } /* * Write one bit data to Phy Controller */ static void phy_write_1bit(unsigned long ioaddr, u32 phy_data) { outl(phy_data, ioaddr); /* MII Clock Low */ udelay(1); outl(phy_data | MDCLKH, ioaddr); /* MII Clock High */ udelay(1); outl(phy_data, ioaddr); /* MII Clock Low */ udelay(1); } /* * Read one bit phy data from PHY controller */ static u16 phy_read_1bit(unsigned long ioaddr) { u16 phy_data; outl(0x50000, ioaddr); udelay(1); phy_data = (inl(ioaddr) >> 19) & 0x1; outl(0x40000, ioaddr); udelay(1); return phy_data; } /* * Parser SROM and media mode */ static void dmfe_parse_srom(struct nic *nic) { unsigned char *srom = db->srom; int dmfe_mode, tmp_reg; /* Init CR15 */ db->cr15_data = CR15_DEFAULT; /* Check SROM Version */ if (((int) srom[18] & 0xff) == SROM_V41_CODE) { /* SROM V4.01 */ /* Get NIC support media mode */ db->NIC_capability = *(u16 *) (srom + 34); db->PHY_reg4 = 0; for (tmp_reg = 1; tmp_reg < 0x10; tmp_reg <<= 1) { switch (db->NIC_capability & tmp_reg) { case 0x1: db->PHY_reg4 |= 0x0020; break; case 0x2: db->PHY_reg4 |= 0x0040; break; case 0x4: db->PHY_reg4 |= 0x0080; break; case 0x8: db->PHY_reg4 |= 0x0100; break; } } /* Media Mode Force or not check */ dmfe_mode = *((int *) srom + 34) & *((int *) srom + 36); switch (dmfe_mode) { case 0x4: dmfe_media_mode = DMFE_100MHF; break; /* 100MHF */ case 0x2: dmfe_media_mode = DMFE_10MFD; break; /* 10MFD */ case 0x8: dmfe_media_mode = DMFE_100MFD; break; /* 100MFD */ case 0x100: case 0x200: dmfe_media_mode = DMFE_1M_HPNA; break; /* HomePNA */ } /* Special Function setting */ /* VLAN function */ if ((SF_mode & 0x1) || (srom[43] & 0x80)) db->cr15_data |= 0x40; /* Flow Control */ if ((SF_mode & 0x2) || (srom[40] & 0x1)) db->cr15_data |= 0x400; /* TX pause packet */ if ((SF_mode & 0x4) || (srom[40] & 0xe)) db->cr15_data |= 0x9800; } /* Parse HPNA parameter */ db->HPNA_command = 1; /* Accept remote command or not */ if (HPNA_rx_cmd == 0) db->HPNA_command |= 0x8000; /* Issue remote command & operation mode */ if (HPNA_tx_cmd == 1) switch (HPNA_mode) { /* Issue Remote Command */ case 0: db->HPNA_command |= 0x0904; break; case 1: db->HPNA_command |= 0x0a00; break; case 2: db->HPNA_command |= 0x0506; break; case 3: db->HPNA_command |= 0x0602; break; } else switch (HPNA_mode) { /* Don't Issue */ case 0: db->HPNA_command |= 0x0004; break; case 1: db->HPNA_command |= 0x0000; break; case 2: db->HPNA_command |= 0x0006; break; case 3: db->HPNA_command |= 0x0002; break; } /* Check DM9801 or DM9802 present or not */ db->HPNA_present = 0; update_cr6(db->cr6_data | 0x40000, BASE); tmp_reg = phy_read(BASE, db->phy_addr, 3, db->chip_id); if ((tmp_reg & 0xfff0) == 0xb900) { /* DM9801 or DM9802 present */ db->HPNA_timer = 8; if (phy_read(BASE, db->phy_addr, 31, db->chip_id) == 0x4404) { /* DM9801 HomeRun */ db->HPNA_present = 1; dmfe_program_DM9801(nic, tmp_reg); } else { /* DM9802 LongRun */ db->HPNA_present = 2; dmfe_program_DM9802(nic); } } } /* * Init HomeRun DM9801 */ static void dmfe_program_DM9801(struct nic *nic __unused, int HPNA_rev) { u32 reg17, reg25; if (!HPNA_NoiseFloor) HPNA_NoiseFloor = DM9801_NOISE_FLOOR; switch (HPNA_rev) { case 0xb900: /* DM9801 E3 */ db->HPNA_command |= 0x1000; reg25 = phy_read(BASE, db->phy_addr, 24, db->chip_id); reg25 = ((reg25 + HPNA_NoiseFloor) & 0xff) | 0xf000; reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id); break; case 0xb901: /* DM9801 E4 */ reg25 = phy_read(BASE, db->phy_addr, 25, db->chip_id); reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor; reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id); reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor + 3; break; case 0xb902: /* DM9801 E5 */ case 0xb903: /* DM9801 E6 */ default: db->HPNA_command |= 0x1000; reg25 = phy_read(BASE, db->phy_addr, 25, db->chip_id); reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor - 5; reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id); reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor; break; } phy_write(BASE, db->phy_addr, 16, db->HPNA_command, db->chip_id); phy_write(BASE, db->phy_addr, 17, reg17, db->chip_id); phy_write(BASE, db->phy_addr, 25, reg25, db->chip_id); } /* * Init HomeRun DM9802 */ static void dmfe_program_DM9802(struct nic *nic __unused) { u32 phy_reg; if (!HPNA_NoiseFloor) HPNA_NoiseFloor = DM9802_NOISE_FLOOR; phy_write(BASE, db->phy_addr, 16, db->HPNA_command, db->chip_id); phy_reg = phy_read(BASE, db->phy_addr, 25, db->chip_id); phy_reg = (phy_reg & 0xff00) + HPNA_NoiseFloor; phy_write(BASE, db->phy_addr, 25, phy_reg, db->chip_id); } static struct nic_operations dmfe_operations = { .connect = dummy_connect, .poll = dmfe_poll, .transmit = dmfe_transmit, .irq = dmfe_irq, }; static struct pci_device_id dmfe_nics[] = { PCI_ROM(0x1282, 0x9100, "dmfe9100", "Davicom 9100", 0), PCI_ROM(0x1282, 0x9102, "dmfe9102", "Davicom 9102", 0), PCI_ROM(0x1282, 0x9009, "dmfe9009", "Davicom 9009", 0), PCI_ROM(0x1282, 0x9132, "dmfe9132", "Davicom 9132", 0), /* Needs probably some fixing */ }; PCI_DRIVER ( dmfe_driver, dmfe_nics, PCI_NO_CLASS ); DRIVER ( "DMFE/PCI", nic_driver, pci_driver, dmfe_driver, dmfe_probe, dmfe_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/forcedeth.c0000664000000000000000000012127012524662415021321 0ustar /************************************************************************** * forcedeth.c -- Etherboot device driver for the NVIDIA nForce * media access controllers. * * Note: This driver is based on the Linux driver that was based on * a cleanroom reimplementation which was based on reverse * engineered documentation written by Carl-Daniel Hailfinger * and Andrew de Quincey. It's neither supported nor endorsed * by NVIDIA Corp. Use at your own risk. * * Written 2004 by Timothy Legge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Portions of this code based on: * forcedeth: Ethernet driver for NVIDIA nForce media access controllers: * * (C) 2003 Manfred Spraul * See Linux Driver for full information * * Linux Driver Version 0.30, 25 Sep 2004 * Linux Kernel 2.6.10 * * * REVISION HISTORY: * ================ * v1.0 01-31-2004 timlegge Initial port of Linux driver * v1.1 02-03-2004 timlegge Large Clean up, first release * v1.2 05-14-2005 timlegge Add Linux 0.22 to .030 features * * Indent Options: indent -kr -i8 ***************************************************************************/ FILE_LICENCE ( GPL2_OR_LATER ); /* to get some global routines like printf */ #include "etherboot.h" /* to get the interface to the body of the program */ #include "nic.h" /* to get the PCI support functions, if this is a PCI NIC */ #include /* Include timer support functions */ #include #include "mii.h" #define drv_version "v1.2" #define drv_date "05-14-2005" //#define TFTM_DEBUG #ifdef TFTM_DEBUG #define dprintf(x) printf x #else #define dprintf(x) #endif #define ETH_DATA_LEN 1500 /* Condensed operations for readability. */ #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) static unsigned long BASE; /* NIC specific static variables go here */ #define PCI_DEVICE_ID_NVIDIA_NVENET_1 0x01c3 #define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066 #define PCI_DEVICE_ID_NVIDIA_NVENET_4 0x0086 #define PCI_DEVICE_ID_NVIDIA_NVENET_5 0x008c #define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6 #define PCI_DEVICE_ID_NVIDIA_NVENET_7 0x00df #define PCI_DEVICE_ID_NVIDIA_NVENET_6 0x00e6 #define PCI_DEVICE_ID_NVIDIA_NVENET_8 0x0056 #define PCI_DEVICE_ID_NVIDIA_NVENET_9 0x0057 #define PCI_DEVICE_ID_NVIDIA_NVENET_10 0x0037 #define PCI_DEVICE_ID_NVIDIA_NVENET_11 0x0038 #define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373 /* * Hardware access: */ #define DEV_NEED_LASTPACKET1 0x0001 /* set LASTPACKET1 in tx flags */ #define DEV_IRQMASK_1 0x0002 /* use NVREG_IRQMASK_WANTED_1 for irq mask */ #define DEV_IRQMASK_2 0x0004 /* use NVREG_IRQMASK_WANTED_2 for irq mask */ #define DEV_NEED_TIMERIRQ 0x0008 /* set the timer irq flag in the irq mask */ #define DEV_NEED_LINKTIMER 0x0010 /* poll link settings. Relies on the timer irq */ enum { NvRegIrqStatus = 0x000, #define NVREG_IRQSTAT_MIIEVENT 0040 #define NVREG_IRQSTAT_MASK 0x1ff NvRegIrqMask = 0x004, #define NVREG_IRQ_RX_ERROR 0x0001 #define NVREG_IRQ_RX 0x0002 #define NVREG_IRQ_RX_NOBUF 0x0004 #define NVREG_IRQ_TX_ERR 0x0008 #define NVREG_IRQ_TX2 0x0010 #define NVREG_IRQ_TIMER 0x0020 #define NVREG_IRQ_LINK 0x0040 #define NVREG_IRQ_TX1 0x0100 #define NVREG_IRQMASK_WANTED_1 0x005f #define NVREG_IRQMASK_WANTED_2 0x0147 #define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1)) NvRegUnknownSetupReg6 = 0x008, #define NVREG_UNKSETUP6_VAL 3 /* * NVREG_POLL_DEFAULT is the interval length of the timer source on the nic * NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms */ NvRegPollingInterval = 0x00c, #define NVREG_POLL_DEFAULT 970 NvRegMisc1 = 0x080, #define NVREG_MISC1_HD 0x02 #define NVREG_MISC1_FORCE 0x3b0f3c NvRegTransmitterControl = 0x084, #define NVREG_XMITCTL_START 0x01 NvRegTransmitterStatus = 0x088, #define NVREG_XMITSTAT_BUSY 0x01 NvRegPacketFilterFlags = 0x8c, #define NVREG_PFF_ALWAYS 0x7F0008 #define NVREG_PFF_PROMISC 0x80 #define NVREG_PFF_MYADDR 0x20 NvRegOffloadConfig = 0x90, #define NVREG_OFFLOAD_HOMEPHY 0x601 #define NVREG_OFFLOAD_NORMAL RX_NIC_BUFSIZE NvRegReceiverControl = 0x094, #define NVREG_RCVCTL_START 0x01 NvRegReceiverStatus = 0x98, #define NVREG_RCVSTAT_BUSY 0x01 NvRegRandomSeed = 0x9c, #define NVREG_RNDSEED_MASK 0x00ff #define NVREG_RNDSEED_FORCE 0x7f00 #define NVREG_RNDSEED_FORCE2 0x2d00 #define NVREG_RNDSEED_FORCE3 0x7400 NvRegUnknownSetupReg1 = 0xA0, #define NVREG_UNKSETUP1_VAL 0x16070f NvRegUnknownSetupReg2 = 0xA4, #define NVREG_UNKSETUP2_VAL 0x16 NvRegMacAddrA = 0xA8, NvRegMacAddrB = 0xAC, NvRegMulticastAddrA = 0xB0, #define NVREG_MCASTADDRA_FORCE 0x01 NvRegMulticastAddrB = 0xB4, NvRegMulticastMaskA = 0xB8, NvRegMulticastMaskB = 0xBC, NvRegPhyInterface = 0xC0, #define PHY_RGMII 0x10000000 NvRegTxRingPhysAddr = 0x100, NvRegRxRingPhysAddr = 0x104, NvRegRingSizes = 0x108, #define NVREG_RINGSZ_TXSHIFT 0 #define NVREG_RINGSZ_RXSHIFT 16 NvRegUnknownTransmitterReg = 0x10c, NvRegLinkSpeed = 0x110, #define NVREG_LINKSPEED_FORCE 0x10000 #define NVREG_LINKSPEED_10 1000 #define NVREG_LINKSPEED_100 100 #define NVREG_LINKSPEED_1000 50 NvRegUnknownSetupReg5 = 0x130, #define NVREG_UNKSETUP5_BIT31 (1<<31) NvRegUnknownSetupReg3 = 0x13c, #define NVREG_UNKSETUP3_VAL1 0x200010 NvRegTxRxControl = 0x144, #define NVREG_TXRXCTL_KICK 0x0001 #define NVREG_TXRXCTL_BIT1 0x0002 #define NVREG_TXRXCTL_BIT2 0x0004 #define NVREG_TXRXCTL_IDLE 0x0008 #define NVREG_TXRXCTL_RESET 0x0010 #define NVREG_TXRXCTL_RXCHECK 0x0400 NvRegMIIStatus = 0x180, #define NVREG_MIISTAT_ERROR 0x0001 #define NVREG_MIISTAT_LINKCHANGE 0x0008 #define NVREG_MIISTAT_MASK 0x000f #define NVREG_MIISTAT_MASK2 0x000f NvRegUnknownSetupReg4 = 0x184, #define NVREG_UNKSETUP4_VAL 8 NvRegAdapterControl = 0x188, #define NVREG_ADAPTCTL_START 0x02 #define NVREG_ADAPTCTL_LINKUP 0x04 #define NVREG_ADAPTCTL_PHYVALID 0x40000 #define NVREG_ADAPTCTL_RUNNING 0x100000 #define NVREG_ADAPTCTL_PHYSHIFT 24 NvRegMIISpeed = 0x18c, #define NVREG_MIISPEED_BIT8 (1<<8) #define NVREG_MIIDELAY 5 NvRegMIIControl = 0x190, #define NVREG_MIICTL_INUSE 0x08000 #define NVREG_MIICTL_WRITE 0x00400 #define NVREG_MIICTL_ADDRSHIFT 5 NvRegMIIData = 0x194, NvRegWakeUpFlags = 0x200, #define NVREG_WAKEUPFLAGS_VAL 0x7770 #define NVREG_WAKEUPFLAGS_BUSYSHIFT 24 #define NVREG_WAKEUPFLAGS_ENABLESHIFT 16 #define NVREG_WAKEUPFLAGS_D3SHIFT 12 #define NVREG_WAKEUPFLAGS_D2SHIFT 8 #define NVREG_WAKEUPFLAGS_D1SHIFT 4 #define NVREG_WAKEUPFLAGS_D0SHIFT 0 #define NVREG_WAKEUPFLAGS_ACCEPT_MAGPAT 0x01 #define NVREG_WAKEUPFLAGS_ACCEPT_WAKEUPPAT 0x02 #define NVREG_WAKEUPFLAGS_ACCEPT_LINKCHANGE 0x04 #define NVREG_WAKEUPFLAGS_ENABLE 0x1111 NvRegPatternCRC = 0x204, NvRegPatternMask = 0x208, NvRegPowerCap = 0x268, #define NVREG_POWERCAP_D3SUPP (1<<30) #define NVREG_POWERCAP_D2SUPP (1<<26) #define NVREG_POWERCAP_D1SUPP (1<<25) NvRegPowerState = 0x26c, #define NVREG_POWERSTATE_POWEREDUP 0x8000 #define NVREG_POWERSTATE_VALID 0x0100 #define NVREG_POWERSTATE_MASK 0x0003 #define NVREG_POWERSTATE_D0 0x0000 #define NVREG_POWERSTATE_D1 0x0001 #define NVREG_POWERSTATE_D2 0x0002 #define NVREG_POWERSTATE_D3 0x0003 }; #define FLAG_MASK_V1 0xffff0000 #define FLAG_MASK_V2 0xffffc000 #define LEN_MASK_V1 (0xffffffff ^ FLAG_MASK_V1) #define LEN_MASK_V2 (0xffffffff ^ FLAG_MASK_V2) #define NV_TX_LASTPACKET (1<<16) #define NV_TX_RETRYERROR (1<<19) #define NV_TX_LASTPACKET1 (1<<24) #define NV_TX_DEFERRED (1<<26) #define NV_TX_CARRIERLOST (1<<27) #define NV_TX_LATECOLLISION (1<<28) #define NV_TX_UNDERFLOW (1<<29) #define NV_TX_ERROR (1<<30) #define NV_TX_VALID (1<<31) #define NV_TX2_LASTPACKET (1<<29) #define NV_TX2_RETRYERROR (1<<18) #define NV_TX2_LASTPACKET1 (1<<23) #define NV_TX2_DEFERRED (1<<25) #define NV_TX2_CARRIERLOST (1<<26) #define NV_TX2_LATECOLLISION (1<<27) #define NV_TX2_UNDERFLOW (1<<28) /* error and valid are the same for both */ #define NV_TX2_ERROR (1<<30) #define NV_TX2_VALID (1<<31) #define NV_RX_DESCRIPTORVALID (1<<16) #define NV_RX_MISSEDFRAME (1<<17) #define NV_RX_SUBSTRACT1 (1<<18) #define NV_RX_ERROR1 (1<<23) #define NV_RX_ERROR2 (1<<24) #define NV_RX_ERROR3 (1<<25) #define NV_RX_ERROR4 (1<<26) #define NV_RX_CRCERR (1<<27) #define NV_RX_OVERFLOW (1<<28) #define NV_RX_FRAMINGERR (1<<29) #define NV_RX_ERROR (1<<30) #define NV_RX_AVAIL (1<<31) #define NV_RX2_CHECKSUMMASK (0x1C000000) #define NV_RX2_CHECKSUMOK1 (0x10000000) #define NV_RX2_CHECKSUMOK2 (0x14000000) #define NV_RX2_CHECKSUMOK3 (0x18000000) #define NV_RX2_DESCRIPTORVALID (1<<29) #define NV_RX2_SUBSTRACT1 (1<<25) #define NV_RX2_ERROR1 (1<<18) #define NV_RX2_ERROR2 (1<<19) #define NV_RX2_ERROR3 (1<<20) #define NV_RX2_ERROR4 (1<<21) #define NV_RX2_CRCERR (1<<22) #define NV_RX2_OVERFLOW (1<<23) #define NV_RX2_FRAMINGERR (1<<24) /* error and avail are the same for both */ #define NV_RX2_ERROR (1<<30) #define NV_RX2_AVAIL (1<<31) /* Miscelaneous hardware related defines: */ #define NV_PCI_REGSZ 0x270 /* various timeout delays: all in usec */ #define NV_TXRX_RESET_DELAY 4 #define NV_TXSTOP_DELAY1 10 #define NV_TXSTOP_DELAY1MAX 500000 #define NV_TXSTOP_DELAY2 100 #define NV_RXSTOP_DELAY1 10 #define NV_RXSTOP_DELAY1MAX 500000 #define NV_RXSTOP_DELAY2 100 #define NV_SETUP5_DELAY 5 #define NV_SETUP5_DELAYMAX 50000 #define NV_POWERUP_DELAY 5 #define NV_POWERUP_DELAYMAX 5000 #define NV_MIIBUSY_DELAY 50 #define NV_MIIPHY_DELAY 10 #define NV_MIIPHY_DELAYMAX 10000 #define NV_WAKEUPPATTERNS 5 #define NV_WAKEUPMASKENTRIES 4 /* General driver defaults */ #define NV_WATCHDOG_TIMEO (5*HZ) #define RX_RING 4 #define TX_RING 2 /* * If your nic mysteriously hangs then try to reduce the limits * to 1/0: It might be required to set NV_TX_LASTPACKET in the * last valid ring entry. But this would be impossible to * implement - probably a disassembly error. */ #define TX_LIMIT_STOP 63 #define TX_LIMIT_START 62 /* rx/tx mac addr + type + vlan + align + slack*/ #define RX_NIC_BUFSIZE (ETH_DATA_LEN + 64) /* even more slack */ #define RX_ALLOC_BUFSIZE (ETH_DATA_LEN + 128) #define OOM_REFILL (1+HZ/20) #define POLL_WAIT (1+HZ/100) #define LINK_TIMEOUT (3*HZ) /* * desc_ver values: * This field has two purposes: * - Newer nics uses a different ring layout. The layout is selected by * comparing np->desc_ver with DESC_VER_xy. * - It contains bits that are forced on when writing to NvRegTxRxControl. */ #define DESC_VER_1 0x0 #define DESC_VER_2 (0x02100|NVREG_TXRXCTL_RXCHECK) /* PHY defines */ #define PHY_OUI_MARVELL 0x5043 #define PHY_OUI_CICADA 0x03f1 #define PHYID1_OUI_MASK 0x03ff #define PHYID1_OUI_SHFT 6 #define PHYID2_OUI_MASK 0xfc00 #define PHYID2_OUI_SHFT 10 #define PHY_INIT1 0x0f000 #define PHY_INIT2 0x0e00 #define PHY_INIT3 0x01000 #define PHY_INIT4 0x0200 #define PHY_INIT5 0x0004 #define PHY_INIT6 0x02000 #define PHY_GIGABIT 0x0100 #define PHY_TIMEOUT 0x1 #define PHY_ERROR 0x2 #define PHY_100 0x1 #define PHY_1000 0x2 #define PHY_HALF 0x100 /* Bit to know if MAC addr is stored in correct order */ #define MAC_ADDR_CORRECT 0x01 /* Big endian: should work, but is untested */ struct ring_desc { u32 PacketBuffer; u32 FlagLen; }; /* Define the TX and RX Descriptor and Buffers */ struct { struct ring_desc tx_ring[TX_RING]; unsigned char txb[TX_RING * RX_NIC_BUFSIZE]; struct ring_desc rx_ring[RX_RING]; unsigned char rxb[RX_RING * RX_NIC_BUFSIZE]; } forcedeth_bufs __shared; #define tx_ring forcedeth_bufs.tx_ring #define rx_ring forcedeth_bufs.rx_ring #define txb forcedeth_bufs.txb #define rxb forcedeth_bufs.rxb /* Private Storage for the NIC */ static struct forcedeth_private { /* General data: * Locking: spin_lock(&np->lock); */ int in_shutdown; u32 linkspeed; int duplex; int phyaddr; int wolenabled; unsigned int phy_oui; u16 gigabit; /* General data: RO fields */ u8 *ring_addr; u32 orig_mac[2]; u32 irqmask; u32 desc_ver; /* rx specific fields. * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); */ unsigned int cur_rx, refill_rx; /* * tx specific fields. */ unsigned int next_tx, nic_tx; u32 tx_flags; } npx; static struct forcedeth_private *np; static inline void pci_push(u8 * base) { /* force out pending posted writes */ readl(base); } static inline u32 nv_descr_getlength(struct ring_desc *prd, u32 v) { return le32_to_cpu(prd->FlagLen) & ((v == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); } static int reg_delay(int offset, u32 mask, u32 target, int delay, int delaymax, const char *msg) { u8 *base = (u8 *) BASE; pci_push(base); do { udelay(delay); delaymax -= delay; if (delaymax < 0) { if (msg) printf("%s", msg); return 1; } } while ((readl(base + offset) & mask) != target); return 0; } #define MII_READ (-1) /* mii_rw: read/write a register on the PHY. * * Caller must guarantee serialization */ static int mii_rw(struct nic *nic __unused, int addr, int miireg, int value) { u8 *base = (u8 *) BASE; u32 reg; int retval; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); reg = readl(base + NvRegMIIControl); if (reg & NVREG_MIICTL_INUSE) { writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl); udelay(NV_MIIBUSY_DELAY); } reg = (addr << NVREG_MIICTL_ADDRSHIFT) | miireg; if (value != MII_READ) { writel(value, base + NvRegMIIData); reg |= NVREG_MIICTL_WRITE; } writel(reg, base + NvRegMIIControl); if (reg_delay(NvRegMIIControl, NVREG_MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL)) { dprintf(("mii_rw of reg %d at PHY %d timed out.\n", miireg, addr)); retval = -1; } else if (value != MII_READ) { /* it was a write operation - fewer failures are detectable */ dprintf(("mii_rw wrote 0x%x to reg %d at PHY %d\n", value, miireg, addr)); retval = 0; } else if (readl(base + NvRegMIIStatus) & NVREG_MIISTAT_ERROR) { dprintf(("mii_rw of reg %d at PHY %d failed.\n", miireg, addr)); retval = -1; } else { retval = readl(base + NvRegMIIData); dprintf(("mii_rw read from reg %d at PHY %d: 0x%x.\n", miireg, addr, retval)); } return retval; } static int phy_reset(struct nic *nic) { u32 miicontrol; unsigned int tries = 0; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ); miicontrol |= BMCR_RESET; if (mii_rw(nic, np->phyaddr, MII_BMCR, miicontrol)) { return -1; } /* wait for 500ms */ mdelay(500); /* must wait till reset is deasserted */ while (miicontrol & BMCR_RESET) { mdelay(10); miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ); /* FIXME: 100 tries seem excessive */ if (tries++ > 100) return -1; } return 0; } static int phy_init(struct nic *nic) { u8 *base = (u8 *) BASE; u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000, reg; /* set advertise register */ reg = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ); reg |= (ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | ADVERTISE_100FULL | 0x800 | 0x400); if (mii_rw(nic, np->phyaddr, MII_ADVERTISE, reg)) { printf("phy write to advertise failed.\n"); return PHY_ERROR; } /* get phy interface type */ phyinterface = readl(base + NvRegPhyInterface); /* see if gigabit phy */ mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); if (mii_status & PHY_GIGABIT) { np->gigabit = PHY_GIGABIT; mii_control_1000 = mii_rw(nic, np->phyaddr, MII_CTRL1000, MII_READ); mii_control_1000 &= ~ADVERTISE_1000HALF; if (phyinterface & PHY_RGMII) mii_control_1000 |= ADVERTISE_1000FULL; else mii_control_1000 &= ~ADVERTISE_1000FULL; if (mii_rw (nic, np->phyaddr, MII_CTRL1000, mii_control_1000)) { printf("phy init failed.\n"); return PHY_ERROR; } } else np->gigabit = 0; /* reset the phy */ if (phy_reset(nic)) { printf("phy reset failed\n"); return PHY_ERROR; } /* phy vendor specific configuration */ if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII)) { phy_reserved = mii_rw(nic, np->phyaddr, MII_RESV1, MII_READ); phy_reserved &= ~(PHY_INIT1 | PHY_INIT2); phy_reserved |= (PHY_INIT3 | PHY_INIT4); if (mii_rw(nic, np->phyaddr, MII_RESV1, phy_reserved)) { printf("phy init failed.\n"); return PHY_ERROR; } phy_reserved = mii_rw(nic, np->phyaddr, MII_NCONFIG, MII_READ); phy_reserved |= PHY_INIT5; if (mii_rw(nic, np->phyaddr, MII_NCONFIG, phy_reserved)) { printf("phy init failed.\n"); return PHY_ERROR; } } if (np->phy_oui == PHY_OUI_CICADA) { phy_reserved = mii_rw(nic, np->phyaddr, MII_SREVISION, MII_READ); phy_reserved |= PHY_INIT6; if (mii_rw(nic, np->phyaddr, MII_SREVISION, phy_reserved)) { printf("phy init failed.\n"); return PHY_ERROR; } } /* restart auto negotiation */ mii_control = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ); mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE); if (mii_rw(nic, np->phyaddr, MII_BMCR, mii_control)) { return PHY_ERROR; } return 0; } static void start_rx(struct nic *nic __unused) { u8 *base = (u8 *) BASE; dprintf(("start_rx\n")); /* Already running? Stop it. */ if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) { writel(0, base + NvRegReceiverControl); pci_push(base); } writel(np->linkspeed, base + NvRegLinkSpeed); pci_push(base); writel(NVREG_RCVCTL_START, base + NvRegReceiverControl); pci_push(base); } static void stop_rx(void) { u8 *base = (u8 *) BASE; dprintf(("stop_rx\n")); writel(0, base + NvRegReceiverControl); reg_delay(NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, "stop_rx: ReceiverStatus remained busy"); udelay(NV_RXSTOP_DELAY2); writel(0, base + NvRegLinkSpeed); } static void start_tx(struct nic *nic __unused) { u8 *base = (u8 *) BASE; dprintf(("start_tx\n")); writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl); pci_push(base); } static void stop_tx(void) { u8 *base = (u8 *) BASE; dprintf(("stop_tx\n")); writel(0, base + NvRegTransmitterControl); reg_delay(NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0, NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX, "stop_tx: TransmitterStatus remained busy"); udelay(NV_TXSTOP_DELAY2); writel(0, base + NvRegUnknownTransmitterReg); } static void txrx_reset(struct nic *nic __unused) { u8 *base = (u8 *) BASE; dprintf(("txrx_reset\n")); writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl); pci_push(base); udelay(NV_TXRX_RESET_DELAY); writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl); pci_push(base); } /* * alloc_rx: fill rx ring entries. * Return 1 if the allocations for the skbs failed and the * rx engine is without Available descriptors */ static int alloc_rx(struct nic *nic __unused) { unsigned int refill_rx = np->refill_rx; int i; //while (np->cur_rx != refill_rx) { for (i = 0; i < RX_RING; i++) { //int nr = refill_rx % RX_RING; rx_ring[i].PacketBuffer = virt_to_le32desc(&rxb[i * RX_NIC_BUFSIZE]); wmb(); rx_ring[i].FlagLen = cpu_to_le32(RX_NIC_BUFSIZE | NV_RX_AVAIL); /* printf("alloc_rx: Packet %d marked as Available\n", refill_rx); */ refill_rx++; } np->refill_rx = refill_rx; if (np->cur_rx - refill_rx == RX_RING) return 1; return 0; } static int update_linkspeed(struct nic *nic) { int adv, lpa; u32 newls; int newdup = np->duplex; u32 mii_status; int retval = 0; u32 control_1000, status_1000, phyreg; u8 *base = (u8 *) BASE; int i; /* BMSR_LSTATUS is latched, read it twice: * we want the current value. */ mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); #if 1 //yhlu for(i=0;i<30;i++) { mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); if((mii_status & BMSR_LSTATUS) && (mii_status & BMSR_ANEGCOMPLETE)) break; mdelay(100); } #endif if (!(mii_status & BMSR_LSTATUS)) { printf ("no link detected by phy - falling back to 10HD.\n"); newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10; newdup = 0; retval = 0; goto set_speed; } /* check auto negotiation is complete */ if (!(mii_status & BMSR_ANEGCOMPLETE)) { /* still in autonegotiation - configure nic for 10 MBit HD and wait. */ newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10; newdup = 0; retval = 0; printf("autoneg not completed - falling back to 10HD.\n"); goto set_speed; } retval = 1; if (np->gigabit == PHY_GIGABIT) { control_1000 = mii_rw(nic, np->phyaddr, MII_CTRL1000, MII_READ); status_1000 = mii_rw(nic, np->phyaddr, MII_STAT1000, MII_READ); if ((control_1000 & ADVERTISE_1000FULL) && (status_1000 & LPA_1000FULL)) { printf ("update_linkspeed: GBit ethernet detected.\n"); newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_1000; newdup = 1; goto set_speed; } } adv = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ); lpa = mii_rw(nic, np->phyaddr, MII_LPA, MII_READ); dprintf(("update_linkspeed: PHY advertises 0x%hX, lpa 0x%hX.\n", adv, lpa)); /* FIXME: handle parallel detection properly, handle gigabit ethernet */ lpa = lpa & adv; if (lpa & LPA_100FULL) { newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100; newdup = 1; } else if (lpa & LPA_100HALF) { newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100; newdup = 0; } else if (lpa & LPA_10FULL) { newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10; newdup = 1; } else if (lpa & LPA_10HALF) { newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10; newdup = 0; } else { printf("bad ability %hX - falling back to 10HD.\n", lpa); newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10; newdup = 0; } set_speed: if (np->duplex == newdup && np->linkspeed == newls) return retval; dprintf(("changing link setting from %d/%s to %d/%s.\n", np->linkspeed, np->duplex ? "Full-Duplex": "Half-Duplex", newls, newdup ? "Full-Duplex": "Half-Duplex")); np->duplex = newdup; np->linkspeed = newls; if (np->gigabit == PHY_GIGABIT) { phyreg = readl(base + NvRegRandomSeed); phyreg &= ~(0x3FF00); if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) phyreg |= NVREG_RNDSEED_FORCE3; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) phyreg |= NVREG_RNDSEED_FORCE2; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) phyreg |= NVREG_RNDSEED_FORCE; writel(phyreg, base + NvRegRandomSeed); } phyreg = readl(base + NvRegPhyInterface); phyreg &= ~(PHY_HALF | PHY_100 | PHY_1000); if (np->duplex == 0) phyreg |= PHY_HALF; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) phyreg |= PHY_100; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) phyreg |= PHY_1000; writel(phyreg, base + NvRegPhyInterface); writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD), base + NvRegMisc1); pci_push(base); writel(np->linkspeed, base + NvRegLinkSpeed); pci_push(base); return retval; } #if 0 /* Not used */ static void nv_linkchange(struct nic *nic) { if (update_linkspeed(nic)) { // if (netif_carrier_ok(nic)) { stop_rx(); //= } else { // netif_carrier_on(dev); // printk(KERN_INFO "%s: link up.\n", dev->name); // } start_rx(nic); } else { // if (netif_carrier_ok(dev)) { // netif_carrier_off(dev); // printk(KERN_INFO "%s: link down.\n", dev->name); stop_rx(); // } } } #endif static int init_ring(struct nic *nic) { int i; np->next_tx = np->nic_tx = 0; for (i = 0; i < TX_RING; i++) tx_ring[i].FlagLen = 0; np->cur_rx = 0; np->refill_rx = 0; for (i = 0; i < RX_RING; i++) rx_ring[i].FlagLen = 0; return alloc_rx(nic); } static void set_multicast(struct nic *nic) { u8 *base = (u8 *) BASE; u32 addr[2]; u32 mask[2]; u32 pff; u32 alwaysOff[2]; u32 alwaysOn[2]; memset(addr, 0, sizeof(addr)); memset(mask, 0, sizeof(mask)); pff = NVREG_PFF_MYADDR; alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0; addr[0] = alwaysOn[0]; addr[1] = alwaysOn[1]; mask[0] = alwaysOn[0] | alwaysOff[0]; mask[1] = alwaysOn[1] | alwaysOff[1]; addr[0] |= NVREG_MCASTADDRA_FORCE; pff |= NVREG_PFF_ALWAYS; stop_rx(); writel(addr[0], base + NvRegMulticastAddrA); writel(addr[1], base + NvRegMulticastAddrB); writel(mask[0], base + NvRegMulticastMaskA); writel(mask[1], base + NvRegMulticastMaskB); writel(pff, base + NvRegPacketFilterFlags); start_rx(nic); } /************************************************************************** RESET - Reset the NIC to prepare for use ***************************************************************************/ static int forcedeth_reset(struct nic *nic) { u8 *base = (u8 *) BASE; int ret, oom, i; ret = 0; dprintf(("forcedeth: open\n")); /* 1) erase previous misconfiguration */ /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */ writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); writel(0, base + NvRegMulticastAddrB); writel(0, base + NvRegMulticastMaskA); writel(0, base + NvRegMulticastMaskB); writel(0, base + NvRegPacketFilterFlags); writel(0, base + NvRegTransmitterControl); writel(0, base + NvRegReceiverControl); writel(0, base + NvRegAdapterControl); /* 2) initialize descriptor rings */ oom = init_ring(nic); writel(0, base + NvRegLinkSpeed); writel(0, base + NvRegUnknownTransmitterReg); txrx_reset(nic); writel(0, base + NvRegUnknownSetupReg6); np->in_shutdown = 0; /* 3) set mac address */ { u32 mac[2]; mac[0] = (nic->node_addr[0] << 0) + (nic->node_addr[1] << 8) + (nic->node_addr[2] << 16) + (nic->node_addr[3] << 24); mac[1] = (nic->node_addr[4] << 0) + (nic->node_addr[5] << 8); writel(mac[0], base + NvRegMacAddrA); writel(mac[1], base + NvRegMacAddrB); } /* 4) give hw rings */ writel((u32) virt_to_le32desc(&rx_ring[0]), base + NvRegRxRingPhysAddr); writel((u32) virt_to_le32desc(&tx_ring[0]), base + NvRegTxRingPhysAddr); writel(((RX_RING - 1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING - 1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); /* 5) continue setup */ np->linkspeed = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10; np->duplex = 0; writel(np->linkspeed, base + NvRegLinkSpeed); writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3); writel(np->desc_ver, base + NvRegTxRxControl); pci_push(base); writel(NVREG_TXRXCTL_BIT1 | np->desc_ver, base + NvRegTxRxControl); reg_delay(NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, "open: SetupReg5, Bit 31 remained off\n"); writel(0, base + NvRegUnknownSetupReg4); // writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); #if 0 printf("%d-Mbs Link, %s-Duplex\n", np->linkspeed & NVREG_LINKSPEED_10 ? 10 : 100, np->duplex ? "Full" : "Half"); #endif /* 6) continue setup */ writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1); writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags); writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig); writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus); /* Get a random number */ i = random(); writel(NVREG_RNDSEED_FORCE | (i & NVREG_RNDSEED_MASK), base + NvRegRandomSeed); writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1); writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2); writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval); writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6); writel((np-> phyaddr << NVREG_ADAPTCTL_PHYSHIFT) | NVREG_ADAPTCTL_PHYVALID | NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); writel(NVREG_MIISPEED_BIT8 | NVREG_MIIDELAY, base + NvRegMIISpeed); writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4); writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags); i = readl(base + NvRegPowerState); if ((i & NVREG_POWERSTATE_POWEREDUP) == 0) writel(NVREG_POWERSTATE_POWEREDUP | i, base + NvRegPowerState); pci_push(base); udelay(10); writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState); writel(0, base + NvRegIrqMask); pci_push(base); writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); pci_push(base); /* writel(np->irqmask, base + NvRegIrqMask); */ writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); writel(0, base + NvRegMulticastAddrB); writel(0, base + NvRegMulticastMaskA); writel(0, base + NvRegMulticastMaskB); writel(NVREG_PFF_ALWAYS | NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags); set_multicast(nic); /* One manual link speed update: Interrupts are enabled, future link * speed changes cause interrupts and are handled by nv_link_irq(). */ { u32 miistat; miistat = readl(base + NvRegMIIStatus); writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); dprintf(("startup: got 0x%hX.\n", miistat)); } ret = update_linkspeed(nic); //start_rx(nic); start_tx(nic); if (ret) { //Start Connection netif_carrier_on(dev); } else { printf("no link during initialization.\n"); } return ret; } /* * extern void hex_dump(const char *data, const unsigned int len); */ /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int forcedeth_poll(struct nic *nic, int retrieve) { /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ /* nic->packetlen should contain length of data */ int len; int i; u32 Flags; i = np->cur_rx % RX_RING; Flags = le32_to_cpu(rx_ring[i].FlagLen); len = nv_descr_getlength(&rx_ring[i], np->desc_ver); if (Flags & NV_RX_AVAIL) return 0; /* still owned by hardware, */ if (np->desc_ver == DESC_VER_1) { if (!(Flags & NV_RX_DESCRIPTORVALID)) return 0; } else { if (!(Flags & NV_RX2_DESCRIPTORVALID)) return 0; } if (!retrieve) return 1; /* got a valid packet - forward it to the network core */ nic->packetlen = len; memcpy(nic->packet, rxb + (i * RX_NIC_BUFSIZE), nic->packetlen); /* * hex_dump(rxb + (i * RX_NIC_BUFSIZE), len); */ wmb(); np->cur_rx++; alloc_rx(nic); return 1; } /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void forcedeth_transmit(struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) { /* Packet */ /* send the packet to destination */ u8 *ptxb; u16 nstype; u8 *base = (u8 *) BASE; int nr = np->next_tx % TX_RING; /* point to the current txb incase multiple tx_rings are used */ ptxb = txb + (nr * RX_NIC_BUFSIZE); //np->tx_skbuff[nr] = ptxb; /* copy the packet to ring buffer */ memcpy(ptxb, d, ETH_ALEN); /* dst */ memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */ nstype = htons((u16) t); /* type */ memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); /* type */ memcpy(ptxb + ETH_HLEN, p, s); s += ETH_HLEN; while (s < ETH_ZLEN) /* pad to min length */ ptxb[s++] = '\0'; tx_ring[nr].PacketBuffer = (u32) virt_to_le32desc(ptxb); wmb(); tx_ring[nr].FlagLen = cpu_to_le32((s - 1) | np->tx_flags); writel(NVREG_TXRXCTL_KICK | np->desc_ver, base + NvRegTxRxControl); pci_push(base); np->next_tx++; } /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void forcedeth_disable ( struct nic *nic __unused ) { /* put the card in its initial state */ /* This function serves 3 purposes. * This disables DMA and interrupts so we don't receive * unexpected packets or interrupts from the card after * etherboot has finished. * This frees resources so etherboot may use * this driver on another interface * This allows etherboot to reinitialize the interface * if something is something goes wrong. */ u8 *base = (u8 *) BASE; np->in_shutdown = 1; stop_tx(); stop_rx(); /* disable interrupts on the nic or we will lock up */ writel(0, base + NvRegIrqMask); pci_push(base); dprintf(("Irqmask is zero again\n")); /* specia op:o write back the misordered MAC address - otherwise * the next probe_nic would see a wrong address. */ writel(np->orig_mac[0], base + NvRegMacAddrA); writel(np->orig_mac[1], base + NvRegMacAddrB); } /************************************************************************** IRQ - Enable, Disable, or Force interrupts ***************************************************************************/ static void forcedeth_irq(struct nic *nic __unused, irq_action_t action __unused) { switch (action) { case DISABLE: break; case ENABLE: break; case FORCE: break; } } static struct nic_operations forcedeth_operations = { .connect = dummy_connect, .poll = forcedeth_poll, .transmit = forcedeth_transmit, .irq = forcedeth_irq, }; /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside ***************************************************************************/ #define IORESOURCE_MEM 0x00000200 #define board_found 1 #define valid_link 0 static int forcedeth_probe ( struct nic *nic, struct pci_device *pci ) { unsigned long addr; int sz; u8 *base; int i; struct pci_device_id *ids = pci->driver->ids; int id_count = pci->driver->id_count; unsigned int flags = 0; if (pci->ioaddr == 0) return 0; printf("forcedeth.c: Found %s, vendor=0x%hX, device=0x%hX\n", pci->driver_name, pci->vendor, pci->device); nic->ioaddr = pci->ioaddr; nic->irqno = 0; /* point to private storage */ np = &npx; adjust_pci_device(pci); addr = pci_bar_start(pci, PCI_BASE_ADDRESS_0); sz = pci_bar_size(pci, PCI_BASE_ADDRESS_0); /* BASE is used throughout to address the card */ BASE = (unsigned long) ioremap(addr, sz); if (!BASE) return 0; /* handle different descriptor versions */ if (pci->device == PCI_DEVICE_ID_NVIDIA_NVENET_1 || pci->device == PCI_DEVICE_ID_NVIDIA_NVENET_2 || pci->device == PCI_DEVICE_ID_NVIDIA_NVENET_3) np->desc_ver = DESC_VER_1; else np->desc_ver = DESC_VER_2; //rx_ring[0] = rx_ring; //tx_ring[0] = tx_ring; /* read the mac address */ base = (u8 *) BASE; np->orig_mac[0] = readl(base + NvRegMacAddrA); np->orig_mac[1] = readl(base + NvRegMacAddrB); /* lookup the flags from pci_device_id */ for(i = 0; i < id_count; i++) { if(pci->vendor == ids[i].vendor && pci->device == ids[i].device) { flags = ids[i].driver_data; break; } } /* read MAC address */ if(flags & MAC_ADDR_CORRECT) { nic->node_addr[0] = (np->orig_mac[0] >> 0) & 0xff; nic->node_addr[1] = (np->orig_mac[0] >> 8) & 0xff; nic->node_addr[2] = (np->orig_mac[0] >> 16) & 0xff; nic->node_addr[3] = (np->orig_mac[0] >> 24) & 0xff; nic->node_addr[4] = (np->orig_mac[1] >> 0) & 0xff; nic->node_addr[5] = (np->orig_mac[1] >> 8) & 0xff; } else { nic->node_addr[0] = (np->orig_mac[1] >> 8) & 0xff; nic->node_addr[1] = (np->orig_mac[1] >> 0) & 0xff; nic->node_addr[2] = (np->orig_mac[0] >> 24) & 0xff; nic->node_addr[3] = (np->orig_mac[0] >> 16) & 0xff; nic->node_addr[4] = (np->orig_mac[0] >> 8) & 0xff; nic->node_addr[5] = (np->orig_mac[0] >> 0) & 0xff; } #ifdef LINUX if (!is_valid_ether_addr(dev->dev_addr)) { /* * Bad mac address. At least one bios sets the mac address * to 01:23:45:67:89:ab */ printk(KERN_ERR "%s: Invalid Mac address detected: %02x:%02x:%02x:%02x:%02x:%02x\n", pci_name(pci_dev), dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); printk(KERN_ERR "Please complain to your hardware vendor. Switching to a random MAC.\n"); dev->dev_addr[0] = 0x00; dev->dev_addr[1] = 0x00; dev->dev_addr[2] = 0x6c; get_random_bytes(&dev->dev_addr[3], 3); } #endif DBG ( "%s: MAC Address %s\n", pci->driver_name, eth_ntoa ( nic->node_addr ) ); /* disable WOL */ writel(0, base + NvRegWakeUpFlags); np->wolenabled = 0; if (np->desc_ver == DESC_VER_1) { np->tx_flags = NV_TX_LASTPACKET | NV_TX_VALID; } else { np->tx_flags = NV_TX2_LASTPACKET | NV_TX2_VALID; } switch (pci->device) { case 0x01C3: // nforce // DEV_IRQMASK_1|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, np->irqmask = NVREG_IRQMASK_WANTED_2 | NVREG_IRQ_TIMER; // np->need_linktimer = 1; // np->link_timeout = jiffies + LINK_TIMEOUT; break; case 0x0066: /* Fall Through */ case 0x00D6: // DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER np->irqmask = NVREG_IRQMASK_WANTED_2; np->irqmask |= NVREG_IRQ_TIMER; // np->need_linktimer = 1; // np->link_timeout = jiffies + LINK_TIMEOUT; if (np->desc_ver == DESC_VER_1) np->tx_flags |= NV_TX_LASTPACKET1; else np->tx_flags |= NV_TX2_LASTPACKET1; break; case 0x0373: /* Fall Through */ case 0x0086: /* Fall Through */ case 0x008c: /* Fall Through */ case 0x00e6: /* Fall Through */ case 0x00df: /* Fall Through */ case 0x0056: /* Fall Through */ case 0x0057: /* Fall Through */ case 0x0037: /* Fall Through */ case 0x0038: //DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ np->irqmask = NVREG_IRQMASK_WANTED_2; np->irqmask |= NVREG_IRQ_TIMER; // np->need_linktimer = 1; // np->link_timeout = jiffies + LINK_TIMEOUT; if (np->desc_ver == DESC_VER_1) np->tx_flags |= NV_TX_LASTPACKET1; else np->tx_flags |= NV_TX2_LASTPACKET1; break; default: printf ("Your card was undefined in this driver. Review driver_data in Linux driver and send a patch\n"); } /* find a suitable phy */ for (i = 1; i < 32; i++) { int id1, id2; id1 = mii_rw(nic, i, MII_PHYSID1, MII_READ); if (id1 < 0 || id1 == 0xffff) continue; id2 = mii_rw(nic, i, MII_PHYSID2, MII_READ); if (id2 < 0 || id2 == 0xffff) continue; id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT; id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT; dprintf (("%s: open: Found PHY %hX:%hX at address %d.\n", pci->driver_name, id1, id2, i)); np->phyaddr = i; np->phy_oui = id1 | id2; break; } if (i == 32) { /* PHY in isolate mode? No phy attached and user wants to * test loopback? Very odd, but can be correct. */ printf ("%s: open: Could not find a valid PHY.\n", pci->driver_name); } if (i != 32) { /* reset it */ phy_init(nic); } dprintf(("%s: forcedeth.c: subsystem: %hX:%hX bound to %s\n", pci->driver_name, pci->vendor, pci->dev_id, pci->driver_name)); if(!forcedeth_reset(nic)) return 0; // no valid link /* point to NIC specific routines */ nic->nic_op = &forcedeth_operations; return 1; } static struct pci_device_id forcedeth_nics[] = { PCI_ROM(0x10de, 0x01C3, "nforce", "nForce NVENET_1 Ethernet Controller", 0), PCI_ROM(0x10de, 0x0066, "nforce2", "nForce NVENET_2 Ethernet Controller", 0), PCI_ROM(0x10de, 0x00D6, "nforce3", "nForce NVENET_3 Ethernet Controller", 0), PCI_ROM(0x10de, 0x0086, "nforce4", "nForce NVENET_4 Ethernet Controller", 0), PCI_ROM(0x10de, 0x008c, "nforce5", "nForce NVENET_5 Ethernet Controller", 0), PCI_ROM(0x10de, 0x00e6, "nforce6", "nForce NVENET_6 Ethernet Controller", 0), PCI_ROM(0x10de, 0x00df, "nforce7", "nForce NVENET_7 Ethernet Controller", 0), PCI_ROM(0x10de, 0x0056, "nforce8", "nForce NVENET_8 Ethernet Controller", 0), PCI_ROM(0x10de, 0x0057, "nforce9", "nForce NVENET_9 Ethernet Controller", 0), PCI_ROM(0x10de, 0x0037, "nforce10", "nForce NVENET_10 Ethernet Controller", 0), PCI_ROM(0x10de, 0x0038, "nforce11", "nForce NVENET_11 Ethernet Controller", 0), PCI_ROM(0x10de, 0x0373, "nforce15", "nForce NVENET_15 Ethernet Controller", 0), PCI_ROM(0x10de, 0x0269, "nforce16", "nForce NVENET_16 Ethernet Controller", 0), PCI_ROM(0x10de, 0x0760, "nforce17", "nForce NVENET_17 Ethernet Controller", MAC_ADDR_CORRECT), }; PCI_DRIVER ( forcedeth_driver, forcedeth_nics, PCI_NO_CLASS ); DRIVER ( "forcedeth", nic_driver, pci_driver, forcedeth_driver, forcedeth_probe, forcedeth_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/ns83820.c0000664000000000000000000006547512524662415020421 0ustar /************************************************************************** * ns83820.c: Etherboot device driver for the National Semiconductor 83820 * Written 2004 by Timothy Legge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Portions of this code based on: * ns83820.c by Benjamin LaHaise with contributions * for Linux kernel 2.4.x. * * Linux Driver Version 0.20, 20020610 * * This development of this Etherboot driver was funded by: * * NXTV: http://www.nxtv.com/ * * REVISION HISTORY: * ================ * * v1.0 02-16-2004 timlegge Initial port of Linux driver * v1.1 02-19-2004 timlegge More rohbust transmit and poll * * Indent Options: indent -kr -i8 ***************************************************************************/ FILE_LICENCE ( GPL2_OR_LATER ); /* to get some global routines like printf */ #include "etherboot.h" /* to get the interface to the body of the program */ #include "nic.h" /* to get the PCI support functions, if this is a PCI NIC */ #include #if ARCH == ia64 /* Support 64-bit addressing */ #define USE_64BIT_ADDR #endif //#define DDEBUG #ifdef DDEBUG #define dprintf(x) printf x #else #define dprintf(x) #endif #define HZ 100 /* Condensed operations for readability. */ #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) /* NIC specific static variables go here */ /* Global parameters. See MODULE_PARM near the bottom. */ // static int ihr = 2; static int reset_phy = 0; static int lnksts = 0; /* CFG_LNKSTS bit polarity */ #if defined(CONFIG_HIGHMEM64G) || defined(__ia64__) #define USE_64BIT_ADDR "+" #endif #if defined(USE_64BIT_ADDR) #define TRY_DAC 1 #else #define TRY_DAC 0 #endif /* tunables */ #define RX_BUF_SIZE 1500 /* 8192 */ /* Must not exceed ~65000. */ #define NR_RX_DESC 64 #define NR_TX_DESC 1 /* not tunable *//* Extra 6 bytes for 64 bit alignment (divisable by 8) */ #define REAL_RX_BUF_SIZE (RX_BUF_SIZE + 14 + 6) /* rx/tx mac addr + type */ #define MIN_TX_DESC_FREE 8 /* register defines */ #define CFGCS 0x04 #define CR_TXE 0x00000001 #define CR_TXD 0x00000002 /* Ramit : Here's a tip, don't do a RXD immediately followed by an RXE * The Receive engine skips one descriptor and moves * onto the next one!! */ #define CR_RXE 0x00000004 #define CR_RXD 0x00000008 #define CR_TXR 0x00000010 #define CR_RXR 0x00000020 #define CR_SWI 0x00000080 #define CR_RST 0x00000100 #define PTSCR_EEBIST_FAIL 0x00000001 #define PTSCR_EEBIST_EN 0x00000002 #define PTSCR_EELOAD_EN 0x00000004 #define PTSCR_RBIST_FAIL 0x000001b8 #define PTSCR_RBIST_DONE 0x00000200 #define PTSCR_RBIST_EN 0x00000400 #define PTSCR_RBIST_RST 0x00002000 #define MEAR_EEDI 0x00000001 #define MEAR_EEDO 0x00000002 #define MEAR_EECLK 0x00000004 #define MEAR_EESEL 0x00000008 #define MEAR_MDIO 0x00000010 #define MEAR_MDDIR 0x00000020 #define MEAR_MDC 0x00000040 #define ISR_TXDESC3 0x40000000 #define ISR_TXDESC2 0x20000000 #define ISR_TXDESC1 0x10000000 #define ISR_TXDESC0 0x08000000 #define ISR_RXDESC3 0x04000000 #define ISR_RXDESC2 0x02000000 #define ISR_RXDESC1 0x01000000 #define ISR_RXDESC0 0x00800000 #define ISR_TXRCMP 0x00400000 #define ISR_RXRCMP 0x00200000 #define ISR_DPERR 0x00100000 #define ISR_SSERR 0x00080000 #define ISR_RMABT 0x00040000 #define ISR_RTABT 0x00020000 #define ISR_RXSOVR 0x00010000 #define ISR_HIBINT 0x00008000 #define ISR_PHY 0x00004000 #define ISR_PME 0x00002000 #define ISR_SWI 0x00001000 #define ISR_MIB 0x00000800 #define ISR_TXURN 0x00000400 #define ISR_TXIDLE 0x00000200 #define ISR_TXERR 0x00000100 #define ISR_TXDESC 0x00000080 #define ISR_TXOK 0x00000040 #define ISR_RXORN 0x00000020 #define ISR_RXIDLE 0x00000010 #define ISR_RXEARLY 0x00000008 #define ISR_RXERR 0x00000004 #define ISR_RXDESC 0x00000002 #define ISR_RXOK 0x00000001 #define TXCFG_CSI 0x80000000 #define TXCFG_HBI 0x40000000 #define TXCFG_MLB 0x20000000 #define TXCFG_ATP 0x10000000 #define TXCFG_ECRETRY 0x00800000 #define TXCFG_BRST_DIS 0x00080000 #define TXCFG_MXDMA1024 0x00000000 #define TXCFG_MXDMA512 0x00700000 #define TXCFG_MXDMA256 0x00600000 #define TXCFG_MXDMA128 0x00500000 #define TXCFG_MXDMA64 0x00400000 #define TXCFG_MXDMA32 0x00300000 #define TXCFG_MXDMA16 0x00200000 #define TXCFG_MXDMA8 0x00100000 #define CFG_LNKSTS 0x80000000 #define CFG_SPDSTS 0x60000000 #define CFG_SPDSTS1 0x40000000 #define CFG_SPDSTS0 0x20000000 #define CFG_DUPSTS 0x10000000 #define CFG_TBI_EN 0x01000000 #define CFG_MODE_1000 0x00400000 /* Ramit : Dont' ever use AUTO_1000, it never works and is buggy. * Read the Phy response and then configure the MAC accordingly */ #define CFG_AUTO_1000 0x00200000 #define CFG_PINT_CTL 0x001c0000 #define CFG_PINT_DUPSTS 0x00100000 #define CFG_PINT_LNKSTS 0x00080000 #define CFG_PINT_SPDSTS 0x00040000 #define CFG_TMRTEST 0x00020000 #define CFG_MRM_DIS 0x00010000 #define CFG_MWI_DIS 0x00008000 #define CFG_T64ADDR 0x00004000 #define CFG_PCI64_DET 0x00002000 #define CFG_DATA64_EN 0x00001000 #define CFG_M64ADDR 0x00000800 #define CFG_PHY_RST 0x00000400 #define CFG_PHY_DIS 0x00000200 #define CFG_EXTSTS_EN 0x00000100 #define CFG_REQALG 0x00000080 #define CFG_SB 0x00000040 #define CFG_POW 0x00000020 #define CFG_EXD 0x00000010 #define CFG_PESEL 0x00000008 #define CFG_BROM_DIS 0x00000004 #define CFG_EXT_125 0x00000002 #define CFG_BEM 0x00000001 #define EXTSTS_UDPPKT 0x00200000 #define EXTSTS_TCPPKT 0x00080000 #define EXTSTS_IPPKT 0x00020000 #define SPDSTS_POLARITY (CFG_SPDSTS1 | CFG_SPDSTS0 | CFG_DUPSTS | (lnksts ? CFG_LNKSTS : 0)) #define MIBC_MIBS 0x00000008 #define MIBC_ACLR 0x00000004 #define MIBC_FRZ 0x00000002 #define MIBC_WRN 0x00000001 #define PCR_PSEN (1 << 31) #define PCR_PS_MCAST (1 << 30) #define PCR_PS_DA (1 << 29) #define PCR_STHI_8 (3 << 23) #define PCR_STLO_4 (1 << 23) #define PCR_FFHI_8K (3 << 21) #define PCR_FFLO_4K (1 << 21) #define PCR_PAUSE_CNT 0xFFFE #define RXCFG_AEP 0x80000000 #define RXCFG_ARP 0x40000000 #define RXCFG_STRIPCRC 0x20000000 #define RXCFG_RX_FD 0x10000000 #define RXCFG_ALP 0x08000000 #define RXCFG_AIRL 0x04000000 #define RXCFG_MXDMA512 0x00700000 #define RXCFG_DRTH 0x0000003e #define RXCFG_DRTH0 0x00000002 #define RFCR_RFEN 0x80000000 #define RFCR_AAB 0x40000000 #define RFCR_AAM 0x20000000 #define RFCR_AAU 0x10000000 #define RFCR_APM 0x08000000 #define RFCR_APAT 0x07800000 #define RFCR_APAT3 0x04000000 #define RFCR_APAT2 0x02000000 #define RFCR_APAT1 0x01000000 #define RFCR_APAT0 0x00800000 #define RFCR_AARP 0x00400000 #define RFCR_MHEN 0x00200000 #define RFCR_UHEN 0x00100000 #define RFCR_ULM 0x00080000 #define VRCR_RUDPE 0x00000080 #define VRCR_RTCPE 0x00000040 #define VRCR_RIPE 0x00000020 #define VRCR_IPEN 0x00000010 #define VRCR_DUTF 0x00000008 #define VRCR_DVTF 0x00000004 #define VRCR_VTREN 0x00000002 #define VRCR_VTDEN 0x00000001 #define VTCR_PPCHK 0x00000008 #define VTCR_GCHK 0x00000004 #define VTCR_VPPTI 0x00000002 #define VTCR_VGTI 0x00000001 #define CR 0x00 #define CFG 0x04 #define MEAR 0x08 #define PTSCR 0x0c #define ISR 0x10 #define IMR 0x14 #define IER 0x18 #define IHR 0x1c #define TXDP 0x20 #define TXDP_HI 0x24 #define TXCFG 0x28 #define GPIOR 0x2c #define RXDP 0x30 #define RXDP_HI 0x34 #define RXCFG 0x38 #define PQCR 0x3c #define WCSR 0x40 #define PCR 0x44 #define RFCR 0x48 #define RFDR 0x4c #define SRR 0x58 #define VRCR 0xbc #define VTCR 0xc0 #define VDR 0xc4 #define CCSR 0xcc #define TBICR 0xe0 #define TBISR 0xe4 #define TANAR 0xe8 #define TANLPAR 0xec #define TANER 0xf0 #define TESR 0xf4 #define TBICR_MR_AN_ENABLE 0x00001000 #define TBICR_MR_RESTART_AN 0x00000200 #define TBISR_MR_LINK_STATUS 0x00000020 #define TBISR_MR_AN_COMPLETE 0x00000004 #define TANAR_PS2 0x00000100 #define TANAR_PS1 0x00000080 #define TANAR_HALF_DUP 0x00000040 #define TANAR_FULL_DUP 0x00000020 #define GPIOR_GP5_OE 0x00000200 #define GPIOR_GP4_OE 0x00000100 #define GPIOR_GP3_OE 0x00000080 #define GPIOR_GP2_OE 0x00000040 #define GPIOR_GP1_OE 0x00000020 #define GPIOR_GP3_OUT 0x00000004 #define GPIOR_GP1_OUT 0x00000001 #define LINK_AUTONEGOTIATE 0x01 #define LINK_DOWN 0x02 #define LINK_UP 0x04 #define __kick_rx() writel(CR_RXE, ns->base + CR) #define kick_rx() do { \ dprintf(("kick_rx: maybe kicking\n")); \ writel(virt_to_le32desc(&rx_ring[ns->cur_rx]), ns->base + RXDP); \ if (ns->next_rx == ns->next_empty) \ printf("uh-oh: next_rx == next_empty???\n"); \ __kick_rx(); \ } while(0) #ifdef USE_64BIT_ADDR #define HW_ADDR_LEN 8 #else #define HW_ADDR_LEN 4 #endif #define CMDSTS_OWN 0x80000000 #define CMDSTS_MORE 0x40000000 #define CMDSTS_INTR 0x20000000 #define CMDSTS_ERR 0x10000000 #define CMDSTS_OK 0x08000000 #define CMDSTS_LEN_MASK 0x0000ffff #define CMDSTS_DEST_MASK 0x01800000 #define CMDSTS_DEST_SELF 0x00800000 #define CMDSTS_DEST_MULTI 0x01000000 #define DESC_SIZE 8 /* Should be cache line sized */ #ifdef USE_64BIT_ADDR struct ring_desc { uint64_t link; uint64_t bufptr; u32 cmdsts; u32 extsts; /* Extended status field */ }; #else struct ring_desc { u32 link; u32 bufptr; u32 cmdsts; u32 extsts; /* Extended status field */ }; #endif /* Private Storage for the NIC */ static struct ns83820_private { u8 *base; int up; long idle; u32 *next_rx_desc; u16 next_rx, next_empty; u32 cur_rx; u32 *descs; unsigned ihr; u32 CFG_cache; u32 MEAR_cache; u32 IMR_cache; int linkstate; u16 tx_done_idx; u16 tx_idx; u16 tx_intr_idx; u32 phy_descs; u32 *tx_descs; } nsx; static struct ns83820_private *ns; /* Define the TX and RX Descriptor and Buffers */ struct { struct ring_desc tx_ring[NR_TX_DESC] __attribute__ ((aligned(8))); unsigned char txb[NR_TX_DESC * REAL_RX_BUF_SIZE]; struct ring_desc rx_ring[NR_RX_DESC] __attribute__ ((aligned(8))); unsigned char rxb[NR_RX_DESC * REAL_RX_BUF_SIZE] __attribute__ ((aligned(8))); } ns83820_bufs __shared; #define tx_ring ns83820_bufs.tx_ring #define rx_ring ns83820_bufs.rx_ring #define txb ns83820_bufs.txb #define rxb ns83820_bufs.rxb static void phy_intr(struct nic *nic __unused) { static char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" }; u32 cfg, new_cfg; u32 tbisr, tanar, tanlpar; int speed, fullduplex, newlinkstate; cfg = readl(ns->base + CFG) ^ SPDSTS_POLARITY; if (ns->CFG_cache & CFG_TBI_EN) { /* we have an optical transceiver */ tbisr = readl(ns->base + TBISR); tanar = readl(ns->base + TANAR); tanlpar = readl(ns->base + TANLPAR); dprintf(("phy_intr: tbisr=%hX, tanar=%hX, tanlpar=%hX\n", tbisr, tanar, tanlpar)); if ((fullduplex = (tanlpar & TANAR_FULL_DUP) && (tanar & TANAR_FULL_DUP))) { /* both of us are full duplex */ writel(readl(ns->base + TXCFG) | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP, ns->base + TXCFG); writel(readl(ns->base + RXCFG) | RXCFG_RX_FD, ns->base + RXCFG); /* Light up full duplex LED */ writel(readl(ns->base + GPIOR) | GPIOR_GP1_OUT, ns->base + GPIOR); } else if (((tanlpar & TANAR_HALF_DUP) && (tanar & TANAR_HALF_DUP)) || ((tanlpar & TANAR_FULL_DUP) && (tanar & TANAR_HALF_DUP)) || ((tanlpar & TANAR_HALF_DUP) && (tanar & TANAR_FULL_DUP))) { /* one or both of us are half duplex */ writel((readl(ns->base + TXCFG) & ~(TXCFG_CSI | TXCFG_HBI)) | TXCFG_ATP, ns->base + TXCFG); writel(readl(ns->base + RXCFG) & ~RXCFG_RX_FD, ns->base + RXCFG); /* Turn off full duplex LED */ writel(readl(ns->base + GPIOR) & ~GPIOR_GP1_OUT, ns->base + GPIOR); } speed = 4; /* 1000F */ } else { /* we have a copper transceiver */ new_cfg = ns->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS); if (cfg & CFG_SPDSTS1) new_cfg |= CFG_MODE_1000; else new_cfg &= ~CFG_MODE_1000; speed = ((cfg / CFG_SPDSTS0) & 3); fullduplex = (cfg & CFG_DUPSTS); if (fullduplex) new_cfg |= CFG_SB; if ((cfg & CFG_LNKSTS) && ((new_cfg ^ ns->CFG_cache) & CFG_MODE_1000)) { writel(new_cfg, ns->base + CFG); ns->CFG_cache = new_cfg; } ns->CFG_cache &= ~CFG_SPDSTS; ns->CFG_cache |= cfg & CFG_SPDSTS; } newlinkstate = (cfg & CFG_LNKSTS) ? LINK_UP : LINK_DOWN; if (newlinkstate & LINK_UP && ns->linkstate != newlinkstate) { printf("link now %s mbps, %s duplex and up.\n", speeds[speed], fullduplex ? "full" : "half"); } else if (newlinkstate & LINK_DOWN && ns->linkstate != newlinkstate) { printf("link now down.\n"); } ns->linkstate = newlinkstate; } static void ns83820_set_multicast(struct nic *nic __unused); static void ns83820_setup_rx(struct nic *nic) { unsigned i; ns->idle = 1; ns->next_rx = 0; ns->next_rx_desc = ns->descs; ns->next_empty = 0; ns->cur_rx = 0; for (i = 0; i < NR_RX_DESC; i++) { rx_ring[i].link = virt_to_le32desc(&rx_ring[i + 1]); rx_ring[i].bufptr = virt_to_le32desc(&rxb[i * REAL_RX_BUF_SIZE]); rx_ring[i].cmdsts = cpu_to_le32(REAL_RX_BUF_SIZE); rx_ring[i].extsts = cpu_to_le32(0); } // No need to wrap the ring // rx_ring[i].link = virt_to_le32desc(&rx_ring[0]); writel(0, ns->base + RXDP_HI); writel(virt_to_le32desc(&rx_ring[0]), ns->base + RXDP); dprintf(("starting receiver\n")); writel(0x0001, ns->base + CCSR); writel(0, ns->base + RFCR); writel(0x7fc00000, ns->base + RFCR); writel(0xffc00000, ns->base + RFCR); ns->up = 1; phy_intr(nic); /* Okay, let it rip */ ns->IMR_cache |= ISR_PHY; ns->IMR_cache |= ISR_RXRCMP; //dev->IMR_cache |= ISR_RXERR; //dev->IMR_cache |= ISR_RXOK; ns->IMR_cache |= ISR_RXORN; ns->IMR_cache |= ISR_RXSOVR; ns->IMR_cache |= ISR_RXDESC; ns->IMR_cache |= ISR_RXIDLE; ns->IMR_cache |= ISR_TXDESC; ns->IMR_cache |= ISR_TXIDLE; // No reason to enable interupts... // writel(ns->IMR_cache, ns->base + IMR); // writel(1, ns->base + IER); ns83820_set_multicast(nic); kick_rx(); } static void ns83820_do_reset(struct nic *nic __unused, u32 which) { dprintf(("resetting chip...\n")); writel(which, ns->base + CR); do { } while (readl(ns->base + CR) & which); dprintf(("okay!\n")); } static void ns83820_reset(struct nic *nic) { unsigned i; dprintf(("ns83820_reset\n")); writel(0, ns->base + PQCR); ns83820_setup_rx(nic); for (i = 0; i < NR_TX_DESC; i++) { tx_ring[i].link = 0; tx_ring[i].bufptr = 0; tx_ring[i].cmdsts = cpu_to_le32(0); tx_ring[i].extsts = cpu_to_le32(0); } ns->tx_idx = 0; ns->tx_done_idx = 0; writel(0, ns->base + TXDP_HI); return; } static void ns83820_getmac(struct nic *nic __unused, u8 * mac) { unsigned i; for (i = 0; i < 3; i++) { u32 data; /* Read from the perfect match memory: this is loaded by * the chip from the EEPROM via the EELOAD self test. */ writel(i * 2, ns->base + RFCR); data = readl(ns->base + RFDR); *mac++ = data; *mac++ = data >> 8; } } static void ns83820_set_multicast(struct nic *nic __unused) { u8 *rfcr = ns->base + RFCR; u32 and_mask = 0xffffffff; u32 or_mask = 0; u32 val; /* Support Multicast */ and_mask &= ~(RFCR_AAU | RFCR_AAM); or_mask |= RFCR_AAM; val = (readl(rfcr) & and_mask) | or_mask; /* Ramit : RFCR Write Fix doc says RFEN must be 0 modify other bits */ writel(val & ~RFCR_RFEN, rfcr); writel(val, rfcr); } static void ns83820_run_bist(struct nic *nic __unused, const char *name, u32 enable, u32 done, u32 fail) { int timed_out = 0; long start; u32 status; int loops = 0; dprintf(("start %s\n", name)) start = currticks(); writel(enable, ns->base + PTSCR); for (;;) { loops++; status = readl(ns->base + PTSCR); if (!(status & enable)) break; if (status & done) break; if (status & fail) break; if ((currticks() - start) >= HZ) { timed_out = 1; break; } } if (status & fail) printf("%s failed! (0x%hX & 0x%hX)\n", name, (unsigned int) status, (unsigned int) fail); else if (timed_out) printf("run_bist %s timed out! (%hX)\n", name, (unsigned int) status); dprintf(("done %s in %d loops\n", name, loops)); } /************************************* Check Link *************************************/ static void ns83820_check_intr(struct nic *nic) { int i; u32 isr = readl(ns->base + ISR); if(ISR_PHY & isr) phy_intr(nic); if(( ISR_RXIDLE | ISR_RXDESC | ISR_RXERR) & isr) kick_rx(); for (i = 0; i < NR_RX_DESC; i++) { if (rx_ring[i].cmdsts == CMDSTS_OWN) { // rx_ring[i].link = virt_to_le32desc(&rx_ring[i + 1]); rx_ring[i].cmdsts = cpu_to_le32(REAL_RX_BUF_SIZE); } } } /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int ns83820_poll(struct nic *nic, int retrieve) { /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ /* nic->packetlen should contain length of data */ u32 cmdsts; int entry = ns->cur_rx; ns83820_check_intr(nic); cmdsts = le32_to_cpu(rx_ring[entry].cmdsts); if ( ! ( (CMDSTS_OWN & (cmdsts)) && (cmdsts != (CMDSTS_OWN)) ) ) return 0; if ( ! retrieve ) return 1; if (! (CMDSTS_OK & cmdsts) ) return 0; nic->packetlen = cmdsts & 0xffff; memcpy(nic->packet, rxb + (entry * REAL_RX_BUF_SIZE), nic->packetlen); // rx_ring[entry].link = 0; rx_ring[entry].cmdsts = cpu_to_le32(CMDSTS_OWN); ns->cur_rx = ++ns->cur_rx % NR_RX_DESC; if (ns->cur_rx == 0) /* We have wrapped the ring */ kick_rx(); return 1; } static inline void kick_tx(struct nic *nic __unused) { dprintf(("kick_tx\n")); writel(CR_TXE, ns->base + CR); } /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void ns83820_transmit(struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) { /* Packet */ /* send the packet to destination */ u16 nstype; u32 cmdsts, extsts; int cur_tx = 0; u32 isr = readl(ns->base + ISR); if (ISR_TXIDLE & isr) kick_tx(nic); /* point to the current txb incase multiple tx_rings are used */ memcpy(txb, d, ETH_ALEN); memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN); nstype = htons((u16) t); memcpy(txb + 2 * ETH_ALEN, (u8 *) & nstype, 2); memcpy(txb + ETH_HLEN, p, s); s += ETH_HLEN; s &= 0x0FFF; while (s < ETH_ZLEN) txb[s++] = '\0'; /* Setup the transmit descriptor */ extsts = 0; extsts |= EXTSTS_UDPPKT; tx_ring[cur_tx].bufptr = virt_to_le32desc(&txb); tx_ring[cur_tx].extsts = cpu_to_le32(extsts); cmdsts = cpu_to_le32(0); cmdsts |= cpu_to_le32(CMDSTS_OWN | s); tx_ring[cur_tx].cmdsts = cpu_to_le32(cmdsts); writel(virt_to_le32desc(&tx_ring[0]), ns->base + TXDP); kick_tx(nic); } /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void ns83820_disable ( struct nic *nic ) { /* put the card in its initial state */ /* This function serves 3 purposes. * This disables DMA and interrupts so we don't receive * unexpected packets or interrupts from the card after * etherboot has finished. * This frees resources so etherboot may use * this driver on another interface * This allows etherboot to reinitialize the interface * if something is something goes wrong. */ /* disable interrupts */ writel(0, ns->base + IMR); writel(0, ns->base + IER); readl(ns->base + IER); ns->up = 0; ns83820_do_reset(nic, CR_RST); ns->IMR_cache &= ~(ISR_RXOK | ISR_RXDESC | ISR_RXERR | ISR_RXEARLY | ISR_RXIDLE); writel(ns->IMR_cache, ns->base + IMR); /* touch the pci bus... */ readl(ns->base + IMR); /* assumes the transmitter is already disabled and reset */ writel(0, ns->base + RXDP_HI); writel(0, ns->base + RXDP); } /************************************************************************** IRQ - Enable, Disable, or Force interrupts ***************************************************************************/ static void ns83820_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } static struct nic_operations ns83820_operations = { .connect = dummy_connect, .poll = ns83820_poll, .transmit = ns83820_transmit, .irq = ns83820_irq, }; static struct pci_device_id ns83820_nics[] = { PCI_ROM(0x100b, 0x0022, "ns83820", "National Semiconductor 83820", 0), }; PCI_DRIVER ( ns83820_driver, ns83820_nics, PCI_NO_CLASS ); /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside ***************************************************************************/ #define board_found 1 #define valid_link 0 static int ns83820_probe ( struct nic *nic, struct pci_device *pci ) { long addr; int using_dac = 0; if (pci->ioaddr == 0) return 0; printf("ns83820.c: vendor=0x%hX, device=0x%hX\n", pci->vendor, pci->device); /* point to private storage */ ns = &nsx; adjust_pci_device(pci); addr = pci_bar_start(pci, PCI_BASE_ADDRESS_1); ns->base = ioremap(addr, (1UL << 12)); if (!ns->base) return 0; nic->irqno = 0; nic->ioaddr = pci->ioaddr & ~3; /* disable interrupts */ writel(0, ns->base + IMR); writel(0, ns->base + IER); readl(ns->base + IER); ns->IMR_cache = 0; ns83820_do_reset(nic, CR_RST); /* Must reset the ram bist before running it */ writel(PTSCR_RBIST_RST, ns->base + PTSCR); ns83820_run_bist(nic, "sram bist", PTSCR_RBIST_EN, PTSCR_RBIST_DONE, PTSCR_RBIST_FAIL); ns83820_run_bist(nic, "eeprom bist", PTSCR_EEBIST_EN, 0, PTSCR_EEBIST_FAIL); ns83820_run_bist(nic, "eeprom load", PTSCR_EELOAD_EN, 0, 0); /* I love config registers */ ns->CFG_cache = readl(ns->base + CFG); if ((ns->CFG_cache & CFG_PCI64_DET)) { printf("detected 64 bit PCI data bus.\n"); /*dev->CFG_cache |= CFG_DATA64_EN; */ if (!(ns->CFG_cache & CFG_DATA64_EN)) printf ("EEPROM did not enable 64 bit bus. Disabled.\n"); } else ns->CFG_cache &= ~(CFG_DATA64_EN); ns->CFG_cache &= (CFG_TBI_EN | CFG_MRM_DIS | CFG_MWI_DIS | CFG_T64ADDR | CFG_DATA64_EN | CFG_EXT_125 | CFG_M64ADDR); ns->CFG_cache |= CFG_PINT_DUPSTS | CFG_PINT_LNKSTS | CFG_PINT_SPDSTS | CFG_EXTSTS_EN | CFG_EXD | CFG_PESEL; ns->CFG_cache |= CFG_REQALG; ns->CFG_cache |= CFG_POW; ns->CFG_cache |= CFG_TMRTEST; /* When compiled with 64 bit addressing, we must always enable * the 64 bit descriptor format. */ #ifdef USE_64BIT_ADDR ns->CFG_cache |= CFG_M64ADDR; #endif //FIXME: Enable section on dac or remove this if (using_dac) ns->CFG_cache |= CFG_T64ADDR; /* Big endian mode does not seem to do what the docs suggest */ ns->CFG_cache &= ~CFG_BEM; /* setup optical transceiver if we have one */ if (ns->CFG_cache & CFG_TBI_EN) { dprintf(("%s: enabling optical transceiver\n", pci->driver_name)); writel(readl(ns->base + GPIOR) | 0x3e8, ns->base + GPIOR); /* setup auto negotiation feature advertisement */ writel(readl(ns->base + TANAR) | TANAR_HALF_DUP | TANAR_FULL_DUP, ns->base + TANAR); /* start auto negotiation */ writel(TBICR_MR_AN_ENABLE | TBICR_MR_RESTART_AN, ns->base + TBICR); writel(TBICR_MR_AN_ENABLE, ns->base + TBICR); ns->linkstate = LINK_AUTONEGOTIATE; ns->CFG_cache |= CFG_MODE_1000; } writel(ns->CFG_cache, ns->base + CFG); dprintf(("CFG: %hX\n", ns->CFG_cache)); /* FIXME: reset_phy is defaulted to 0, should we reset anyway? */ if (reset_phy) { dprintf(("%s: resetting phy\n", pci->driver_name)); writel(ns->CFG_cache | CFG_PHY_RST, ns->base + CFG); writel(ns->CFG_cache, ns->base + CFG); } #if 0 /* Huh? This sets the PCI latency register. Should be done via * the PCI layer. FIXME. */ if (readl(dev->base + SRR)) writel(readl(dev->base + 0x20c) | 0xfe00, dev->base + 0x20c); #endif /* Note! The DMA burst size interacts with packet * transmission, such that the largest packet that * can be transmitted is 8192 - FLTH - burst size. * If only the transmit fifo was larger... */ /* Ramit : 1024 DMA is not a good idea, it ends up banging * some DELL and COMPAQ SMP systems */ writel(TXCFG_CSI | TXCFG_HBI | TXCFG_ATP | TXCFG_MXDMA512 | ((1600 / 32) * 0x100), ns->base + TXCFG); /* Set Rx to full duplex, don't accept runt, errored, long or length * range errored packets. Use 512 byte DMA. */ /* Ramit : 1024 DMA is not a good idea, it ends up banging * some DELL and COMPAQ SMP systems * Turn on ALP, only we are accpeting Jumbo Packets */ writel(RXCFG_AEP | RXCFG_ARP | RXCFG_AIRL | RXCFG_RX_FD | RXCFG_STRIPCRC //| RXCFG_ALP | (RXCFG_MXDMA512) | 0, ns->base + RXCFG); /* Disable priority queueing */ writel(0, ns->base + PQCR); /* Enable IP checksum validation and detetion of VLAN headers. * Note: do not set the reject options as at least the 0x102 * revision of the chip does not properly accept IP fragments * at least for UDP. */ /* Ramit : Be sure to turn on RXCFG_ARP if VLAN's are enabled, since * the MAC it calculates the packetsize AFTER stripping the VLAN * header, and if a VLAN Tagged packet of 64 bytes is received (like * a ping with a VLAN header) then the card, strips the 4 byte VLAN * tag and then checks the packet size, so if RXCFG_ARP is not enabled, * it discrards it!. These guys...... */ writel(VRCR_IPEN | VRCR_VTDEN, ns->base + VRCR); /* Enable per-packet TCP/UDP/IP checksumming */ writel(VTCR_PPCHK, ns->base + VTCR); /* Ramit : Enable async and sync pause frames */ // writel(0, ns->base + PCR); writel((PCR_PS_MCAST | PCR_PS_DA | PCR_PSEN | PCR_FFLO_4K | PCR_FFHI_8K | PCR_STLO_4 | PCR_STHI_8 | PCR_PAUSE_CNT), ns->base + PCR); /* Disable Wake On Lan */ writel(0, ns->base + WCSR); ns83820_getmac(nic, nic->node_addr); if (using_dac) { dprintf(("%s: using 64 bit addressing.\n", pci->driver_name)); } dprintf(("%s: DP83820 %d.%d: %! io=0x%hX\n", pci->driver_name, (unsigned) readl(ns->base + SRR) >> 8, (unsigned) readl(ns->base + SRR) & 0xff, nic->node_addr, pci->ioaddr)); #ifdef PHY_CODE_IS_FINISHED ns83820_probe_phy(dev); #endif ns83820_reset(nic); /* point to NIC specific routines */ nic->nic_op = &ns83820_operations; return 1; } DRIVER ( "NS83820/PCI", nic_driver, pci_driver, ns83820_driver, ns83820_probe, ns83820_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/ns8390.c0000664000000000000000000007661512524662415020336 0ustar /************************************************************************** ETHERBOOT - BOOTP/TFTP Bootstrap Program Author: Martin Renters Date: May/94 This code is based heavily on David Greenman's if_ed.c driver Copyright (C) 1993-1994, David Greenman, Martin Renters. This software may be used, modified, copied, distributed, and sold, in both source and binary form provided that the above copyright and these terms are retained. Under no circumstances are the authors responsible for the proper functioning of this software, nor do the authors assume any responsibility for damages incurred with its use. Multicast support added by Timothy Legge (timlegge@users.sourceforge.net) 09/28/2003 Relocation support added by Ken Yap (ken_yap@users.sourceforge.net) 28/12/02 3c503 support added by Bill Paul (wpaul@ctr.columbia.edu) on 11/15/94 SMC8416 support added by Bill Paul (wpaul@ctr.columbia.edu) on 12/25/94 3c503 PIO support added by Jim Hague (jim.hague@acm.org) on 2/17/98 RX overrun by Klaus Espenlaub (espenlaub@informatik.uni-ulm.de) on 3/10/99 parts taken from the Linux 8390 driver (by Donald Becker and Paul Gortmaker) SMC8416 PIO support added by Andrew Bettison (andrewb@zip.com.au) on 4/3/02 based on the Linux 8390 driver (by Donald Becker and Paul Gortmaker) **************************************************************************/ FILE_LICENCE ( BSD2 ); /* #warning "ns8390.c: FIXME: split ISA and PCI, clean up" */ #if 1 #if !defined(INCLUDE_NS8390) && !defined(INCLUDE_WD) && \ !defined(INCLUDE_NE) && !defined(INCLUDE_3C503) /* The driver named ns8390 is the PCI driver, often called "PCI ne2000 clones". */ # define INCLUDE_NS8390 1 #endif #include "etherboot.h" #include "nic.h" #include "ns8390.h" #include #ifdef INCLUDE_NS8390 #include #else #include #endif static unsigned char eth_vendor, eth_flags; #ifdef INCLUDE_WD static unsigned char eth_laar; #endif static unsigned short eth_nic_base, eth_asic_base; static unsigned char eth_memsize, eth_rx_start, eth_tx_start; static Address eth_bmem, eth_rmem; static unsigned char eth_drain_receiver; #ifdef INCLUDE_WD static struct wd_board { const char *name; char id; char flags; char memsize; } wd_boards[] = { {"WD8003S", TYPE_WD8003S, 0, MEM_8192}, {"WD8003E", TYPE_WD8003E, 0, MEM_8192}, {"WD8013EBT", TYPE_WD8013EBT, FLAG_16BIT, MEM_16384}, {"WD8003W", TYPE_WD8003W, 0, MEM_8192}, {"WD8003EB", TYPE_WD8003EB, 0, MEM_8192}, {"WD8013W", TYPE_WD8013W, FLAG_16BIT, MEM_16384}, {"WD8003EP/WD8013EP", TYPE_WD8013EP, 0, MEM_8192}, {"WD8013WC", TYPE_WD8013WC, FLAG_16BIT, MEM_16384}, {"WD8013EPC", TYPE_WD8013EPC, FLAG_16BIT, MEM_16384}, {"SMC8216T", TYPE_SMC8216T, FLAG_16BIT | FLAG_790, MEM_16384}, {"SMC8216C", TYPE_SMC8216C, FLAG_16BIT | FLAG_790, MEM_16384}, {"SMC8416T", TYPE_SMC8416T, FLAG_16BIT | FLAG_790, MEM_8192}, {"SMC8416C/BT", TYPE_SMC8416C, FLAG_16BIT | FLAG_790, MEM_8192}, {"SMC8013EBP", TYPE_SMC8013EBP,FLAG_16BIT, MEM_16384}, {NULL, 0, 0, 0} }; #endif #ifdef INCLUDE_3C503 static unsigned char t503_output; /* AUI or internal xcvr (Thinnet) */ #endif #if defined(INCLUDE_WD) #define ASIC_PIO WD_IAR #define eth_probe wd_probe #if defined(INCLUDE_3C503) || defined(INCLUDE_NE) || defined(INCLUDE_NS8390) Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390 #endif #endif #if defined(INCLUDE_3C503) #define eth_probe t503_probe #if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || defined(INCLUDE_WD) Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390 #endif #endif #if defined(INCLUDE_NE) #define eth_probe ne_probe #if defined(INCLUDE_NS8390) || defined(INCLUDE_3C503) || defined(INCLUDE_WD) Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390 #endif #endif #if defined(INCLUDE_NS8390) #define eth_probe nepci_probe #if defined(INCLUDE_NE) || defined(INCLUDE_3C503) || defined(INCLUDE_WD) Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390 #endif #endif #if defined(INCLUDE_3C503) #define ASIC_PIO _3COM_RFMSB #else #if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) #define ASIC_PIO NE_DATA #endif #endif #if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM)) || (defined(INCLUDE_WD) && defined(WD_790_PIO)) /************************************************************************** ETH_PIO_READ - Read a frame via Programmed I/O **************************************************************************/ static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt) { #ifdef INCLUDE_WD outb(src & 0xff, eth_asic_base + WD_GP2); outb(src >> 8, eth_asic_base + WD_GP2); #else outb(D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); outb(cnt, eth_nic_base + D8390_P0_RBCR0); outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1); outb(src, eth_nic_base + D8390_P0_RSAR0); outb(src>>8, eth_nic_base + D8390_P0_RSAR1); outb(D8390_COMMAND_RD0 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); #ifdef INCLUDE_3C503 outb(src & 0xff, eth_asic_base + _3COM_DALSB); outb(src >> 8, eth_asic_base + _3COM_DAMSB); outb(t503_output | _3COM_CR_START, eth_asic_base + _3COM_CR); #endif #endif if (eth_flags & FLAG_16BIT) cnt = (cnt + 1) >> 1; while(cnt--) { #ifdef INCLUDE_3C503 while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0) ; #endif if (eth_flags & FLAG_16BIT) { *((unsigned short *)dst) = inw(eth_asic_base + ASIC_PIO); dst += 2; } else *(dst++) = inb(eth_asic_base + ASIC_PIO); } #ifdef INCLUDE_3C503 outb(t503_output, eth_asic_base + _3COM_CR); #endif } /************************************************************************** ETH_PIO_WRITE - Write a frame via Programmed I/O **************************************************************************/ static void eth_pio_write(const unsigned char *src, unsigned int dst, unsigned int cnt) { #ifdef COMPEX_RL2000_FIX unsigned int x; #endif /* COMPEX_RL2000_FIX */ #ifdef INCLUDE_WD outb(dst & 0xff, eth_asic_base + WD_GP2); outb(dst >> 8, eth_asic_base + WD_GP2); #else outb(D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); outb(D8390_ISR_RDC, eth_nic_base + D8390_P0_ISR); outb(cnt, eth_nic_base + D8390_P0_RBCR0); outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1); outb(dst, eth_nic_base + D8390_P0_RSAR0); outb(dst>>8, eth_nic_base + D8390_P0_RSAR1); outb(D8390_COMMAND_RD1 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); #ifdef INCLUDE_3C503 outb(dst & 0xff, eth_asic_base + _3COM_DALSB); outb(dst >> 8, eth_asic_base + _3COM_DAMSB); outb(t503_output | _3COM_CR_DDIR | _3COM_CR_START, eth_asic_base + _3COM_CR); #endif #endif if (eth_flags & FLAG_16BIT) cnt = (cnt + 1) >> 1; while(cnt--) { #ifdef INCLUDE_3C503 while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0) ; #endif if (eth_flags & FLAG_16BIT) { outw(*((unsigned short *)src), eth_asic_base + ASIC_PIO); src += 2; } else outb(*(src++), eth_asic_base + ASIC_PIO); } #ifdef INCLUDE_3C503 outb(t503_output, eth_asic_base + _3COM_CR); #else #ifdef COMPEX_RL2000_FIX for (x = 0; x < COMPEX_RL2000_TRIES && (inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC) != D8390_ISR_RDC; ++x); if (x >= COMPEX_RL2000_TRIES) printf("Warning: Compex RL2000 aborted wait!\n"); #endif /* COMPEX_RL2000_FIX */ #ifndef INCLUDE_WD while((inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC) != D8390_ISR_RDC); #endif #endif } #else /************************************************************************** ETH_PIO_READ - Dummy routine when NE2000 not compiled in **************************************************************************/ static void eth_pio_read(unsigned int src __unused, unsigned char *dst __unused, unsigned int cnt __unused) {} #endif /************************************************************************** enable_multycast - Enable Multicast **************************************************************************/ static void enable_multicast(unsigned short eth_nic_base) { unsigned char mcfilter[8]; int i; memset(mcfilter, 0xFF, 8); outb(4, eth_nic_base+D8390_P0_RCR); outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS1, eth_nic_base + D8390_P0_COMMAND); for(i=0;i<8;i++) { outb(mcfilter[i], eth_nic_base + 8 + i); if(inb(eth_nic_base + 8 + i)!=mcfilter[i]) printf("Error SMC 83C690 Multicast filter read/write mishap %d\n",i); } outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS0, eth_nic_base + D8390_P0_COMMAND); outb(4 | 0x08, eth_nic_base+D8390_P0_RCR); } /************************************************************************** NS8390_RESET - Reset adapter **************************************************************************/ static void ns8390_reset(struct nic *nic) { int i; eth_drain_receiver = 0; #ifdef INCLUDE_WD if (eth_flags & FLAG_790) outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); else #endif outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); if (eth_flags & FLAG_16BIT) outb(0x49, eth_nic_base+D8390_P0_DCR); else outb(0x48, eth_nic_base+D8390_P0_DCR); outb(0, eth_nic_base+D8390_P0_RBCR0); outb(0, eth_nic_base+D8390_P0_RBCR1); outb(0x20, eth_nic_base+D8390_P0_RCR); /* monitor mode */ outb(2, eth_nic_base+D8390_P0_TCR); outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR); outb(eth_rx_start, eth_nic_base+D8390_P0_PSTART); #ifdef INCLUDE_WD if (eth_flags & FLAG_790) { #ifdef WD_790_PIO outb(0x10, eth_asic_base + 0x06); /* disable interrupts, enable PIO */ outb(0x01, eth_nic_base + 0x09); /* enable ring read auto-wrap */ #else outb(0, eth_nic_base + 0x09); #endif } #endif outb(eth_memsize, eth_nic_base+D8390_P0_PSTOP); outb(eth_memsize - 1, eth_nic_base+D8390_P0_BOUND); outb(0xFF, eth_nic_base+D8390_P0_ISR); outb(0, eth_nic_base+D8390_P0_IMR); #ifdef INCLUDE_WD if (eth_flags & FLAG_790) outb(D8390_COMMAND_PS1 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); else #endif outb(D8390_COMMAND_PS1 | D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); for (i=0; inode_addr[i], eth_nic_base+D8390_P1_PAR0+i); for (i=0; iflags) ? 0 : _3COM_CR_XSEL; outb(t503_output, eth_asic_base + _3COM_CR); #endif } static int ns8390_poll(struct nic *nic, int retrieve); #ifndef INCLUDE_3C503 /************************************************************************** ETH_RX_OVERRUN - Bring adapter back to work after an RX overrun **************************************************************************/ static void eth_rx_overrun(struct nic *nic) { int start_time; #ifdef INCLUDE_WD if (eth_flags & FLAG_790) outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); else #endif outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); /* wait for at least 1.6ms - we wait one timer tick */ start_time = currticks(); while (currticks() - start_time <= 1) /* Nothing */; outb(0, eth_nic_base+D8390_P0_RBCR0); /* reset byte counter */ outb(0, eth_nic_base+D8390_P0_RBCR1); /* * Linux driver checks for interrupted TX here. This is not necessary, * because the transmit routine waits until the frame is sent. */ /* enter loopback mode and restart NIC */ outb(2, eth_nic_base+D8390_P0_TCR); #ifdef INCLUDE_WD if (eth_flags & FLAG_790) outb(D8390_COMMAND_PS0 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); else #endif outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); /* clear the RX ring, acknowledge overrun interrupt */ eth_drain_receiver = 1; while (ns8390_poll(nic, 1)) /* Nothing */; eth_drain_receiver = 0; outb(D8390_ISR_OVW, eth_nic_base+D8390_P0_ISR); /* leave loopback mode - no packets to be resent (see Linux driver) */ outb(0, eth_nic_base+D8390_P0_TCR); } #endif /* INCLUDE_3C503 */ /************************************************************************** NS8390_TRANSMIT - Transmit a frame **************************************************************************/ static void ns8390_transmit( struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) /* Packet */ { #if defined(INCLUDE_3C503) || (defined(INCLUDE_WD) && ! defined(WD_790_PIO)) Address eth_vmem = bus_to_virt(eth_bmem); #endif #ifdef INCLUDE_3C503 if (!(eth_flags & FLAG_PIO)) { memcpy((char *)eth_vmem, d, ETH_ALEN); /* dst */ memcpy((char *)eth_vmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */ *((char *)eth_vmem+12) = t>>8; /* type */ *((char *)eth_vmem+13) = t; memcpy((char *)eth_vmem+ETH_HLEN, p, s); s += ETH_HLEN; while (s < ETH_ZLEN) *((char *)eth_vmem+(s++)) = 0; } #endif #ifdef INCLUDE_WD if (eth_flags & FLAG_16BIT) { outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR); inb(0x84); } #ifndef WD_790_PIO /* Memory interface */ if (eth_flags & FLAG_790) { outb(WD_MSR_MENB, eth_asic_base + WD_MSR); inb(0x84); } inb(0x84); memcpy((char *)eth_vmem, d, ETH_ALEN); /* dst */ memcpy((char *)eth_vmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */ *((char *)eth_vmem+12) = t>>8; /* type */ *((char *)eth_vmem+13) = t; memcpy((char *)eth_vmem+ETH_HLEN, p, s); s += ETH_HLEN; while (s < ETH_ZLEN) *((char *)eth_vmem+(s++)) = 0; if (eth_flags & FLAG_790) { outb(0, eth_asic_base + WD_MSR); inb(0x84); } #else inb(0x84); #endif #endif #if defined(INCLUDE_3C503) if (eth_flags & FLAG_PIO) #endif #if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM)) || (defined(INCLUDE_WD) && defined(WD_790_PIO)) { /* Programmed I/O */ unsigned short type; type = (t >> 8) | (t << 8); eth_pio_write( (unsigned char *) d, eth_tx_start<<8, ETH_ALEN); eth_pio_write(nic->node_addr, (eth_tx_start<<8)+ETH_ALEN, ETH_ALEN); /* bcc generates worse code without (const+const) below */ eth_pio_write((unsigned char *)&type, (eth_tx_start<<8)+(ETH_ALEN+ETH_ALEN), 2); eth_pio_write( (unsigned char *) p, (eth_tx_start<<8)+ETH_HLEN, s); s += ETH_HLEN; if (s < ETH_ZLEN) s = ETH_ZLEN; } #endif #if defined(INCLUDE_3C503) #endif #ifdef INCLUDE_WD if (eth_flags & FLAG_16BIT) { outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR); inb(0x84); } if (eth_flags & FLAG_790) outb(D8390_COMMAND_PS0 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); else #endif outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR); outb(s, eth_nic_base+D8390_P0_TBCR0); outb(s>>8, eth_nic_base+D8390_P0_TBCR1); #ifdef INCLUDE_WD if (eth_flags & FLAG_790) outb(D8390_COMMAND_PS0 | D8390_COMMAND_TXP | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); else #endif outb(D8390_COMMAND_PS0 | D8390_COMMAND_TXP | D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); } /************************************************************************** NS8390_POLL - Wait for a frame **************************************************************************/ static int ns8390_poll(struct nic *nic, int retrieve) { int ret = 0; unsigned char rstat, curr, next; unsigned short len, frag; unsigned short pktoff; unsigned char *p; struct ringbuffer pkthdr; #ifndef INCLUDE_3C503 /* avoid infinite recursion: see eth_rx_overrun() */ if (!eth_drain_receiver && (inb(eth_nic_base+D8390_P0_ISR) & D8390_ISR_OVW)) { eth_rx_overrun(nic); return(0); } #endif /* INCLUDE_3C503 */ rstat = inb(eth_nic_base+D8390_P0_RSR); if (!(rstat & D8390_RSTAT_PRX)) return(0); next = inb(eth_nic_base+D8390_P0_BOUND)+1; if (next >= eth_memsize) next = eth_rx_start; outb(D8390_COMMAND_PS1, eth_nic_base+D8390_P0_COMMAND); curr = inb(eth_nic_base+D8390_P1_CURR); outb(D8390_COMMAND_PS0, eth_nic_base+D8390_P0_COMMAND); if (curr >= eth_memsize) curr=eth_rx_start; if (curr == next) return(0); if ( ! retrieve ) return 1; #ifdef INCLUDE_WD if (eth_flags & FLAG_16BIT) { outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR); inb(0x84); } #ifndef WD_790_PIO if (eth_flags & FLAG_790) { outb(WD_MSR_MENB, eth_asic_base + WD_MSR); inb(0x84); } #endif inb(0x84); #endif pktoff = next << 8; if (eth_flags & FLAG_PIO) eth_pio_read(pktoff, (unsigned char *)&pkthdr, 4); else memcpy(&pkthdr, bus_to_virt(eth_rmem + pktoff), 4); pktoff += sizeof(pkthdr); /* incoming length includes FCS so must sub 4 */ len = pkthdr.len - 4; if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || len < ETH_ZLEN || len > ETH_FRAME_LEN) { printf("Bogus packet, ignoring\n"); return (0); } else { p = nic->packet; nic->packetlen = len; /* available to caller */ frag = (eth_memsize << 8) - pktoff; if (len > frag) { /* We have a wrap-around */ /* read first part */ if (eth_flags & FLAG_PIO) eth_pio_read(pktoff, p, frag); else memcpy(p, bus_to_virt(eth_rmem + pktoff), frag); pktoff = eth_rx_start << 8; p += frag; len -= frag; } /* read second part */ if (eth_flags & FLAG_PIO) eth_pio_read(pktoff, p, len); else memcpy(p, bus_to_virt(eth_rmem + pktoff), len); ret = 1; } #ifdef INCLUDE_WD #ifndef WD_790_PIO if (eth_flags & FLAG_790) { outb(0, eth_asic_base + WD_MSR); inb(0x84); } #endif if (eth_flags & FLAG_16BIT) { outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR); inb(0x84); } inb(0x84); #endif next = pkthdr.next; /* frame number of next packet */ if (next == eth_rx_start) next = eth_memsize; outb(next-1, eth_nic_base+D8390_P0_BOUND); return(ret); } /************************************************************************** NS8390_DISABLE - Turn off adapter **************************************************************************/ static void ns8390_disable ( struct nic *nic ) { ns8390_reset(nic); } /************************************************************************** NS8390_IRQ - Enable, Disable, or Force interrupts **************************************************************************/ static void ns8390_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } static struct nic_operations ns8390_operations; static struct nic_operations ns8390_operations = { .connect = dummy_connect, .poll = ns8390_poll, .transmit = ns8390_transmit, .irq = ns8390_irq, }; /************************************************************************** ETH_PROBE - Look for an adapter **************************************************************************/ #ifdef INCLUDE_NS8390 static int eth_probe (struct nic *nic, struct pci_device *pci) #else static int eth_probe (struct dev *dev, unsigned short *probe_addrs __unused) #endif { int i; #ifdef INCLUDE_NS8390 unsigned short pci_probe_addrs[] = { pci->ioaddr, 0 }; unsigned short *probe_addrs = pci_probe_addrs; #endif eth_vendor = VENDOR_NONE; eth_drain_receiver = 0; nic->irqno = 0; #ifdef INCLUDE_WD { /****************************************************************** Search for WD/SMC cards ******************************************************************/ struct wd_board *brd; unsigned short chksum; unsigned char c; for (eth_asic_base = WD_LOW_BASE; eth_asic_base <= WD_HIGH_BASE; eth_asic_base += 0x20) { chksum = 0; for (i=8; i<16; i++) chksum += inb(eth_asic_base+i); /* Extra checks to avoid soundcard */ if ((chksum & 0xFF) == 0xFF && inb(eth_asic_base+8) != 0xFF && inb(eth_asic_base+9) != 0xFF) break; } if (eth_asic_base > WD_HIGH_BASE) return (0); /* We've found a board */ eth_vendor = VENDOR_WD; eth_nic_base = eth_asic_base + WD_NIC_ADDR; nic->ioaddr = eth_nic_base; c = inb(eth_asic_base+WD_BID); /* Get board id */ for (brd = wd_boards; brd->name; brd++) if (brd->id == c) break; if (!brd->name) { printf("Unknown WD/SMC NIC type %hhX\n", c); return (0); /* Unknown type */ } eth_flags = brd->flags; eth_memsize = brd->memsize; eth_tx_start = 0; eth_rx_start = D8390_TXBUF_SIZE; if ((c == TYPE_WD8013EP) && (inb(eth_asic_base + WD_ICR) & WD_ICR_16BIT)) { eth_flags = FLAG_16BIT; eth_memsize = MEM_16384; } if ((c & WD_SOFTCONFIG) && (!(eth_flags & FLAG_790))) { eth_bmem = (0x80000 | ((inb(eth_asic_base + WD_MSR) & 0x3F) << 13)); } else eth_bmem = WD_DEFAULT_MEM; if (brd->id == TYPE_SMC8216T || brd->id == TYPE_SMC8216C) { /* from Linux driver, 8416BT detects as 8216 sometimes */ unsigned int addr = inb(eth_asic_base + 0xb); if (((addr >> 4) & 3) == 0) { brd += 2; eth_memsize = brd->memsize; } } outb(0x80, eth_asic_base + WD_MSR); /* Reset */ for (i=0; inode_addr[i] = inb(i+eth_asic_base+WD_LAR); } DBG ( "\n%s base %4.4x", brd->name, eth_asic_base ); if (eth_flags & FLAG_790) { #ifdef WD_790_PIO DBG ( ", PIO mode, addr %s\n", eth_ntoa ( nic->node_addr ) ); eth_bmem = 0; eth_flags |= FLAG_PIO; /* force PIO mode */ outb(0, eth_asic_base+WD_MSR); #else DBG ( ", Memory %x, MAC Addr %s\n", eth_bmem, eth_ntoa ( nic->node_addr) ); outb(WD_MSR_MENB, eth_asic_base+WD_MSR); outb((inb(eth_asic_base+0x04) | 0x80), eth_asic_base+0x04); outb(((unsigned)(eth_bmem >> 13) & 0x0F) | ((unsigned)(eth_bmem >> 11) & 0x40) | (inb(eth_asic_base+0x0B) & 0xB0), eth_asic_base+0x0B); outb((inb(eth_asic_base+0x04) & ~0x80), eth_asic_base+0x04); #endif } else { DBG (", Memory %x, MAC Addr %s\n", eth_bmem, eth_ntoa ( nic->node_addr) ); outb(((unsigned)(eth_bmem >> 13) & 0x3F) | 0x40, eth_asic_base+WD_MSR); } if (eth_flags & FLAG_16BIT) { if (eth_flags & FLAG_790) { eth_laar = inb(eth_asic_base + WD_LAAR); outb(WD_LAAR_M16EN, eth_asic_base + WD_LAAR); } else { outb((eth_laar = WD_LAAR_L16EN | 1), eth_asic_base + WD_LAAR); /* The previous line used to be WD_LAAR_M16EN | WD_LAAR_L16EN | 1)); jluke@deakin.edu.au reported that removing WD_LAAR_M16EN made it work for WD8013s. This seems to work for my 8013 boards. I don't know what is really happening. I wish I had data sheets or more time to decode the Linux driver. - Ken */ } inb(0x84); } } #endif #ifdef INCLUDE_3C503 #ifdef T503_AUI nic->flags = 1; /* aui */ #else nic->flags = 0; /* no aui */ #endif /****************************************************************** Search for 3Com 3c503 if no WD/SMC cards ******************************************************************/ if (eth_vendor == VENDOR_NONE) { int idx; int iobase_reg, membase_reg; static unsigned short base[] = { 0x300, 0x310, 0x330, 0x350, 0x250, 0x280, 0x2A0, 0x2E0, 0 }; /* Loop through possible addresses checking each one */ for (idx = 0; (eth_nic_base = base[idx]) != 0; ++idx) { eth_asic_base = eth_nic_base + _3COM_ASIC_OFFSET; /* * Note that we use the same settings for both 8 and 16 bit cards: * both have an 8K bank of memory at page 1 while only the 16 bit * cards have a bank at page 0. */ eth_memsize = MEM_16384; eth_tx_start = 32; eth_rx_start = 32 + D8390_TXBUF_SIZE; /* Check our base address. iobase and membase should */ /* both have a maximum of 1 bit set or be 0. */ iobase_reg = inb(eth_asic_base + _3COM_BCFR); membase_reg = inb(eth_asic_base + _3COM_PCFR); if ((iobase_reg & (iobase_reg - 1)) || (membase_reg & (membase_reg - 1))) continue; /* nope */ /* Now get the shared memory address */ eth_flags = 0; switch (membase_reg) { case _3COM_PCFR_DC000: eth_bmem = 0xdc000; break; case _3COM_PCFR_D8000: eth_bmem = 0xd8000; break; case _3COM_PCFR_CC000: eth_bmem = 0xcc000; break; case _3COM_PCFR_C8000: eth_bmem = 0xc8000; break; case _3COM_PCFR_PIO: eth_flags |= FLAG_PIO; eth_bmem = 0; break; default: continue; /* nope */ } break; } if (base[idx] == 0) /* not found */ return (0); #ifndef T503_SHMEM eth_flags |= FLAG_PIO; /* force PIO mode */ eth_bmem = 0; #endif eth_vendor = VENDOR_3COM; /* Need this to make ns8390_poll() happy. */ eth_rmem = eth_bmem - 0x2000; /* Reset NIC and ASIC */ outb(_3COM_CR_RST | _3COM_CR_XSEL, eth_asic_base + _3COM_CR ); outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR ); /* Get our ethernet address */ outb(_3COM_CR_EALO | _3COM_CR_XSEL, eth_asic_base + _3COM_CR); nic->ioaddr = eth_nic_base; DBG ( "\n3Com 3c503 base %4.4x, ", eth_nic_base ); if (eth_flags & FLAG_PIO) DBG ( "PIO mode" ); else DBG ( "memory %4.4x", eth_bmem ); for (i=0; inode_addr[i] = inb(eth_nic_base+i); } DBG ( ", %s, MAC Addr %s\n", nic->flags ? "AUI" : "internal xcvr", eth_ntoa ( nic->node_addr ) ); outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR); /* * Initialize GA configuration register. Set bank and enable shared * mem. We always use bank 1. Disable interrupts. */ outb(_3COM_GACFR_RSEL | _3COM_GACFR_MBS0 | _3COM_GACFR_TCM | _3COM_GACFR_NIM, eth_asic_base + _3COM_GACFR); outb(0xff, eth_asic_base + _3COM_VPTR2); outb(0xff, eth_asic_base + _3COM_VPTR1); outb(0x00, eth_asic_base + _3COM_VPTR0); /* * Clear memory and verify that it worked (we use only 8K) */ if (!(eth_flags & FLAG_PIO)) { memset(bus_to_virt(eth_bmem), 0, 0x2000); for(i = 0; i < 0x2000; ++i) if (*((char *)(bus_to_virt(eth_bmem+i)))) { printf ("Failed to clear 3c503 shared mem.\n"); return (0); } } /* * Initialize GA page/start/stop registers. */ outb(eth_tx_start, eth_asic_base + _3COM_PSTR); outb(eth_memsize, eth_asic_base + _3COM_PSPR); } #endif #if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) { /****************************************************************** Search for NE1000/2000 if no WD/SMC or 3com cards ******************************************************************/ unsigned char c; if (eth_vendor == VENDOR_NONE) { unsigned char romdata[16]; unsigned char testbuf[32]; int idx; static unsigned char test[] = "NE*000 memory"; static unsigned short base[] = { #ifdef NE_SCAN NE_SCAN, #endif 0 }; /* if no addresses supplied, fall back on defaults */ if (probe_addrs == 0 || probe_addrs[0] == 0) probe_addrs = base; eth_bmem = 0; /* No shared memory */ for (idx = 0; (eth_nic_base = probe_addrs[idx]) != 0; ++idx) { eth_flags = FLAG_PIO; eth_asic_base = eth_nic_base + NE_ASIC_OFFSET; eth_memsize = MEM_16384; eth_tx_start = 32; eth_rx_start = 32 + D8390_TXBUF_SIZE; c = inb(eth_asic_base + NE_RESET); outb(c, eth_asic_base + NE_RESET); (void) inb(0x84); outb(D8390_COMMAND_STP | D8390_COMMAND_RD2, eth_nic_base + D8390_P0_COMMAND); outb(D8390_RCR_MON, eth_nic_base + D8390_P0_RCR); outb(D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR); outb(MEM_8192, eth_nic_base + D8390_P0_PSTART); outb(MEM_16384, eth_nic_base + D8390_P0_PSTOP); #ifdef NS8390_FORCE_16BIT eth_flags |= FLAG_16BIT; /* force 16-bit mode */ #endif eth_pio_write( (unsigned char *) test, 8192, sizeof(test)); eth_pio_read(8192, testbuf, sizeof(test)); if (!memcmp(test, testbuf, sizeof(test))) break; eth_flags |= FLAG_16BIT; eth_memsize = MEM_32768; eth_tx_start = 64; eth_rx_start = 64 + D8390_TXBUF_SIZE; outb(D8390_DCR_WTS | D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR); outb(MEM_16384, eth_nic_base + D8390_P0_PSTART); outb(MEM_32768, eth_nic_base + D8390_P0_PSTOP); eth_pio_write( (unsigned char *) test, 16384, sizeof(test)); eth_pio_read(16384, testbuf, sizeof(test)); if (!memcmp(testbuf, test, sizeof(test))) break; } if (eth_nic_base == 0) return (0); if (eth_nic_base > ISA_MAX_ADDR) /* PCI probably */ eth_flags |= FLAG_16BIT; eth_vendor = VENDOR_NOVELL; eth_pio_read(0, romdata, sizeof(romdata)); for (i=0; inode_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)]; } nic->ioaddr = eth_nic_base; DBG ( "\nNE%c000 base %4.4x, MAC Addr %s\n", (eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base, eth_ntoa ( nic->node_addr ) ); } } #endif if (eth_vendor == VENDOR_NONE) return(0); if (eth_vendor != VENDOR_3COM) eth_rmem = eth_bmem; ns8390_reset(nic); nic->nic_op = &ns8390_operations; /* Based on PnP ISA map */ #ifdef INCLUDE_WD dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR); dev->devid.device_id = htons(0x812a); #endif #ifdef INCLUDE_3C503 dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR); dev->devid.device_id = htons(0x80f3); #endif #ifdef INCLUDE_NE dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR); dev->devid.device_id = htons(0x80d6); #endif return 1; } #ifdef INCLUDE_WD struct isa_driver wd_driver __isa_driver = { .type = NIC_DRIVER, .name = "WD", .probe = wd_probe, .ioaddrs = 0, }; ISA_ROM("wd","WD8003/8013, SMC8216/8416, SMC 83c790 (EtherEZ)"); #endif #ifdef INCLUDE_3C503 struct isa_driver t503_driver __isa_driver = { .type = NIC_DRIVER, .name = "3C503", .probe = t503_probe, .ioaddrs = 0, }; ISA_ROM("3c503","3Com503, Etherlink II[/16]"); #endif #ifdef INCLUDE_NE struct isa_driver ne_driver __isa_driver = { .type = NIC_DRIVER, .name = "NE*000", .probe = ne_probe, .ioaddrs = 0, }; ISA_ROM("ne","NE1000/2000 and clones"); #endif #ifdef INCLUDE_NS8390 static struct pci_device_id nepci_nics[] = { /* A few NE2000 PCI clones, list not exhaustive */ PCI_ROM(0x10ec, 0x8029, "rtl8029", "Realtek 8029", 0), PCI_ROM(0x1186, 0x0300, "dlink-528", "D-Link DE-528", 0), PCI_ROM(0x1050, 0x0940, "winbond940", "Winbond NE2000-PCI", 0), /* Winbond 86C940 / 89C940 */ PCI_ROM(0x1050, 0x5a5a, "winbond940f", "Winbond W89c940F", 0), /* Winbond 89C940F */ PCI_ROM(0x11f6, 0x1401, "compexrl2000", "Compex ReadyLink 2000", 0), PCI_ROM(0x8e2e, 0x3000, "ktiet32p2", "KTI ET32P2", 0), PCI_ROM(0x4a14, 0x5000, "nv5000sc", "NetVin NV5000SC", 0), PCI_ROM(0x12c3, 0x0058, "holtek80232", "Holtek HT80232", 0), PCI_ROM(0x12c3, 0x5598, "holtek80229", "Holtek HT80229", 0), PCI_ROM(0x10bd, 0x0e34, "surecom-ne34", "Surecom NE34", 0), PCI_ROM(0x1106, 0x0926, "via86c926", "Via 86c926", 0), }; PCI_DRIVER ( nepci_driver, nepci_nics, PCI_NO_CLASS ); DRIVER ( "NE2000/PCI", nic_driver, pci_driver, nepci_driver, nepci_probe, ns8390_disable ); #endif /* INCLUDE_NS8390 */ #endif /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/3c509.h0000664000000000000000000002740112524662415020127 0ustar /* * Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. 2. The name * of the author may not be used to endorse or promote products derived from * this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * if_epreg.h,v 1.4 1994/11/13 10:12:37 gibbs Exp Modified by: * October 2, 1994 Modified by: Andres Vega Garcia INRIA - Sophia Antipolis, France e-mail: avega@sophia.inria.fr finger: avega@pax.inria.fr */ FILE_LICENCE ( BSD3 ); #include "nic.h" /* * Ethernet software status per interface. */ /* * Some global constants */ #define TX_INIT_RATE 16 #define TX_INIT_MAX_RATE 64 #define RX_INIT_LATENCY 64 #define RX_INIT_EARLY_THRESH 64 #define MIN_RX_EARLY_THRESHF 16 /* not less than ether_header */ #define MIN_RX_EARLY_THRESHL 4 #define EEPROMSIZE 0x40 #define MAX_EEPROMBUSY 1000 #define EP_ID_PORT_START 0x110 /* avoid 0x100 to avoid conflict with SB16 */ #define EP_ID_PORT_INC 0x10 #define EP_ID_PORT_END 0x200 #define EP_TAG_MAX 0x7 /* must be 2^n - 1 */ /* * Commands to read/write EEPROM trough EEPROM command register (Window 0, * Offset 0xa) */ #define EEPROM_CMD_RD 0x0080 /* Read: Address required (5 bits) */ #define EEPROM_CMD_WR 0x0040 /* Write: Address required (5 bits) */ #define EEPROM_CMD_ERASE 0x00c0 /* Erase: Address required (5 bits) */ #define EEPROM_CMD_EWEN 0x0030 /* Erase/Write Enable: No data required */ #define EEPROM_BUSY (1<<15) #define EEPROM_TST_MODE (1<<14) /* * Some short functions, worth to let them be a macro */ #define is_eeprom_busy(b) (inw((b)+EP_W0_EEPROM_COMMAND)&EEPROM_BUSY) #define GO_WINDOW(b,x) outw(WINDOW_SELECT|(x), (b)+EP_COMMAND) /************************************************************************** * * These define the EEPROM data structure. They are used in the probe * function to verify the existance of the adapter after having sent * the ID_Sequence. * * There are others but only the ones we use are defined here. * **************************************************************************/ #define EEPROM_NODE_ADDR_0 0x0 /* Word */ #define EEPROM_NODE_ADDR_1 0x1 /* Word */ #define EEPROM_NODE_ADDR_2 0x2 /* Word */ #define EEPROM_PROD_ID 0x3 /* 0x9[0-f]50 */ #define EEPROM_MFG_ID 0x7 /* 0x6d50 */ #define EEPROM_ADDR_CFG 0x8 /* Base addr */ #define EEPROM_RESOURCE_CFG 0x9 /* IRQ. Bits 12-15 */ /************************************************************************** * * These are the registers for the 3Com 3c509 and their bit patterns when * applicable. They have been taken out the the "EtherLink III Parallel * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual * from 3com. * * Getting this document out of 3Com is almost impossible. However, * archived copies are available at * http://www.osdever.net/cottontail/downloads/docs/3c5x9b.zip and * several other places on the web (search for 3c5x9b.pdf). * **************************************************************************/ #define EP_COMMAND 0x0e /* Write. BASE+0x0e is always a * command reg. */ #define EP_STATUS 0x0e /* Read. BASE+0x0e is always status * reg. */ #define EP_WINDOW 0x0f /* Read. BASE+0x0f is always window * reg. */ /* * Window 0 registers. Setup. */ /* Write */ #define EP_W0_EEPROM_DATA 0x0c #define EP_W0_EEPROM_COMMAND 0x0a #define EP_W0_RESOURCE_CFG 0x08 #define EP_W0_ADDRESS_CFG 0x06 #define EP_W0_CONFIG_CTRL 0x04 /* Read */ #define EP_W0_PRODUCT_ID 0x02 #define EP_W0_MFG_ID 0x00 /* * Window 1 registers. Operating Set. */ /* Write */ #define EP_W1_TX_PIO_WR_2 0x02 #define EP_W1_TX_PIO_WR_1 0x00 /* Read */ #define EP_W1_FREE_TX 0x0c #define EP_W1_TX_STATUS 0x0b /* byte */ #define EP_W1_TIMER 0x0a /* byte */ #define EP_W1_RX_STATUS 0x08 #define EP_W1_RX_PIO_RD_2 0x02 #define EP_W1_RX_PIO_RD_1 0x00 /* * Window 2 registers. Station Address Setup/Read */ /* Read/Write */ #define EP_W2_ADDR_5 0x05 #define EP_W2_ADDR_4 0x04 #define EP_W2_ADDR_3 0x03 #define EP_W2_ADDR_2 0x02 #define EP_W2_ADDR_1 0x01 #define EP_W2_ADDR_0 0x00 /* * Window 3 registers. FIFO Management. */ /* Read */ #define EP_W3_FREE_TX 0x0c #define EP_W3_FREE_RX 0x0a /* * Window 4 registers. Diagnostics. */ /* Read/Write */ #define EP_W4_MEDIA_TYPE 0x0a #define EP_W4_CTRLR_STATUS 0x08 #define EP_W4_NET_DIAG 0x06 #define EP_W4_FIFO_DIAG 0x04 #define EP_W4_HOST_DIAG 0x02 #define EP_W4_TX_DIAG 0x00 /* * Window 5 Registers. Results and Internal status. */ /* Read */ #define EP_W5_READ_0_MASK 0x0c #define EP_W5_INTR_MASK 0x0a #define EP_W5_RX_FILTER 0x08 #define EP_W5_RX_EARLY_THRESH 0x06 #define EP_W5_TX_AVAIL_THRESH 0x02 #define EP_W5_TX_START_THRESH 0x00 /* * Window 6 registers. Statistics. */ /* Read/Write */ #define TX_TOTAL_OK 0x0c #define RX_TOTAL_OK 0x0a #define TX_DEFERRALS 0x08 #define RX_FRAMES_OK 0x07 #define TX_FRAMES_OK 0x06 #define RX_OVERRUNS 0x05 #define TX_COLLISIONS 0x04 #define TX_AFTER_1_COLLISION 0x03 #define TX_AFTER_X_COLLISIONS 0x02 #define TX_NO_SQE 0x01 #define TX_CD_LOST 0x00 /**************************************** * * Register definitions. * ****************************************/ /* * Command register. All windows. * * 16 bit register. * 15-11: 5-bit code for command to be executed. * 10-0: 11-bit arg if any. For commands with no args; * this can be set to anything. */ #define GLOBAL_RESET (unsigned short) 0x0000 /* Wait at least 1ms * after issuing */ #define WINDOW_SELECT (unsigned short) (0x1<<11) #define START_TRANSCEIVER (unsigned short) (0x2<<11) /* Read ADDR_CFG reg to * determine whether * this is needed. If * so; wait 800 uSec * before using trans- * ceiver. */ #define RX_DISABLE (unsigned short) (0x3<<11) /* state disabled on * power-up */ #define RX_ENABLE (unsigned short) (0x4<<11) #define RX_RESET (unsigned short) (0x5<<11) #define RX_DISCARD_TOP_PACK (unsigned short) (0x8<<11) #define TX_ENABLE (unsigned short) (0x9<<11) #define TX_DISABLE (unsigned short) (0xa<<11) #define TX_RESET (unsigned short) (0xb<<11) #define REQ_INTR (unsigned short) (0xc<<11) #define SET_INTR_MASK (unsigned short) (0xe<<11) #define SET_RD_0_MASK (unsigned short) (0xf<<11) #define SET_RX_FILTER (unsigned short) (0x10<<11) #define FIL_INDIVIDUAL (unsigned short) (0x1) #define FIL_GROUP (unsigned short) (0x2) #define FIL_BRDCST (unsigned short) (0x4) #define FIL_ALL (unsigned short) (0x8) #define SET_RX_EARLY_THRESH (unsigned short) (0x11<<11) #define SET_TX_AVAIL_THRESH (unsigned short) (0x12<<11) #define SET_TX_START_THRESH (unsigned short) (0x13<<11) #define STATS_ENABLE (unsigned short) (0x15<<11) #define STATS_DISABLE (unsigned short) (0x16<<11) #define STOP_TRANSCEIVER (unsigned short) (0x17<<11) /* * The following C_* acknowledge the various interrupts. Some of them don't * do anything. See the manual. */ #define ACK_INTR (unsigned short) (0x6800) #define C_INTR_LATCH (unsigned short) (ACK_INTR|0x1) #define C_CARD_FAILURE (unsigned short) (ACK_INTR|0x2) #define C_TX_COMPLETE (unsigned short) (ACK_INTR|0x4) #define C_TX_AVAIL (unsigned short) (ACK_INTR|0x8) #define C_RX_COMPLETE (unsigned short) (ACK_INTR|0x10) #define C_RX_EARLY (unsigned short) (ACK_INTR|0x20) #define C_INT_RQD (unsigned short) (ACK_INTR|0x40) #define C_UPD_STATS (unsigned short) (ACK_INTR|0x80) /* * Status register. All windows. * * 15-13: Window number(0-7). * 12: Command_in_progress. * 11: reserved. * 10: reserved. * 9: reserved. * 8: reserved. * 7: Update Statistics. * 6: Interrupt Requested. * 5: RX Early. * 4: RX Complete. * 3: TX Available. * 2: TX Complete. * 1: Adapter Failure. * 0: Interrupt Latch. */ #define S_INTR_LATCH (unsigned short) (0x1) #define S_CARD_FAILURE (unsigned short) (0x2) #define S_TX_COMPLETE (unsigned short) (0x4) #define S_TX_AVAIL (unsigned short) (0x8) #define S_RX_COMPLETE (unsigned short) (0x10) #define S_RX_EARLY (unsigned short) (0x20) #define S_INT_RQD (unsigned short) (0x40) #define S_UPD_STATS (unsigned short) (0x80) #define S_5_INTS (S_CARD_FAILURE|S_TX_COMPLETE|\ S_TX_AVAIL|S_RX_COMPLETE|S_RX_EARLY) #define S_COMMAND_IN_PROGRESS (unsigned short) (0x1000) /* * FIFO Registers. * RX Status. Window 1/Port 08 * * 15: Incomplete or FIFO empty. * 14: 1: Error in RX Packet 0: Incomplete or no error. * 13-11: Type of error. * 1000 = Overrun. * 1011 = Run Packet Error. * 1100 = Alignment Error. * 1101 = CRC Error. * 1001 = Oversize Packet Error (>1514 bytes) * 0010 = Dribble Bits. * (all other error codes, no errors.) * * 10-0: RX Bytes (0-1514) */ #define ERR_RX_INCOMPLETE (unsigned short) (0x1<<15) #define ERR_RX (unsigned short) (0x1<<14) #define ERR_RX_OVERRUN (unsigned short) (0x8<<11) #define ERR_RX_RUN_PKT (unsigned short) (0xb<<11) #define ERR_RX_ALIGN (unsigned short) (0xc<<11) #define ERR_RX_CRC (unsigned short) (0xd<<11) #define ERR_RX_OVERSIZE (unsigned short) (0x9<<11) #define ERR_RX_DRIBBLE (unsigned short) (0x2<<11) /* * FIFO Registers. * TX Status. Window 1/Port 0B * * Reports the transmit status of a completed transmission. Writing this * register pops the transmit completion stack. * * Window 1/Port 0x0b. * * 7: Complete * 6: Interrupt on successful transmission requested. * 5: Jabber Error (TP Only, TX Reset required. ) * 4: Underrun (TX Reset required. ) * 3: Maximum Collisions. * 2: TX Status Overflow. * 1-0: Undefined. * */ #define TXS_COMPLETE 0x80 #define TXS_SUCCES_INTR_REQ 0x40 #define TXS_JABBER 0x20 #define TXS_UNDERRUN 0x10 #define TXS_MAX_COLLISION 0x8 #define TXS_STATUS_OVERFLOW 0x4 /* * Configuration control register. * Window 0/Port 04 */ /* Read */ #define IS_AUI (1<<13) #define IS_BNC (1<<12) #define IS_UTP (1<<9) /* Write */ #define ENABLE_DRQ_IRQ 0x0001 #define W0_P4_CMD_RESET_ADAPTER 0x4 #define W0_P4_CMD_ENABLE_ADAPTER 0x1 /* * Media type and status. * Window 4/Port 0A */ #define ENABLE_UTP 0xc0 #define DISABLE_UTP 0x0 /* * Resource control register */ #define SET_IRQ(i) ( ((i)<<12) | 0xF00) /* set IRQ i */ /* * Receive status register */ #define RX_BYTES_MASK (unsigned short) (0x07ff) #define RX_ERROR 0x4000 #define RX_INCOMPLETE 0x8000 /* * Misc defines for various things. */ #define MFG_ID 0x6d50 /* in EEPROM and W0 ADDR_CONFIG */ #define PROD_ID 0x9150 #define AUI 0x1 #define BNC 0x2 #define UTP 0x4 #define RX_BYTES_MASK (unsigned short) (0x07ff) /* * Function shared between 3c509.c and 3c529.c */ extern int t5x9_probe ( struct nic *nic, uint16_t prod_id_check, uint16_t prod_id_mask ); extern void t5x9_disable ( struct nic *nic ); /* * Local variables: * c-basic-offset: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/sis900.h0000664000000000000000000002510012524662415020405 0ustar /* -*- Mode:C; c-basic-offset:4; -*- */ /* Definitions for SiS ethernet controllers including 7014/7016 and 900 * References: * SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support, * preliminary Rev. 1.0 Jan. 14, 1998 * SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support, * preliminary Rev. 1.0 Nov. 10, 1998 * SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution, * preliminary Rev. 1.0 Jan. 18, 1998 * http://www.sis.com.tw/support/databook.htm */ FILE_LICENCE ( GPL_ANY ); /* MAC operationl registers of SiS 7016 and SiS 900 ethernet controller */ /* The I/O extent, SiS 900 needs 256 bytes of io address */ #define SIS900_TOTAL_SIZE 0x100 /* Symbolic offsets to registers. */ enum sis900_registers { cr=0x0, /* Command Register */ cfg=0x4, /* Configuration Register */ mear=0x8, /* EEPROM Access Register */ ptscr=0xc, /* PCI Test Control Register */ isr=0x10, /* Interrupt Status Register */ imr=0x14, /* Interrupt Mask Register */ ier=0x18, /* Interrupt Enable Register */ epar=0x18, /* Enhanced PHY Access Register */ txdp=0x20, /* Transmit Descriptor Pointer Register */ txcfg=0x24, /* Transmit Configuration Register */ rxdp=0x30, /* Receive Descriptor Pointer Register */ rxcfg=0x34, /* Receive Configuration Register */ flctrl=0x38, /* Flow Control Register */ rxlen=0x3c, /* Receive Packet Length Register */ rfcr=0x48, /* Receive Filter Control Register */ rfdr=0x4C, /* Receive Filter Data Register */ pmctrl=0xB0, /* Power Management Control Register */ pmer=0xB4 /* Power Management Wake-up Event Register */ }; /* Symbolic names for bits in various registers */ enum sis900_command_register_bits { RELOAD = 0x00000400, ACCESSMODE = 0x00000200, RESET = 0x00000100, SWI = 0x00000080, RxRESET = 0x00000020, TxRESET = 0x00000010, RxDIS = 0x00000008, RxENA = 0x00000004, TxDIS = 0x00000002, TxENA = 0x00000001 }; enum sis900_configuration_register_bits { DESCRFMT = 0x00000100, /* 7016 specific */ REQALG = 0x00000080, SB = 0x00000040, POW = 0x00000020, EXD = 0x00000010, PESEL = 0x00000008, LPM = 0x00000004, BEM = 0x00000001, RND_CNT = 0x00000400, FAIR_BACKOFF = 0x00000200, EDB_MASTER_EN = 0x00002000 }; enum sis900_eeprom_access_reigster_bits { MDC = 0x00000040, MDDIR = 0x00000020, MDIO = 0x00000010, /* 7016 specific */ EECS = 0x00000008, EECLK = 0x00000004, EEDO = 0x00000002, EEDI = 0x00000001 }; enum sis900_interrupt_register_bits { WKEVT = 0x10000000, TxPAUSEEND = 0x08000000, TxPAUSE = 0x04000000, TxRCMP = 0x02000000, RxRCMP = 0x01000000, DPERR = 0x00800000, SSERR = 0x00400000, RMABT = 0x00200000, RTABT = 0x00100000, RxSOVR = 0x00010000, HIBERR = 0x00008000, SWINT = 0x00001000, MIBINT = 0x00000800, TxURN = 0x00000400, TxIDLE = 0x00000200, TxERR = 0x00000100, TxDESC = 0x00000080, TxOK = 0x00000040, RxORN = 0x00000020, RxIDLE = 0x00000010, RxEARLY = 0x00000008, RxERR = 0x00000004, RxDESC = 0x00000002, RxOK = 0x00000001 }; enum sis900_interrupt_enable_reigster_bits { IE = 0x00000001 }; /* maximum dma burst fro transmission and receive*/ #define MAX_DMA_RANGE 7 /* actually 0 means MAXIMUM !! */ #define TxMXDMA_shift 20 #define RxMXDMA_shift 20 #define TX_DMA_BURST 0 #define RX_DMA_BURST 0 enum sis900_tx_rx_dma{ DMA_BURST_512 = 0, DMA_BURST_64 = 5 }; /* transmit FIFO threshholds */ #define TX_FILL_THRESH 16 /* 1/4 FIFO size */ #define TxFILLT_shift 8 #define TxDRNT_shift 0 #define TxDRNT_100 48 /* 3/4 FIFO size */ #define TxDRNT_10 16 /* 1/2 FIFO size */ enum sis900_transmit_config_register_bits { TxCSI = 0x80000000, TxHBI = 0x40000000, TxMLB = 0x20000000, TxATP = 0x10000000, TxIFG = 0x0C000000, TxFILLT = 0x00003F00, TxDRNT = 0x0000003F }; /* recevie FIFO thresholds */ #define RxDRNT_shift 1 #define RxDRNT_100 16 /* 1/2 FIFO size */ #define RxDRNT_10 24 /* 3/4 FIFO size */ enum sis900_reveive_config_register_bits { RxAEP = 0x80000000, RxARP = 0x40000000, RxATX = 0x10000000, RxAJAB = 0x08000000, RxDRNT = 0x0000007F }; #define RFAA_shift 28 #define RFADDR_shift 16 enum sis900_receive_filter_control_register_bits { RFEN = 0x80000000, RFAAB = 0x40000000, RFAAM = 0x20000000, RFAAP = 0x10000000, RFPromiscuous = (RFAAB|RFAAM|RFAAP) }; enum sis900_reveive_filter_data_mask { RFDAT = 0x0000FFFF }; /* EEPROM Addresses */ enum sis900_eeprom_address { EEPROMSignature = 0x00, EEPROMVendorID = 0x02, EEPROMDeviceID = 0x03, EEPROMMACAddr = 0x08, EEPROMChecksum = 0x0b }; /* The EEPROM commands include the alway-set leading bit. Refer to NM93Cxx datasheet */ enum sis900_eeprom_command { EEread = 0x0180, EEwrite = 0x0140, EEerase = 0x01C0, EEwriteEnable = 0x0130, EEwriteDisable = 0x0100, EEeraseAll = 0x0120, EEwriteAll = 0x0110, EEaddrMask = 0x013F, EEcmdShift = 16 }; /* For SiS962 or SiS963, request the eeprom software access */ enum sis96x_eeprom_command { EEREQ = 0x00000400, EEDONE = 0x00000200, EEGNT = 0x00000100 }; /* Manamgement Data I/O (mdio) frame */ #define MIIread 0x6000 #define MIIwrite 0x5002 #define MIIpmdShift 7 #define MIIregShift 2 #define MIIcmdLen 16 #define MIIcmdShift 16 /* Buffer Descriptor Status*/ enum sis900_buffer_status { OWN = 0x80000000, MORE = 0x40000000, INTR = 0x20000000, SUPCRC = 0x10000000, INCCRC = 0x10000000, OK = 0x08000000, DSIZE = 0x00000FFF }; /* Status for TX Buffers */ enum sis900_tx_buffer_status { ABORT = 0x04000000, UNDERRUN = 0x02000000, NOCARRIER = 0x01000000, DEFERD = 0x00800000, EXCDEFER = 0x00400000, OWCOLL = 0x00200000, EXCCOLL = 0x00100000, COLCNT = 0x000F0000 }; enum sis900_rx_bufer_status { OVERRUN = 0x02000000, DEST = 0x00800000, BCAST = 0x01800000, MCAST = 0x01000000, UNIMATCH = 0x00800000, TOOLONG = 0x00400000, RUNT = 0x00200000, RXISERR = 0x00100000, CRCERR = 0x00080000, FAERR = 0x00040000, LOOPBK = 0x00020000, RXCOL = 0x00010000 }; /* MII register offsets */ enum mii_registers { MII_CONTROL = 0x0000, MII_STATUS = 0x0001, MII_PHY_ID0 = 0x0002, MII_PHY_ID1 = 0x0003, MII_ANADV = 0x0004, MII_ANLPAR = 0x0005, MII_ANEXT = 0x0006 }; /* mii registers specific to SiS 900 */ enum sis_mii_registers { MII_CONFIG1 = 0x0010, MII_CONFIG2 = 0x0011, MII_STSOUT = 0x0012, MII_MASK = 0x0013, MII_RESV = 0x0014 }; /* mii registers specific to AMD 79C901 */ enum amd_mii_registers { MII_STATUS_SUMMARY = 0x0018 }; /* mii registers specific to ICS 1893 */ enum ics_mii_registers { MII_EXTCTRL = 0x0010, MII_QPDSTS = 0x0011, MII_10BTOP = 0x0012, MII_EXTCTRL2 = 0x0013 }; /* MII Control register bit definitions. */ enum mii_control_register_bits { MII_CNTL_FDX = 0x0100, MII_CNTL_RST_AUTO = 0x0200, MII_CNTL_ISOLATE = 0x0400, MII_CNTL_PWRDWN = 0x0800, MII_CNTL_AUTO = 0x1000, MII_CNTL_SPEED = 0x2000, MII_CNTL_LPBK = 0x4000, MII_CNTL_RESET = 0x8000 }; /* MII Status register bit */ enum mii_status_register_bits { MII_STAT_EXT = 0x0001, MII_STAT_JAB = 0x0002, MII_STAT_LINK = 0x0004, MII_STAT_CAN_AUTO = 0x0008, MII_STAT_FAULT = 0x0010, MII_STAT_AUTO_DONE = 0x0020, MII_STAT_CAN_T = 0x0800, MII_STAT_CAN_T_FDX = 0x1000, MII_STAT_CAN_TX = 0x2000, MII_STAT_CAN_TX_FDX = 0x4000, MII_STAT_CAN_T4 = 0x8000 }; #define MII_ID1_OUI_LO 0xFC00 /* low bits of OUI mask */ #define MII_ID1_MODEL 0x03F0 /* model number */ #define MII_ID1_REV 0x000F /* model number */ /* MII NWAY Register Bits ... valid for the ANAR (Auto-Negotiation Advertisement) and ANLPAR (Auto-Negotiation Link Partner) registers */ enum mii_nway_register_bits { MII_NWAY_NODE_SEL = 0x001f, MII_NWAY_CSMA_CD = 0x0001, MII_NWAY_T = 0x0020, MII_NWAY_T_FDX = 0x0040, MII_NWAY_TX = 0x0080, MII_NWAY_TX_FDX = 0x0100, MII_NWAY_T4 = 0x0200, MII_NWAY_PAUSE = 0x0400, MII_NWAY_RF = 0x2000, MII_NWAY_ACK = 0x4000, MII_NWAY_NP = 0x8000 }; enum mii_stsout_register_bits { MII_STSOUT_LINK_FAIL = 0x4000, MII_STSOUT_SPD = 0x0080, MII_STSOUT_DPLX = 0x0040 }; enum mii_stsics_register_bits { MII_STSICS_SPD = 0x8000, MII_STSICS_DPLX = 0x4000, MII_STSICS_LINKSTS = 0x0001 }; enum mii_stssum_register_bits { MII_STSSUM_LINK = 0x0008, MII_STSSUM_DPLX = 0x0004, MII_STSSUM_AUTO = 0x0002, MII_STSSUM_SPD = 0x0001 }; enum sis900_revision_id { SIS630A_900_REV = 0x80, SIS630E_900_REV = 0x81, SIS630S_900_REV = 0x82, SIS630EA1_900_REV = 0x83, SIS630ET_900_REV = 0x84, SIS635A_900_REV = 0x90, SIS96x_900_REV = 0X91, SIS900B_900_REV = 0x03 }; enum sis630_revision_id { SIS630A0 = 0x00, SIS630A1 = 0x01, SIS630B0 = 0x10, SIS630B1 = 0x11 }; #define FDX_CAPABLE_DUPLEX_UNKNOWN 0 #define FDX_CAPABLE_HALF_SELECTED 1 #define FDX_CAPABLE_FULL_SELECTED 2 #define HW_SPEED_UNCONFIG 0 #define HW_SPEED_HOME 1 #define HW_SPEED_10_MBPS 10 #define HW_SPEED_100_MBPS 100 #define HW_SPEED_DEFAULT (HW_SPEED_100_MBPS) #define CRC_SIZE 4 #define MAC_HEADER_SIZE 14 #define TX_BUF_SIZE 1536 #define RX_BUF_SIZE 1536 #define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */ /* Time in ticks before concluding the transmitter is hung. */ #define TX_TIMEOUT (4*TICKS_PER_SEC) typedef struct _BufferDesc { u32 link; volatile u32 cmdsts; u32 bufptr; } BufferDesc; debian/grub-extras/disabled/gpxe/src/drivers/net/depca.c0000664000000000000000000007146112524662415020440 0ustar /* #warning "depca.c: FIXME: fix relocation" */ FILE_LICENCE ( GPL_ANY ); #if 0 /* Not fixed for relocation yet. Probably won't work relocated above 16MB */ #ifdef ALLMULTI #error multicast support is not yet implemented #endif /* Etherboot: depca.h merged, comments from Linux driver retained */ /* depca.c: A DIGITAL DEPCA & EtherWORKS ethernet driver for linux. Written 1994, 1995 by David C. Davies. Copyright 1994 David C. Davies and United States Government (as represented by the Director, National Security Agency). Copyright 1995 Digital Equipment Corporation. This software may be used and distributed according to the terms of the GNU Public License, incorporated herein by reference. This driver is written for the Digital Equipment Corporation series of DEPCA and EtherWORKS ethernet cards: DEPCA (the original) DE100 DE101 DE200 Turbo DE201 Turbo DE202 Turbo (TP BNC) DE210 DE422 (EISA) The driver has been tested on DE100, DE200 and DE202 cards in a relatively busy network. The DE422 has been tested a little. This driver will NOT work for the DE203, DE204 and DE205 series of cards, since they have a new custom ASIC in place of the AMD LANCE chip. See the 'ewrk3.c' driver in the Linux source tree for running those cards. I have benchmarked the driver with a DE100 at 595kB/s to (542kB/s from) a DECstation 5000/200. The author may be reached at davies@maniac.ultranet.com ========================================================================= The driver was originally based on the 'lance.c' driver from Donald Becker which is included with the standard driver distribution for linux. V0.4 is a complete re-write with only the kernel interface remaining from the original code. 1) Lance.c code in /linux/drivers/net/ 2) "Ethernet/IEEE 802.3 Family. 1992 World Network Data Book/Handbook", AMD, 1992 [(800) 222-9323]. 3) "Am79C90 CMOS Local Area Network Controller for Ethernet (C-LANCE)", AMD, Pub. #17881, May 1993. 4) "Am79C960 PCnet-ISA(tm), Single-Chip Ethernet Controller for ISA", AMD, Pub. #16907, May 1992 5) "DEC EtherWORKS LC Ethernet Controller Owners Manual", Digital Equipment corporation, 1990, Pub. #EK-DE100-OM.003 6) "DEC EtherWORKS Turbo Ethernet Controller Owners Manual", Digital Equipment corporation, 1990, Pub. #EK-DE200-OM.003 7) "DEPCA Hardware Reference Manual", Pub. #EK-DEPCA-PR Digital Equipment Corporation, 1989 8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual", Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001 Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this driver. The original DEPCA card requires that the ethernet ROM address counter be enabled to count and has an 8 bit NICSR. The ROM counter enabling is only done when a 0x08 is read as the first address octet (to minimise the chances of writing over some other hardware's I/O register). The NICSR accesses have been changed to byte accesses for all the cards supported by this driver, since there is only one useful bit in the MSB (remote boot timeout) and it is not used. Also, there is a maximum of only 48kB network RAM for this card. My thanks to Torbjorn Lindh for help debugging all this (and holding my feet to the fire until I got it right). The DE200 series boards have on-board 64kB RAM for use as a shared memory network buffer. Only the DE100 cards make use of a 2kB buffer mode which has not been implemented in this driver (only the 32kB and 64kB modes are supported [16kB/48kB for the original DEPCA]). At the most only 2 DEPCA cards can be supported on the ISA bus because there is only provision for two I/O base addresses on each card (0x300 and 0x200). The I/O address is detected by searching for a byte sequence in the Ethernet station address PROM at the expected I/O address for the Ethernet PROM. The shared memory base address is 'autoprobed' by looking for the self test PROM and detecting the card name. When a second DEPCA is detected, information is placed in the base_addr variable of the next device structure (which is created if necessary), thus enabling ethif_probe initialization for the device. More than 2 EISA cards can be supported, but care will be needed assigning the shared memory to ensure that each slot has the correct IRQ, I/O address and shared memory address assigned. ************************************************************************ NOTE: If you are using two ISA DEPCAs, it is important that you assign the base memory addresses correctly. The driver autoprobes I/O 0x300 then 0x200. The base memory address for the first device must be less than that of the second so that the auto probe will correctly assign the I/O and memory addresses on the same card. I can't think of a way to do this unambiguously at the moment, since there is nothing on the cards to tie I/O and memory information together. I am unable to test 2 cards together for now, so this code is unchecked. All reports, good or bad, are welcome. ************************************************************************ The board IRQ setting must be at an unused IRQ which is auto-probed using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are {2,3,4,5,7}, whereas the DE200 is at {5,9,10,11,15}. Note that IRQ2 is really IRQ9 in machines with 16 IRQ lines. No 16MB memory limitation should exist with this driver as DMA is not used and the common memory area is in low memory on the network card (my current system has 20MB and I've not had problems yet). The ability to load this driver as a loadable module has been added. To utilise this ability, you have to do <8 things: 0) have a copy of the loadable modules code installed on your system. 1) copy depca.c from the /linux/drivers/net directory to your favourite temporary directory. 2) if you wish, edit the source code near line 1530 to reflect the I/O address and IRQ you're using (see also 5). 3) compile depca.c, but include -DMODULE in the command line to ensure that the correct bits are compiled (see end of source code). 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a kernel with the depca configuration turned off and reboot. 5) insmod depca.o [irq=7] [io=0x200] [mem=0xd0000] [adapter_name=DE100] [Alan Cox: Changed the code to allow command line irq/io assignments] [Dave Davies: Changed the code to allow command line mem/name assignments] 6) run the net startup bits for your eth?? interface manually (usually /etc/rc.inet[12] at boot time). 7) enjoy! Note that autoprobing is not allowed in loadable modules - the system is already up and running and you're messing with interrupts. To unload a module, turn off the associated interface 'ifconfig eth?? down' then 'rmmod depca'. To assign a base memory address for the shared memory when running as a loadable module, see 5 above. To include the adapter name (if you have no PROM but know the card name) also see 5 above. Note that this last option will not work with kernel built-in depca's. The shared memory assignment for a loadable module makes sense to avoid the 'memory autoprobe' picking the wrong shared memory (for the case of 2 depca's in a PC). ************************************************************************ Support for MCA EtherWORKS cards added 11-3-98. Verified to work with up to 2 DE212 cards in a system (although not fully stress-tested). Currently known bugs/limitations: Note: with the MCA stuff as a module, it trusts the MCA configuration, not the command line for IRQ and memory address. You can specify them if you want, but it will throw your values out. You still have to pass the IO address it was configured as though. ************************************************************************ TO DO: ------ Revision History ---------------- Version Date Description 0.1 25-jan-94 Initial writing. 0.2 27-jan-94 Added LANCE TX hardware buffer chaining. 0.3 1-feb-94 Added multiple DEPCA support. 0.31 4-feb-94 Added DE202 recognition. 0.32 19-feb-94 Tidy up. Improve multi-DEPCA support. 0.33 25-feb-94 Fix DEPCA ethernet ROM counter enable. Add jabber packet fix from murf@perftech.com and becker@super.org 0.34 7-mar-94 Fix DEPCA max network memory RAM & NICSR access. 0.35 8-mar-94 Added DE201 recognition. Tidied up. 0.351 30-apr-94 Added EISA support. Added DE422 recognition. 0.36 16-may-94 DE422 fix released. 0.37 22-jul-94 Added MODULE support 0.38 15-aug-94 Added DBR ROM switch in depca_close(). Multi DEPCA bug fix. 0.38axp 15-sep-94 Special version for Alpha AXP Linux V1.0. 0.381 12-dec-94 Added DE101 recognition, fix multicast bug. 0.382 9-feb-95 Fix recognition bug reported by . 0.383 22-feb-95 Fix for conflict with VESA SCSI reported by 0.384 17-mar-95 Fix a ring full bug reported by 0.385 3-apr-95 Fix a recognition bug reported by 0.386 21-apr-95 Fix the last fix...sorry, must be galloping senility 0.40 25-May-95 Rewrite for portability & updated. ALPHA support from 0.41 26-Jun-95 Added verify_area() calls in depca_ioctl() from suggestion by 0.42 27-Dec-95 Add 'mem' shared memory assignment for loadable modules. Add 'adapter_name' for loadable modules when no PROM. Both above from a suggestion by . Add new multicasting code. 0.421 22-Apr-96 Fix alloc_device() bug 0.422 29-Apr-96 Fix depca_hw_init() bug 0.423 7-Jun-96 Fix module load bug 0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c 0.44 1-Sep-97 Fix *_probe() to test check_region() first - bug reported by 0.45 3-Nov-98 Added support for MCA EtherWORKS (DE210/DE212) cards by 0.451 5-Nov-98 Fixed mca stuff cuz I'm a dummy. 0.5 14-Nov-98 Re-spin for 2.1.x kernels. 0.51 27-Jun-99 Correct received packet length for CRC from report by ========================================================================= */ #include "etherboot.h" #include "nic.h" #include #include "console.h" #include /* ** I/O addresses. Note that the 2k buffer option is not supported in ** this driver. */ #define DEPCA_NICSR 0x00 /* Network interface CSR */ #define DEPCA_RBI 0x02 /* RAM buffer index (2k buffer mode) */ #define DEPCA_DATA 0x04 /* LANCE registers' data port */ #define DEPCA_ADDR 0x06 /* LANCE registers' address port */ #define DEPCA_HBASE 0x08 /* EISA high memory base address reg. */ #define DEPCA_PROM 0x0c /* Ethernet address ROM data port */ #define DEPCA_CNFG 0x0c /* EISA Configuration port */ #define DEPCA_RBSA 0x0e /* RAM buffer starting address (2k buff.) */ /* ** These are LANCE registers addressable through nic->ioaddr + DEPCA_ADDR */ #define CSR0 0 #define CSR1 1 #define CSR2 2 #define CSR3 3 /* ** NETWORK INTERFACE CSR (NI_CSR) bit definitions */ #define TO 0x0100 /* Time Out for remote boot */ #define SHE 0x0080 /* SHadow memory Enable */ #define BS 0x0040 /* Bank Select */ #define BUF 0x0020 /* BUFfer size (1->32k, 0->64k) */ #define RBE 0x0010 /* Remote Boot Enable (1->net boot) */ #define AAC 0x0008 /* Address ROM Address Counter (1->enable) */ #define _128KB 0x0008 /* 128kB Network RAM (1->enable) */ #define IM 0x0004 /* Interrupt Mask (1->mask) */ #define IEN 0x0002 /* Interrupt tristate ENable (1->enable) */ #define LED 0x0001 /* LED control */ /* ** Control and Status Register 0 (CSR0) bit definitions */ #define ERR 0x8000 /* Error summary */ #define BABL 0x4000 /* Babble transmitter timeout error */ #define CERR 0x2000 /* Collision Error */ #define MISS 0x1000 /* Missed packet */ #define MERR 0x0800 /* Memory Error */ #define RINT 0x0400 /* Receiver Interrupt */ #define TINT 0x0200 /* Transmit Interrupt */ #define IDON 0x0100 /* Initialization Done */ #define INTR 0x0080 /* Interrupt Flag */ #define INEA 0x0040 /* Interrupt Enable */ #define RXON 0x0020 /* Receiver on */ #define TXON 0x0010 /* Transmitter on */ #define TDMD 0x0008 /* Transmit Demand */ #define STOP 0x0004 /* Stop */ #define STRT 0x0002 /* Start */ #define INIT 0x0001 /* Initialize */ #define INTM 0xff00 /* Interrupt Mask */ #define INTE 0xfff0 /* Interrupt Enable */ /* ** CONTROL AND STATUS REGISTER 3 (CSR3) */ #define BSWP 0x0004 /* Byte SWaP */ #define ACON 0x0002 /* ALE control */ #define BCON 0x0001 /* Byte CONtrol */ /* ** Initialization Block Mode Register */ #define PROM 0x8000 /* Promiscuous Mode */ #define EMBA 0x0080 /* Enable Modified Back-off Algorithm */ #define INTL 0x0040 /* Internal Loopback */ #define DRTY 0x0020 /* Disable Retry */ #define COLL 0x0010 /* Force Collision */ #define DTCR 0x0008 /* Disable Transmit CRC */ #define LOOP 0x0004 /* Loopback */ #define DTX 0x0002 /* Disable the Transmitter */ #define DRX 0x0001 /* Disable the Receiver */ /* ** Receive Message Descriptor 1 (RMD1) bit definitions. */ #define R_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */ #define R_ERR 0x4000 /* Error Summary */ #define R_FRAM 0x2000 /* Framing Error */ #define R_OFLO 0x1000 /* Overflow Error */ #define R_CRC 0x0800 /* CRC Error */ #define R_BUFF 0x0400 /* Buffer Error */ #define R_STP 0x0200 /* Start of Packet */ #define R_ENP 0x0100 /* End of Packet */ /* ** Transmit Message Descriptor 1 (TMD1) bit definitions. */ #define T_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */ #define T_ERR 0x4000 /* Error Summary */ #define T_ADD_FCS 0x2000 /* More the 1 retry needed to Xmit */ #define T_MORE 0x1000 /* >1 retry to transmit packet */ #define T_ONE 0x0800 /* 1 try needed to transmit the packet */ #define T_DEF 0x0400 /* Deferred */ #define T_STP 0x02000000 /* Start of Packet */ #define T_ENP 0x01000000 /* End of Packet */ #define T_FLAGS 0xff000000 /* TX Flags Field */ /* ** Transmit Message Descriptor 3 (TMD3) bit definitions. */ #define TMD3_BUFF 0x8000 /* BUFFer error */ #define TMD3_UFLO 0x4000 /* UnderFLOw error */ #define TMD3_RES 0x2000 /* REServed */ #define TMD3_LCOL 0x1000 /* Late COLlision */ #define TMD3_LCAR 0x0800 /* Loss of CARrier */ #define TMD3_RTRY 0x0400 /* ReTRY error */ /* ** Ethernet PROM defines */ #define PROBE_LENGTH 32 /* ** Set the number of Tx and Rx buffers. Ensure that the memory requested ** here is <= to the amount of shared memory set up by the board switches. ** The number of descriptors MUST BE A POWER OF 2. ** ** total_memory = NUM_RX_DESC*(8+RX_BUFF_SZ) + NUM_TX_DESC*(8+TX_BUFF_SZ) */ #define NUM_RX_DESC 2 /* Number of RX descriptors */ #define NUM_TX_DESC 2 /* Number of TX descriptors */ #define RX_BUFF_SZ 1536 /* Buffer size for each Rx buffer */ #define TX_BUFF_SZ 1536 /* Buffer size for each Tx buffer */ /* ** ISA Bus defines */ #ifndef DEPCA_MODEL #define DEPCA_MODEL DEPCA #endif static enum { DEPCA, DE100, DE101, DE200, DE201, DE202, DE210, DE212, DE422, unknown } adapter = DEPCA_MODEL; /* ** Name <-> Adapter mapping */ static char *adapter_name[] = { "DEPCA", "DE100","DE101", "DE200","DE201","DE202", "DE210","DE212", "DE422", "" }; #ifndef DEPCA_RAM_BASE #define DEPCA_RAM_BASE 0xd0000 #endif /* ** Memory Alignment. Each descriptor is 4 longwords long. To force a ** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and ** DESC_ALIGN. ALIGN aligns the start address of the private memory area ** and hence the RX descriptor ring's first entry. */ #define ALIGN4 ((u32)4 - 1) /* 1 longword align */ #define ALIGN8 ((u32)8 - 1) /* 2 longword (quadword) align */ #define ALIGN ALIGN8 /* Keep the LANCE happy... */ /* ** The DEPCA Rx and Tx ring descriptors. */ struct depca_rx_desc { volatile s32 base; s16 buf_length; /* This length is negative 2's complement! */ s16 msg_length; /* This length is "normal". */ }; struct depca_tx_desc { volatile s32 base; s16 length; /* This length is negative 2's complement! */ s16 misc; /* Errors and TDR info */ }; #define LA_MASK 0x0000ffff /* LANCE address mask for mapping network RAM to LANCE memory address space */ /* ** The Lance initialization block, described in databook, in common memory. */ struct depca_init { u16 mode; /* Mode register */ u8 phys_addr[ETH_ALEN]; /* Physical ethernet address */ u8 mcast_table[8]; /* Multicast Hash Table. */ u32 rx_ring; /* Rx ring base pointer & ring length */ u32 tx_ring; /* Tx ring base pointer & ring length */ }; struct depca_private { struct depca_rx_desc *rx_ring; struct depca_tx_desc *tx_ring; struct depca_init init_block; /* Shadow init block */ char *rx_memcpy[NUM_RX_DESC]; char *tx_memcpy[NUM_TX_DESC]; u32 bus_offset; /* ISA bus address offset */ u32 sh_mem; /* address of shared mem */ u32 dma_buffs; /* Rx & Tx buffer start */ int rx_cur, tx_cur; /* Next free ring entry */ int txRingMask, rxRingMask; s32 rx_rlen, tx_rlen; /* log2([rt]xRingMask+1) for the descriptors */ }; static Address mem_start = DEPCA_RAM_BASE; static Address mem_len, offset; static struct depca_private lp; /* ** Miscellaneous defines... */ #define STOP_DEPCA(ioaddr) \ outw(CSR0, ioaddr + DEPCA_ADDR);\ outw(STOP, ioaddr + DEPCA_DATA) /* Initialize the lance Rx and Tx descriptor rings. */ static void depca_init_ring(struct nic *nic) { int i; u32 p; lp.rx_cur = lp.tx_cur = 0; /* Initialize the base addresses and length of each buffer in the ring */ for (i = 0; i <= lp.rxRingMask; i++) { writel((p = lp.dma_buffs + i * RX_BUFF_SZ) | R_OWN, &lp.rx_ring[i].base); writew(-RX_BUFF_SZ, &lp.rx_ring[i].buf_length); lp.rx_memcpy[i] = (char *) (p + lp.bus_offset); } for (i = 0; i <= lp.txRingMask; i++) { writel((p = lp.dma_buffs + (i + lp.txRingMask + 1) * TX_BUFF_SZ) & 0x00ffffff, &lp.tx_ring[i].base); lp.tx_memcpy[i] = (char *) (p + lp.bus_offset); } /* Set up the initialization block */ lp.init_block.rx_ring = ((u32) ((u32) lp.rx_ring) & LA_MASK) | lp.rx_rlen; lp.init_block.tx_ring = ((u32) ((u32) lp.tx_ring) & LA_MASK) | lp.tx_rlen; for (i = 0; i < ETH_ALEN; i++) lp.init_block.phys_addr[i] = nic->node_addr[i]; lp.init_block.mode = 0x0000; /* Enable the Tx and Rx */ memset(lp.init_block.mcast_table, 0, sizeof(lp.init_block.mcast_table)); } static inline void LoadCSRs(struct nic *nic) { outw(CSR1, nic->ioaddr + DEPCA_ADDR); /* initialisation block address LSW */ outw((u16) (lp.sh_mem & LA_MASK), nic->ioaddr + DEPCA_DATA); outw(CSR2, nic->ioaddr + DEPCA_ADDR); /* initialisation block address MSW */ outw((u16) ((lp.sh_mem & LA_MASK) >> 16), nic->ioaddr + DEPCA_DATA); outw(CSR3, nic->ioaddr + DEPCA_ADDR); /* ALE control */ outw(ACON, nic->ioaddr + DEPCA_DATA); outw(CSR0, nic->ioaddr + DEPCA_ADDR); /* Point back to CSR0 */ } static inline int InitRestartDepca(struct nic *nic) { int i; /* Copy the shadow init_block to shared memory */ memcpy_toio((char *)lp.sh_mem, &lp.init_block, sizeof(struct depca_init)); outw(CSR0, nic->ioaddr + DEPCA_ADDR); /* point back to CSR0 */ outw(INIT, nic->ioaddr + DEPCA_DATA); /* initialise DEPCA */ for (i = 0; i < 100 && !(inw(nic->ioaddr + DEPCA_DATA) & IDON); i++) ; if (i < 100) { /* clear IDON by writing a 1, and start LANCE */ outw(IDON | STRT, nic->ioaddr + DEPCA_DATA); } else { printf("DEPCA not initialised\n"); return (1); } return (0); } /************************************************************************** RESET - Reset adapter ***************************************************************************/ static void depca_reset(struct nic *nic) { s16 nicsr; int i, j; STOP_DEPCA(nic->ioaddr); nicsr = inb(nic->ioaddr + DEPCA_NICSR); nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM); outb(nicsr, nic->ioaddr + DEPCA_NICSR); if (inw(nic->ioaddr + DEPCA_DATA) != STOP) { printf("depca: Cannot stop NIC\n"); return; } /* Initialisation block */ lp.sh_mem = mem_start; mem_start += sizeof(struct depca_init); /* Tx & Rx descriptors (aligned to a quadword boundary) */ mem_start = (mem_start + ALIGN) & ~ALIGN; lp.rx_ring = (struct depca_rx_desc *) mem_start; mem_start += (sizeof(struct depca_rx_desc) * NUM_RX_DESC); lp.tx_ring = (struct depca_tx_desc *) mem_start; mem_start += (sizeof(struct depca_tx_desc) * NUM_TX_DESC); lp.bus_offset = mem_start & 0x00ff0000; /* LANCE re-mapped start address */ lp.dma_buffs = mem_start & LA_MASK; /* Finish initialising the ring information. */ lp.rxRingMask = NUM_RX_DESC - 1; lp.txRingMask = NUM_TX_DESC - 1; /* Calculate Tx/Rx RLEN size for the descriptors. */ for (i = 0, j = lp.rxRingMask; j > 0; i++) { j >>= 1; } lp.rx_rlen = (s32) (i << 29); for (i = 0, j = lp.txRingMask; j > 0; i++) { j >>= 1; } lp.tx_rlen = (s32) (i << 29); /* Load the initialisation block */ depca_init_ring(nic); LoadCSRs(nic); InitRestartDepca(nic); } /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int depca_poll(struct nic *nic, int retrieve) { int entry; u32 status; entry = lp.rx_cur; if ((status = readl(&lp.rx_ring[entry].base) & R_OWN)) return (0); if ( ! retrieve ) return 1; memcpy(nic->packet, lp.rx_memcpy[entry], nic->packetlen = lp.rx_ring[entry].msg_length); lp.rx_ring[entry].base |= R_OWN; lp.rx_cur = (++lp.rx_cur) & lp.rxRingMask; return (1); } /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void depca_transmit( struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) /* Packet */ { int entry, len; char *mem; /* send the packet to destination */ /* ** Caution: the right order is important here... dont ** setup the ownership rights until all the other ** information is in place */ mem = lp.tx_memcpy[entry = lp.tx_cur]; memcpy_toio(mem, d, ETH_ALEN); memcpy_toio(mem + ETH_ALEN, nic->node_addr, ETH_ALEN); mem[ETH_ALEN * 2] = t >> 8; mem[ETH_ALEN * 2 + 1] = t; memcpy_toio(mem + ETH_HLEN, p, s); s += ETH_HLEN; len = (s < ETH_ZLEN ? ETH_ZLEN : s); /* clean out flags */ writel(readl(&lp.tx_ring[entry].base) & ~T_FLAGS, &lp.tx_ring[entry].base); /* clears other error flags */ writew(0x0000, &lp.tx_ring[entry].misc); /* packet length in buffer */ writew(-len, &lp.tx_ring[entry].length); /* start and end of packet, ownership */ writel(readl(&lp.tx_ring[entry].base) | (T_STP|T_ENP|T_OWN), &lp.tx_ring[entry].base); /* update current pointers */ lp.tx_cur = (++lp.tx_cur) & lp.txRingMask; } /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void depca_disable ( struct nic *nic ) { depca_reset(nic); STOP_DEPCA(nic->ioaddr); } /************************************************************************** IRQ - Interrupt Control ***************************************************************************/ static void depca_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } /* ** Look for a special sequence in the Ethernet station address PROM that ** is common across all DEPCA products. Note that the original DEPCA needs ** its ROM address counter to be initialized and enabled. Only enable ** if the first address octet is a 0x08 - this minimises the chances of ** messing around with some other hardware, but it assumes that this DEPCA ** card initialized itself correctly. ** ** Search the Ethernet address ROM for the signature. Since the ROM address ** counter can start at an arbitrary point, the search must include the entire ** probe sequence length plus the (length_of_the_signature - 1). ** Stop the search IMMEDIATELY after the signature is found so that the ** PROM address counter is correctly positioned at the start of the ** ethernet address for later read out. */ /* * Ugly, ugly, ugly. I can't quite make out where the split should be * between probe1 and probe()... * */ static u8 nicsr; static int depca_probe1 ( isa_probe_addr_t ioaddr ) { u8 data; /* This is only correct for little endian machines, but then Etherboot doesn't work on anything but a PC */ u8 sig[] = { 0xFF, 0x00, 0x55, 0xAA, 0xFF, 0x00, 0x55, 0xAA }; int i, j; data = inb(ioaddr + DEPCA_PROM); /* clear counter on DEPCA */ data = inb(ioaddr + DEPCA_PROM); /* read data */ if (data == 0x8) { nicsr = inb(ioaddr + DEPCA_NICSR); nicsr |= AAC; outb(nicsr, ioaddr + DEPCA_NICSR); } for (i = 0, j = 0; j < (int)sizeof(sig) && i < PROBE_LENGTH+((int)sizeof(sig))-1; ++i) { data = inb(ioaddr + DEPCA_PROM); if (data == sig[j]) /* track signature */ ++j; else j = (data == sig[0]) ? 1 : 0; } if (j != sizeof(sig)) return (0); /* put the card in its initial state */ STOP_DEPCA(ioaddr); nicsr = ((inb(ioaddr + DEPCA_NICSR) & ~SHE & ~RBE & ~IEN) | IM); outb(nicsr, ioaddr + DEPCA_NICSR); if (inw(ioaddr + DEPCA_DATA) != STOP) return (0); memcpy((char *)mem_start, sig, sizeof(sig)); if (memcmp((char *)mem_start, sig, sizeof(sig)) != 0) return (0); return 1; } static struct nic_operations depca_operations = { .connect = dummy_connect, .poll = depca_poll, .transmit = depca_transmit, .irq = depca_irq, }; /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside ***************************************************************************/ static int depca_probe ( struct nic *nic, struct isa_device *isa ) { int i, j; long sum, chksum; nic->irqno = 0; nic->ioaddr = isa->ioaddr; for (i = 0, j = 0, sum = 0; j < 3; j++) { sum <<= 1; if (sum > 0xFFFF) sum -= 0xFFFF; sum += (u8)(nic->node_addr[i++] = inb(nic->ioaddr + DEPCA_PROM)); sum += (u16)((nic->node_addr[i++] = inb(nic->ioaddr + DEPCA_PROM)) << 8); if (sum > 0xFFFF) sum -= 0xFFFF; } if (sum == 0xFFFF) sum = 0; chksum = (u8)inb(nic->ioaddr + DEPCA_PROM); chksum |= (u16)(inb(nic->ioaddr + DEPCA_PROM) << 8); mem_len = (adapter == DEPCA) ? (48 << 10) : (64 << 10); offset = 0; if (nicsr & BUF) { offset = 0x8000; nicsr &= ~BS; mem_len -= (32 << 10); } if (adapter != DEPCA) /* enable shadow RAM */ outb(nicsr |= SHE, nic->ioaddr + DEPCA_NICSR); DBG ( "%s base %4.4x, memory [%4.4lx-%4.4lx] addr %s", adapter_name[adapter], nic->ioaddr, mem_start, mem_start + mem_len, eth_ntoa ( nic->node_addr ) ); if (sum != chksum) printf(" (bad checksum)"); putchar('\n'); depca_reset(nic); /* point to NIC specific routines */ nic->nic_op = &depca_operations; return 1; } static isa_probe_addr_t depca_probe_addrs[] = { 0x300, 0x200, }; ISA_DRIVER ( depca_driver, depca_probe_addrs, depca_probe1, GENERIC_ISAPNP_VENDOR, 0x80f7 ); DRIVER ( "depce", nic_driver, isa_driver, depca_driver, depca_probe, depca_disable ); ISA_ROM ( "depca", "Digital DE100 and DE200" ); #endif /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/epic100.h0000664000000000000000000001631312524662415020525 0ustar #ifndef _EPIC100_H_ # define _EPIC100_H_ FILE_LICENCE ( GPL2_OR_LATER ); #ifndef PCI_VENDOR_SMC # define PCI_VENDOR_SMC 0x10B8 #endif #ifndef PCI_DEVICE_SMC_EPIC100 # define PCI_DEVICE_SMC_EPIC100 0x0005 #endif #define PCI_DEVICE_ID_NONE 0xFFFF /* Offsets to registers (using SMC names). */ enum epic100_registers { COMMAND= 0, /* Control Register */ INTSTAT= 4, /* Interrupt Status */ INTMASK= 8, /* Interrupt Mask */ GENCTL = 0x0C, /* General Control */ NVCTL = 0x10, /* Non Volatile Control */ EECTL = 0x14, /* EEPROM Control */ TEST = 0x1C, /* Test register: marked as reserved (see in source code) */ CRCCNT = 0x20, /* CRC Error Counter */ ALICNT = 0x24, /* Frame Alignment Error Counter */ MPCNT = 0x28, /* Missed Packet Counter */ MMCTL = 0x30, /* MII Management Interface Control */ MMDATA = 0x34, /* MII Management Interface Data */ MIICFG = 0x38, /* MII Configuration */ IPG = 0x3C, /* InterPacket Gap */ LAN0 = 0x40, /* MAC address. (0x40-0x48) */ IDCHK = 0x4C, /* BoardID/ Checksum */ MC0 = 0x50, /* Multicast filter table. (0x50-0x5c) */ RXCON = 0x60, /* Receive Control */ TXCON = 0x70, /* Transmit Control */ TXSTAT = 0x74, /* Transmit Status */ PRCDAR = 0x84, /* PCI Receive Current Descriptor Address */ PRSTAT = 0xA4, /* PCI Receive DMA Status */ PRCPTHR= 0xB0, /* PCI Receive Copy Threshold */ PTCDAR = 0xC4, /* PCI Transmit Current Descriptor Address */ ETHTHR = 0xDC /* Early Transmit Threshold */ }; /* Command register (CR_) bits */ #define CR_STOP_RX (0x00000001) #define CR_START_RX (0x00000002) #define CR_QUEUE_TX (0x00000004) #define CR_QUEUE_RX (0x00000008) #define CR_NEXTFRAME (0x00000010) #define CR_STOP_TX_DMA (0x00000020) #define CR_STOP_RX_DMA (0x00000040) #define CR_TX_UGO (0x00000080) /* Interrupt register bits. NI means No Interrupt generated */ #define INTR_RX_THR_STA (0x00400000) /* rx copy threshold status NI */ #define INTR_RX_BUFF_EMPTY (0x00200000) /* rx buffers empty. NI */ #define INTR_TX_IN_PROG (0x00100000) /* tx copy in progess. NI */ #define INTR_RX_IN_PROG (0x00080000) /* rx copy in progress. NI */ #define INTR_TXIDLE (0x00040000) /* tx idle. NI */ #define INTR_RXIDLE (0x00020000) /* rx idle. NI */ #define INTR_INTR_ACTIVE (0x00010000) /* Interrupt active. NI */ #define INTR_RX_STATUS_OK (0x00008000) /* rx status valid. NI */ #define INTR_PCI_TGT_ABT (0x00004000) /* PCI Target abort */ #define INTR_PCI_MASTER_ABT (0x00002000) /* PCI Master abort */ #define INTR_PCI_PARITY_ERR (0x00001000) /* PCI adress parity error */ #define INTR_PCI_DATA_ERR (0x00000800) /* PCI data parity error */ #define INTR_RX_THR_CROSSED (0x00000400) /* rx copy threshold crossed */ #define INTR_CNTFULL (0x00000200) /* Counter overflow */ #define INTR_TXUNDERRUN (0x00000100) /* tx underrun. */ #define INTR_TXEMPTY (0x00000080) /* tx queue empty */ #define INTR_TX_CH_COMPLETE (0x00000040) /* tx chain complete */ #define INTR_TXDONE (0x00000020) /* tx complete (w or w/o err) */ #define INTR_RXERROR (0x00000010) /* rx error (CRC) */ #define INTR_RXOVERFLOW (0x00000008) /* rx buffer overflow */ #define INTR_RX_QUEUE_EMPTY (0x00000004) /* rx queue empty. */ #define INTR_RXHEADER (0x00000002) /* header copy complete */ #define INTR_RXDONE (0x00000001) /* Receive copy complete */ #define INTR_CLEARINTR (0x00007FFF) #define INTR_VALIDBITS (0x007FFFFF) #define INTR_DISABLE (0x00000000) #define INTR_CLEARERRS (0x00007F18) #define INTR_ABNINTR (INTR_CNTFULL | INTR_TXUNDERRUN | INTR_RXOVERFLOW) /* General Control (GC_) bits */ #define GC_SOFT_RESET (0x00000001) #define GC_INTR_ENABLE (0x00000002) #define GC_SOFT_INTR (0x00000004) #define GC_POWER_DOWN (0x00000008) #define GC_ONE_COPY (0x00000010) #define GC_BIG_ENDIAN (0x00000020) #define GC_RX_PREEMPT_TX (0x00000040) #define GC_TX_PREEMPT_RX (0x00000080) /* * Receive FIFO Threshold values * Control the level at which the PCI burst state machine * begins to empty the receive FIFO. Possible values: 0-3 * * 0 => 32, 1 => 64, 2 => 96 3 => 128 bytes. */ #define GC_RX_FIFO_THR_32 (0x00000000) #define GC_RX_FIFO_THR_64 (0x00000100) #define GC_RX_FIFO_THR_96 (0x00000200) #define GC_RX_FIFO_THR_128 (0x00000300) /* Memory Read Control (MRC_) values */ #define GC_MRC_MEM_READ (0x00000000) #define GC_MRC_READ_MULT (0x00000400) #define GC_MRC_READ_LINE (0x00000800) #define GC_SOFTBIT0 (0x00001000) #define GC_SOFTBIT1 (0x00002000) #define GC_RESET_PHY (0x00004000) /* Definitions of the Receive Control (RC_) register bits */ #define RC_SAVE_ERRORED_PKT (0x00000001) #define RC_SAVE_RUNT_FRAMES (0x00000002) #define RC_RCV_BROADCAST (0x00000004) #define RC_RCV_MULTICAST (0x00000008) #define RC_RCV_INVERSE_PKT (0x00000010) #define RC_PROMISCUOUS_MODE (0x00000020) #define RC_MONITOR_MODE (0x00000040) #define RC_EARLY_RCV_ENABLE (0x00000080) /* description of the rx descriptors control bits */ #define RD_FRAGLIST (0x0001) /* Desc points to a fragment list */ #define RD_LLFORM (0x0002) /* Frag list format */ #define RD_HDR_CPY (0x0004) /* Desc used for header copy */ /* Definition of the Transmit CONTROL (TC) register bits */ #define TC_EARLY_TX_ENABLE (0x00000001) /* Loopback Mode (LM_) Select valuesbits */ #define TC_LM_NORMAL (0x00000000) #define TC_LM_INTERNAL (0x00000002) #define TC_LM_EXTERNAL (0x00000004) #define TC_LM_FULL_DPX (0x00000006) #define TX_SLOT_TIME (0x00000078) /* Bytes transferred to chip before transmission starts. */ #define TX_FIFO_THRESH 128 /* Rounded down to 4 byte units. */ /* description of rx descriptors status bits */ #define RRING_PKT_INTACT (0x0001) #define RRING_ALIGN_ERR (0x0002) #define RRING_CRC_ERR (0x0004) #define RRING_MISSED_PKT (0x0008) #define RRING_MULTICAST (0x0010) #define RRING_BROADCAST (0x0020) #define RRING_RECEIVER_DISABLE (0x0040) #define RRING_STATUS_VALID (0x1000) #define RRING_FRAGLIST_ERR (0x2000) #define RRING_HDR_COPIED (0x4000) #define RRING_OWN (0x8000) /* error summary */ #define RRING_ERROR (RRING_ALIGN_ERR|RRING_CRC_ERR) /* description of tx descriptors status bits */ #define TRING_PKT_INTACT (0x0001) /* pkt transmitted. */ #define TRING_PKT_NONDEFER (0x0002) /* pkt xmitted w/o deferring */ #define TRING_COLL (0x0004) /* pkt xmitted w collisions */ #define TRING_CARR (0x0008) /* carrier sense lost */ #define TRING_UNDERRUN (0x0010) /* DMA underrun */ #define TRING_HB_COLL (0x0020) /* Collision detect Heartbeat */ #define TRING_WIN_COLL (0x0040) /* out of window collision */ #define TRING_DEFERRED (0x0080) /* Deferring */ #define TRING_COLL_COUNT (0x0F00) /* collision counter (mask) */ #define TRING_COLL_EXCESS (0x1000) /* tx aborted: excessive colls */ #define TRING_OWN (0x8000) /* desc ownership bit */ /* error summary */ #define TRING_ABORT (TRING_COLL_EXCESS|TRING_WIN_COLL|TRING_UNDERRUN) #define TRING_ERROR (TRING_DEFERRED|TRING_WIN_COLL|TRING_UNDERRUN|TRING_CARR/*|TRING_COLL*/ ) /* description of the tx descriptors control bits */ #define TD_FRAGLIST (0x0001) /* Desc points to a fragment list */ #define TD_LLFORM (0x0002) /* Frag list format */ #define TD_IAF (0x0004) /* Generate Interrupt after tx */ #define TD_NOCRC (0x0008) /* No CRC generated */ #define TD_LASTDESC (0x0010) /* Last desc for this frame */ #endif /* _EPIC100_H_ */ debian/grub-extras/disabled/gpxe/src/drivers/net/3c90x.c0000664000000000000000000006553512524662415020237 0ustar /* * 3c90x.c -- This file implements a gPXE API 3c90x driver * * Originally written for etherboot by: * Greg Beeley, Greg.Beeley@LightSys.org * Modified by Steve Smith, * Steve.Smith@Juno.Com. Alignment bug fix Neil Newell (nn@icenoir.net). * Almost totally Rewritten to use gPXE API, implementation of tx/rx ring support * by Thomas Miletich, thomas.miletich@gmail.com * Thanks to Marty Connor and Stefan Hajnoczi for their help and feedback, * and to Daniel Verkamp for his help with testing. * * Copyright (c) 2009 Thomas Miletich * * Copyright (c) 1999 LightSys Technology Services, Inc. * Portions Copyright (c) 1999 Steve Smith * * This program may be re-distributed in source or binary form, modified, * sold, or copied for any purpose, provided that the above copyright message * and this text are included with all source copies or derivative works, and * provided that the above copyright message and this text are included in the * documentation of any binary-only distributions. This program is distributed * WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR A PARTICULAR * PURPOSE or MERCHANTABILITY. Please read the associated documentation * "3c90x.txt" before compiling and using this driver. * * [ --mdc 20090313 The 3c90x.txt file is now at: * http://etherboot.org/wiki/appnotes/3c90x_issues ] * * This program was written with the assistance of the 3com documentation for * the 3c905B-TX card, as well as with some assistance from the 3c59x * driver Donald Becker wrote for the Linux kernel, and with some assistance * from the remainder of the Etherboot distribution. * * Indented with unix 'indent' command: * $ indent -kr -i8 3c90x.c */ FILE_LICENCE ( BSD2 ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "3c90x.h" /** * a3c90x_internal_IssueCommand: sends a command to the 3c90x card * and waits for it's completion * * @v ioaddr IOAddress of the NIC * @v cmd Command to be issued * @v param Command parameter */ static void a3c90x_internal_IssueCommand(int ioaddr, int cmd, int param) { unsigned int val = (cmd << 11) | param; int cnt = 0; DBGP("a3c90x_internal_IssueCommand\n"); /* Send the cmd to the cmd register */ outw(val, ioaddr + regCommandIntStatus_w); /* Wait for the cmd to complete */ for (cnt = 0; cnt < 100000; cnt++) { if (inw(ioaddr + regCommandIntStatus_w) & INT_CMDINPROGRESS) { continue; } else { DBG2("Command 0x%04X finished in time. cnt = %d.\n", cmd, cnt); return; } } DBG("Command 0x%04X DID NOT finish in time. cnt = %d.\n", cmd, cnt); } /** * a3c90x_internal_SetWindow: selects a register window set. * * @v inf_3c90x private NIC data * @v window window to be selected */ static void a3c90x_internal_SetWindow(struct INF_3C90X *inf_3c90x, int window) { DBGP("a3c90x_internal_SetWindow\n"); /* Window already as set? */ if (inf_3c90x->CurrentWindow == window) return; /* Issue the window command. */ a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdSelectRegisterWindow, window); inf_3c90x->CurrentWindow = window; return; } static void a3c90x_internal_WaitForEeprom(struct INF_3C90X *inf_3c90x) { int cnt = 0; DBGP("a3c90x_internal_WaitForEeprom\n"); while (eepromBusy & inw(inf_3c90x->IOAddr + regEepromCommand_0_w)) { if (cnt == EEPROM_TIMEOUT) { DBG("Read from eeprom failed: timeout\n"); return; } udelay(1); cnt++; } } /** * a3c90x_internal_ReadEeprom - nvs routine to read eeprom data * We only support reading one word(2 byte). The nvs subsystem will make sure * that the routine will never be called with len != 2. * * @v nvs nvs data. * @v address eeprom address to read data from. * @v data data is put here. * @v len number of bytes to read. */ static int a3c90x_internal_ReadEeprom(struct nvs_device *nvs, unsigned int address, void *data, size_t len) { unsigned short *dest = (unsigned short *) data; struct INF_3C90X *inf_3c90x = container_of(nvs, struct INF_3C90X, nvs); DBGP("a3c90x_internal_ReadEeprom\n"); /* we support reading 2 bytes only */ assert(len == 2); /* Select correct window */ a3c90x_internal_SetWindow(inf_3c90x, winEepromBios0); /* set eepromRead bits in command sent to NIC */ address += (inf_3c90x->is3c556 ? eepromRead_556 : eepromRead); a3c90x_internal_WaitForEeprom(inf_3c90x); /* send address to NIC */ outw(address, inf_3c90x->IOAddr + regEepromCommand_0_w); a3c90x_internal_WaitForEeprom(inf_3c90x); /* read value */ *dest = inw(inf_3c90x->IOAddr + regEepromData_0_w); return 0; } /** * a3c90x_internal_WriteEeprom - nvs routine to write eeprom data * currently not implemented * * @v nvs nvs data. * @v address eeprom address to read data from. * @v data data is put here. * @v len number of bytes to read. */ static int a3c90x_internal_WriteEeprom(struct nvs_device *nvs __unused, unsigned int address __unused, const void *data __unused, size_t len __unused) { return -ENOTSUP; } static void a3c90x_internal_ReadEepromContents(struct INF_3C90X *inf_3c90x) { int eeprom_size = (inf_3c90x->isBrev ? 0x20 : 0x17) * 2; DBGP("a3c90x_internal_ReadEepromContents\n"); nvs_read(&inf_3c90x->nvs, 0, inf_3c90x->eeprom, eeprom_size); } /** * a3c90x_reset: exported function that resets the card to its default * state. This is so the Linux driver can re-set the card up the way * it wants to. If CFG_3C90X_PRESERVE_XCVR is defined, then the reset will * not alter the selected transceiver that we used to download the boot * image. * * @v inf_3c90x Private NIC data */ static void a3c90x_reset(struct INF_3C90X *inf_3c90x) { DBGP("a3c90x_reset\n"); /* Send the reset command to the card */ DBG("3c90x: Issuing RESET\n"); a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdGlobalReset, 0); /* global reset command resets station mask, non-B revision cards * require explicit reset of values */ a3c90x_internal_SetWindow(inf_3c90x, winAddressing2); outw(0, inf_3c90x->IOAddr + regStationMask_2_3w + 0); outw(0, inf_3c90x->IOAddr + regStationMask_2_3w + 2); outw(0, inf_3c90x->IOAddr + regStationMask_2_3w + 4); /* Issue transmit reset, wait for command completion */ a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdTxReset, 0); a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdTxEnable, 0); /* * reset of the receiver on B-revision cards re-negotiates the link * takes several seconds (a computer eternity) */ a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdRxReset, inf_3c90x->isBrev ? 0x04 : 0x00); a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdRxEnable, 0); a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdSetInterruptEnable, 0); /* enable rxComplete and txComplete */ a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdSetIndicationEnable, INT_TXCOMPLETE | INT_UPCOMPLETE); /* acknowledge any pending status flags */ a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdAcknowledgeInterrupt, 0x661); return; } /** * a3c90x_setup_tx_ring - Allocates TX ring, initialize tx_desc values * * @v p Private NIC data * * @ret Returns 0 on success, negative on failure */ static int a3c90x_setup_tx_ring(struct INF_3C90X *p) { DBGP("a3c90x_setup_tx_ring\n"); p->tx_ring = malloc_dma(TX_RING_SIZE * sizeof(struct TXD), TX_RING_ALIGN); if (!p->tx_ring) { DBG("Could not allocate TX-ring\n"); return -ENOMEM; } memset(p->tx_ring, 0, TX_RING_SIZE * sizeof(struct TXD)); p->tx_cur = 0; p->tx_cnt = 0; p->tx_tail = 0; return 0; } /** * a3c90x_process_tx_packets - Checks for successfully sent packets, * reports them to gPXE with netdev_tx_complete(); * * @v netdev Network device info */ static void a3c90x_process_tx_packets(struct net_device *netdev) { struct INF_3C90X *p = netdev_priv(netdev); unsigned int downlist_ptr; DBGP("a3c90x_process_tx_packets\n"); DBG(" tx_cnt: %d\n", p->tx_cnt); while (p->tx_tail != p->tx_cur) { downlist_ptr = inl(p->IOAddr + regDnListPtr_l); DBG(" downlist_ptr: %#08x\n", downlist_ptr); DBG(" tx_tail: %d tx_cur: %d\n", p->tx_tail, p->tx_cur); /* NIC is currently working on this tx desc */ if(downlist_ptr == virt_to_bus(p->tx_ring + p->tx_tail)) return; netdev_tx_complete(netdev, p->tx_iobuf[p->tx_tail]); DBG("transmitted packet\n"); DBG(" size: %zd\n", iob_len(p->tx_iobuf[p->tx_tail])); p->tx_tail = (p->tx_tail + 1) % TX_RING_SIZE; p->tx_cnt--; } } static void a3c90x_free_tx_ring(struct INF_3C90X *p) { DBGP("a3c90x_free_tx_ring\n"); free_dma(p->tx_ring, TX_RING_SIZE * sizeof(struct TXD)); p->tx_ring = NULL; /* io_buffers are free()ed by netdev_tx_complete[,_err]() */ } /** * a3c90x_transmit - Transmits a packet. * * @v netdev Network device info * @v iob io_buffer containing the data to be send * * @ret Returns 0 on success, negative on failure */ static int a3c90x_transmit(struct net_device *netdev, struct io_buffer *iob) { struct INF_3C90X *inf_3c90x = netdev_priv(netdev); struct TXD *tx_cur_desc; struct TXD *tx_prev_desc; unsigned int len; unsigned int downlist_ptr; DBGP("a3c90x_transmit\n"); if (inf_3c90x->tx_cnt == TX_RING_SIZE) { DBG("TX-Ring overflow\n"); return -ENOBUFS; } inf_3c90x->tx_iobuf[inf_3c90x->tx_cur] = iob; tx_cur_desc = inf_3c90x->tx_ring + inf_3c90x->tx_cur; tx_prev_desc = inf_3c90x->tx_ring + (((inf_3c90x->tx_cur + TX_RING_SIZE) - 1) % TX_RING_SIZE); len = iob_len(iob); /* Setup the DPD (download descriptor) */ tx_cur_desc->DnNextPtr = 0; /* FrameStartHeader differs in 90x and >= 90xB * It contains length in 90x and a round up boundary and packet ID for * 90xB and 90xC. We can leave this to 0 for 90xB and 90xC. */ tx_cur_desc->FrameStartHeader = fshTxIndicate | (inf_3c90x->isBrev ? 0x00 : len); tx_cur_desc->DataAddr = virt_to_bus(iob->data); tx_cur_desc->DataLength = len | downLastFrag; /* We have to stall the download engine, so the NIC won't access the * tx descriptor while we modify it. There is a way around this * from revision B and upwards. To stay compatible with older revisions * we don't use it here. */ a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdStallCtl, dnStall); tx_prev_desc->DnNextPtr = virt_to_bus(tx_cur_desc); downlist_ptr = inl(inf_3c90x->IOAddr + regDnListPtr_l); if (downlist_ptr == 0) { /* currently no DownList, sending a new one */ outl(virt_to_bus(tx_cur_desc), inf_3c90x->IOAddr + regDnListPtr_l); } /* End Stall */ a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdStallCtl, dnUnStall); inf_3c90x->tx_cur = (inf_3c90x->tx_cur + 1) % TX_RING_SIZE; inf_3c90x->tx_cnt++; return 0; } /** * a3c90x_prepare_rx_desc - fills the rx desc with initial data * * @v p NIC private data * @v index Index for rx_iobuf and rx_ring array */ static void a3c90x_prepare_rx_desc(struct INF_3C90X *p, unsigned int index) { DBGP("a3c90x_prepare_rx_desc\n"); DBG("Populating rx_desc %d\n", index); /* We have to stall the upload engine, so the NIC won't access the * rx descriptor while we modify it. There is a way around this * from revision B and upwards. To stay compatible with older revisions * we don't use it here. */ a3c90x_internal_IssueCommand(p->IOAddr, cmdStallCtl, upStall); p->rx_ring[index].DataAddr = virt_to_bus(p->rx_iobuf[index]->data); p->rx_ring[index].DataLength = RX_BUF_SIZE | upLastFrag; p->rx_ring[index].UpPktStatus = 0; /* unstall upload engine */ a3c90x_internal_IssueCommand(p->IOAddr, cmdStallCtl, upUnStall); } /** * a3c90x_refill_rx_ring -checks every entry in the rx ring and reallocates * them as necessary. Then it calls a3c90x_prepare_rx_desc to fill the rx desc * with initial data. * * @v p NIC private data */ static void a3c90x_refill_rx_ring(struct INF_3C90X *p) { int i; unsigned int status; struct RXD *rx_cur_desc; DBGP("a3c90x_refill_rx_ring\n"); for (i = 0; i < RX_RING_SIZE; i++) { rx_cur_desc = p->rx_ring + i; status = rx_cur_desc->UpPktStatus; /* only refill used descriptor */ if (!(status & upComplete)) continue; /* we still need to process this descriptor */ if (p->rx_iobuf[i] != NULL) continue; p->rx_iobuf[i] = alloc_iob(RX_BUF_SIZE); if (p->rx_iobuf[i] == NULL) { DBG("alloc_iob() failed\n"); break; } a3c90x_prepare_rx_desc(p, i); } } /** * a3c90x_setup_rx_ring - Allocates RX ring, initialize rx_desc values * * @v p Private NIC data * * @ret Returns 0 on success, negative on failure */ static int a3c90x_setup_rx_ring(struct INF_3C90X *p) { int i; DBGP("a3c90x_setup_rx_ring\n"); p->rx_ring = malloc_dma(RX_RING_SIZE * sizeof(struct RXD), RX_RING_ALIGN); if (!p->rx_ring) { DBG("Could not allocate RX-ring\n"); return -ENOMEM; } p->rx_cur = 0; for (i = 0; i < RX_RING_SIZE; i++) { p->rx_ring[i].UpNextPtr = virt_to_bus(p->rx_ring + (i + 1)); /* these are needed so refill_rx_ring initializes the ring */ p->rx_ring[i].UpPktStatus = upComplete; p->rx_iobuf[i] = NULL; } /* Loop the ring */ p->rx_ring[i - 1].UpNextPtr = virt_to_bus(p->rx_ring); a3c90x_refill_rx_ring(p); return 0; } static void a3c90x_free_rx_ring(struct INF_3C90X *p) { DBGP("a3c90x_free_rx_ring\n"); free_dma(p->rx_ring, RX_RING_SIZE * sizeof(struct RXD)); p->rx_ring = NULL; } static void a3c90x_free_rx_iobuf(struct INF_3C90X *p) { int i; DBGP("a3c90x_free_rx_iobuf\n"); for (i = 0; i < RX_RING_SIZE; i++) { free_iob(p->rx_iobuf[i]); p->rx_iobuf[i] = NULL; } } /** * a3c90x_process_rx_packets - Checks for received packets, * reports them to gPXE with netdev_rx() or netdev_rx_err() if there was an * error while receiving the packet * * @v netdev Network device info */ static void a3c90x_process_rx_packets(struct net_device *netdev) { int i; unsigned int rx_status; struct INF_3C90X *p = netdev_priv(netdev); struct RXD *rx_cur_desc; DBGP("a3c90x_process_rx_packets\n"); for (i = 0; i < RX_RING_SIZE; i++) { rx_cur_desc = p->rx_ring + p->rx_cur; rx_status = rx_cur_desc->UpPktStatus; if (!(rx_status & upComplete) && !(rx_status & upError)) break; if (p->rx_iobuf[p->rx_cur] == NULL) break; if (rx_status & upError) { DBG("Corrupted packet received\n"); netdev_rx_err(netdev, p->rx_iobuf[p->rx_cur], -EINVAL); } else { /* if we're here, we've got good packet */ int packet_len; packet_len = rx_status & 0x1FFF; iob_put(p->rx_iobuf[p->rx_cur], packet_len); DBG("received packet\n"); DBG(" size: %d\n", packet_len); netdev_rx(netdev, p->rx_iobuf[p->rx_cur]); } p->rx_iobuf[p->rx_cur] = NULL; /* invalidate rx desc */ p->rx_cur = (p->rx_cur + 1) % RX_RING_SIZE; } a3c90x_refill_rx_ring(p); } /** * a3c90x_poll - Routine that gets called periodically. * Here we hanle transmitted and received packets. * We could also check the link status from time to time, which we * currently don't do. * * @v netdev Network device info */ static void a3c90x_poll(struct net_device *netdev) { struct INF_3C90X *p = netdev_priv(netdev); uint16_t raw_status, int_status; DBGP("a3c90x_poll\n"); raw_status = inw(p->IOAddr + regCommandIntStatus_w); int_status = (raw_status & 0x0FFF); if ( int_status == 0 ) return; a3c90x_internal_IssueCommand(p->IOAddr, cmdAcknowledgeInterrupt, int_status); if (int_status & INT_TXCOMPLETE) outb(0x00, p->IOAddr + regTxStatus_b); DBG("poll: status = %#04x\n", raw_status); a3c90x_process_tx_packets(netdev); a3c90x_process_rx_packets(netdev); } static void a3c90x_free_resources(struct INF_3C90X *p) { DBGP("a3c90x_free_resources\n"); a3c90x_free_tx_ring(p); a3c90x_free_rx_ring(p); a3c90x_free_rx_iobuf(p); } /** * a3c90x_remove - Routine to remove the card. Unregisters * the NIC from gPXE, disables RX/TX and resets the card. * * @v pci PCI device info */ static void a3c90x_remove(struct pci_device *pci) { struct net_device *netdev = pci_get_drvdata(pci); struct INF_3C90X *inf_3c90x = netdev_priv(netdev); DBGP("a3c90x_remove\n"); a3c90x_reset(inf_3c90x); /* Disable the receiver and transmitter. */ outw(cmdRxDisable, inf_3c90x->IOAddr + regCommandIntStatus_w); outw(cmdTxDisable, inf_3c90x->IOAddr + regCommandIntStatus_w); unregister_netdev(netdev); netdev_nullify(netdev); netdev_put(netdev); } static void a3c90x_irq(struct net_device *netdev, int enable) { struct INF_3C90X *p = netdev_priv(netdev); DBGP("a3c90x_irq\n"); if (enable == 0) { /* disable interrupts */ a3c90x_internal_IssueCommand(p->IOAddr, cmdSetInterruptEnable, 0); } else { a3c90x_internal_IssueCommand(p->IOAddr, cmdSetInterruptEnable, INT_TXCOMPLETE | INT_UPCOMPLETE); a3c90x_internal_IssueCommand(p->IOAddr, cmdAcknowledgeInterrupt, 0x661); } } /** * a3c90x_hw_start - Initialize hardware, copy MAC address * to NIC registers, set default receiver */ static void a3c90x_hw_start(struct net_device *netdev) { int i, c; unsigned int cfg; unsigned int mopt; unsigned short linktype; struct INF_3C90X *inf_3c90x = netdev_priv(netdev); DBGP("a3c90x_hw_start\n"); /* 3C556: Invert MII power */ if (inf_3c90x->is3c556) { unsigned int tmp; a3c90x_internal_SetWindow(inf_3c90x, winAddressing2); tmp = inw(inf_3c90x->IOAddr + regResetOptions_2_w); tmp |= 0x4000; outw(tmp, inf_3c90x->IOAddr + regResetOptions_2_w); } /* Copy MAC address into the NIC registers */ a3c90x_internal_SetWindow(inf_3c90x, winAddressing2); for (i = 0; i < ETH_ALEN; i++) outb(netdev->ll_addr[i], inf_3c90x->IOAddr + regStationAddress_2_3w + i); for (i = 0; i < ETH_ALEN; i++) outb(0, inf_3c90x->IOAddr + regStationMask_2_3w + i); /* Read the media options register, print a message and set default * xcvr. * * Uses Media Option command on B revision, Reset Option on non-B * revision cards -- same register address */ a3c90x_internal_SetWindow(inf_3c90x, winTxRxOptions3); mopt = inw(inf_3c90x->IOAddr + regResetMediaOptions_3_w); /* mask out VCO bit that is defined as 10baseFL bit on B-rev cards */ if (!inf_3c90x->isBrev) { mopt &= 0x7F; } DBG("Connectors present: "); c = 0; linktype = 0x0008; if (mopt & 0x01) { DBG("%s100Base-T4", (c++) ? ", " : ""); linktype = linkMII; } if (mopt & 0x04) { DBG("%s100Base-FX", (c++) ? ", " : ""); linktype = link100BaseFX; } if (mopt & 0x10) { DBG("%s10Base-2", (c++) ? ", " : ""); linktype = link10Base2; } if (mopt & 0x20) { DBG("%sAUI", (c++) ? ", " : ""); linktype = linkAUI; } if (mopt & 0x40) { DBG("%sMII", (c++) ? ", " : ""); linktype = linkMII; } if ((mopt & 0xA) == 0xA) { DBG("%s10Base-T / 100Base-TX", (c++) ? ", " : ""); linktype = linkAutoneg; } else if ((mopt & 0xA) == 0x2) { DBG("%s100Base-TX", (c++) ? ", " : ""); linktype = linkAutoneg; } else if ((mopt & 0xA) == 0x8) { DBG("%s10Base-T", (c++) ? ", " : ""); linktype = linkAutoneg; } DBG(".\n"); /* Determine transceiver type to use, depending on value stored in * eeprom 0x16 */ if (inf_3c90x->isBrev) { if ((inf_3c90x->eeprom[0x16] & 0xFF00) == XCVR_MAGIC) { /* User-defined */ linktype = inf_3c90x->eeprom[0x16] & 0x000F; } } else { /* I don't know what MII MAC only mode is!!! */ if (linktype == linkExternalMII) { if (inf_3c90x->isBrev) DBG("WARNING: MII External MAC Mode only supported on B-revision " "cards!!!!\nFalling Back to MII Mode\n"); linktype = linkMII; } } /* enable DC converter for 10-Base-T */ if (linktype == link10Base2) { a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdEnableDcConverter, 0); } /* Set the link to the type we just determined. */ a3c90x_internal_SetWindow(inf_3c90x, winTxRxOptions3); cfg = inl(inf_3c90x->IOAddr + regInternalConfig_3_l); cfg &= ~(0xF << 20); cfg |= (linktype << 20); DBG("Setting internal cfg register: 0x%08X (linktype: 0x%02X)\n", cfg, linktype); outl(cfg, inf_3c90x->IOAddr + regInternalConfig_3_l); /* Now that we set the xcvr type, reset the Tx and Rx */ a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdTxReset, 0x00); if (!inf_3c90x->isBrev) outb(0x01, inf_3c90x->IOAddr + regTxFreeThresh_b); /* Set the RX filter = receive only individual pkts & multicast & bcast. */ a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdSetRxFilter, 0x01 + 0x02 + 0x04); /* * set Indication and Interrupt flags , acknowledge any IRQ's */ a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdSetInterruptEnable, INT_TXCOMPLETE | INT_UPCOMPLETE); a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdSetIndicationEnable, INT_TXCOMPLETE | INT_UPCOMPLETE); a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdAcknowledgeInterrupt, 0x661); } /** * a3c90x_open - Routine to initialize the card. Initialize hardware, * allocate TX and RX ring, send RX ring address to the NIC. * * @v netdev Network device info * * @ret Returns 0 on success, negative on failure */ static int a3c90x_open(struct net_device *netdev) { int rc; struct INF_3C90X *inf_3c90x = netdev_priv(netdev); DBGP("a3c90x_open\n"); a3c90x_hw_start(netdev); rc = a3c90x_setup_tx_ring(inf_3c90x); if (rc != 0) { DBG("Error setting up TX Ring\n"); goto error; } rc = a3c90x_setup_rx_ring(inf_3c90x); if (rc != 0) { DBG("Error setting up RX Ring\n"); goto error; } /* send rx_ring address to NIC */ outl(virt_to_bus(inf_3c90x->rx_ring), inf_3c90x->IOAddr + regUpListPtr_l); /* enable packet transmission and reception */ a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdTxEnable, 0); a3c90x_internal_IssueCommand(inf_3c90x->IOAddr, cmdRxEnable, 0); return 0; error: a3c90x_free_resources(inf_3c90x); a3c90x_reset(inf_3c90x); return rc; } /** * a3c90x_close - free()s TX and RX ring, disablex RX/TX, resets NIC * * @v netdev Network device info */ static void a3c90x_close(struct net_device *netdev) { struct INF_3C90X *inf_3c90x = netdev_priv(netdev); DBGP("a3c90x_close\n"); a3c90x_reset(inf_3c90x); outw(cmdRxDisable, inf_3c90x->IOAddr + regCommandIntStatus_w); outw(cmdTxDisable, inf_3c90x->IOAddr + regCommandIntStatus_w); a3c90x_free_resources(inf_3c90x); } static struct net_device_operations a3c90x_operations = { .open = a3c90x_open, .close = a3c90x_close, .poll = a3c90x_poll, .transmit = a3c90x_transmit, .irq = a3c90x_irq, }; /** * a3c90x_probe: exported routine to probe for the 3c905 card. * If this routine is called, the pci functions did find the * card. We read the eeprom here and get the MAC address. * Initialization is done in a3c90x_open(). * * @v pci PCI device info * @ pci_id PCI device IDs * * @ret rc Returns 0 on success, negative on failure */ static int a3c90x_probe(struct pci_device *pci, const struct pci_device_id *pci_id __unused) { struct net_device *netdev; struct INF_3C90X *inf_3c90x; unsigned char *HWAddr; int rc; DBGP("a3c90x_probe\n"); if (pci->ioaddr == 0) return -EINVAL; netdev = alloc_etherdev(sizeof(*inf_3c90x)); if (!netdev) return -ENOMEM; netdev_init(netdev, &a3c90x_operations); pci_set_drvdata(pci, netdev); netdev->dev = &pci->dev; inf_3c90x = netdev_priv(netdev); memset(inf_3c90x, 0, sizeof(*inf_3c90x)); adjust_pci_device(pci); inf_3c90x->is3c556 = (pci->device == 0x6055); inf_3c90x->IOAddr = pci->ioaddr; inf_3c90x->CurrentWindow = winNone; inf_3c90x->isBrev = 1; switch (pci->device) { case 0x9000: /* 10 Base TPO */ case 0x9001: /* 10/100 T4 */ case 0x9050: /* 10/100 TPO */ case 0x9051: /* 10 Base Combo */ inf_3c90x->isBrev = 0; break; } DBG("[3c90x]: found NIC(0x%04X, 0x%04X), isBrev=%d, is3c556=%d\n", pci->vendor, pci->device, inf_3c90x->isBrev, inf_3c90x->is3c556); /* initialize nvs device */ inf_3c90x->nvs.word_len_log2 = 1; /* word */ inf_3c90x->nvs.size = (inf_3c90x->isBrev ? 0x20 : 0x17); inf_3c90x->nvs.block_size = 1; inf_3c90x->nvs.read = a3c90x_internal_ReadEeprom; inf_3c90x->nvs.write = a3c90x_internal_WriteEeprom; /* reset NIC before accessing any data from it */ a3c90x_reset(inf_3c90x); /* load eeprom contents to inf_3c90x->eeprom */ a3c90x_internal_ReadEepromContents(inf_3c90x); HWAddr = netdev->hw_addr; /* Retrieve the Hardware address */ HWAddr[0] = inf_3c90x->eeprom[eepromHwAddrOffset + 0] >> 8; HWAddr[1] = inf_3c90x->eeprom[eepromHwAddrOffset + 0] & 0xFF; HWAddr[2] = inf_3c90x->eeprom[eepromHwAddrOffset + 1] >> 8; HWAddr[3] = inf_3c90x->eeprom[eepromHwAddrOffset + 1] & 0xFF; HWAddr[4] = inf_3c90x->eeprom[eepromHwAddrOffset + 2] >> 8; HWAddr[5] = inf_3c90x->eeprom[eepromHwAddrOffset + 2] & 0xFF; /* we don't handle linkstates yet, so we're always up */ netdev_link_up(netdev); if ((rc = register_netdev(netdev)) != 0) { DBG("3c90x: register_netdev() failed\n"); netdev_put(netdev); return rc; } return 0; } static struct pci_device_id a3c90x_nics[] = { /* Original 90x revisions: */ PCI_ROM(0x10b7, 0x6055, "3c556", "3C556", 0), /* Huricane */ PCI_ROM(0x10b7, 0x9000, "3c905-tpo", "3Com900-TPO", 0), /* 10 Base TPO */ PCI_ROM(0x10b7, 0x9001, "3c905-t4", "3Com900-Combo", 0), /* 10/100 T4 */ PCI_ROM(0x10b7, 0x9050, "3c905-tpo100", "3Com905-TX", 0), /* 100 Base TX / 10/100 TPO */ PCI_ROM(0x10b7, 0x9051, "3c905-combo", "3Com905-T4", 0), /* 100 Base T4 / 10 Base Combo */ /* Newer 90xB revisions: */ PCI_ROM(0x10b7, 0x9004, "3c905b-tpo", "3Com900B-TPO", 0), /* 10 Base TPO */ PCI_ROM(0x10b7, 0x9005, "3c905b-combo", "3Com900B-Combo", 0), /* 10 Base Combo */ PCI_ROM(0x10b7, 0x9006, "3c905b-tpb2", "3Com900B-2/T", 0), /* 10 Base TP and Base2 */ PCI_ROM(0x10b7, 0x900a, "3c905b-fl", "3Com900B-FL", 0), /* 10 Base FL */ PCI_ROM(0x10b7, 0x9055, "3c905b-tpo100", "3Com905B-TX", 0), /* 10/100 TPO */ PCI_ROM(0x10b7, 0x9056, "3c905b-t4", "3Com905B-T4", 0), /* 10/100 T4 */ PCI_ROM(0x10b7, 0x9058, "3c905b-9058", "3Com905B-9058", 0), /* Cyclone 10/100/BNC */ PCI_ROM(0x10b7, 0x905a, "3c905b-fx", "3Com905B-FL", 0), /* 100 Base FX / 10 Base FX */ /* Newer 90xC revision: */ PCI_ROM(0x10b7, 0x9200, "3c905c-tpo", "3Com905C-TXM", 0), /* 10/100 TPO (3C905C-TXM) */ PCI_ROM(0x10b7, 0x9202, "3c920b-emb-ati", "3c920B-EMB-WNM (ATI Radeon 9100 IGP)", 0), /* 3c920B-EMB-WNM (ATI Radeon 9100 IGP) */ PCI_ROM(0x10b7, 0x9210, "3c920b-emb-wnm", "3Com20B-EMB WNM", 0), PCI_ROM(0x10b7, 0x9800, "3c980", "3Com980-Cyclone", 0), /* Cyclone */ PCI_ROM(0x10b7, 0x9805, "3c9805", "3Com9805", 0), /* Dual Port Server Cyclone */ PCI_ROM(0x10b7, 0x7646, "3csoho100-tx", "3CSOHO100-TX", 0), /* Hurricane */ PCI_ROM(0x10b7, 0x4500, "3c450", "3Com450 HomePNA Tornado", 0), PCI_ROM(0x10b7, 0x1201, "3c982a", "3Com982A", 0), PCI_ROM(0x10b7, 0x1202, "3c982b", "3Com982B", 0), }; struct pci_driver a3c90x_driver __pci_driver = { .ids = a3c90x_nics, .id_count = (sizeof(a3c90x_nics) / sizeof(a3c90x_nics[0])), .probe = a3c90x_probe, .remove = a3c90x_remove, }; /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/etherfabric.c0000664000000000000000000033663312524662415021647 0ustar /************************************************************************** * * Etherboot driver for Level 5 Etherfabric network cards * * Written by Michael Brown * * Copyright Fen Systems Ltd. 2005 * Copyright Level 5 Networks Inc. 2005 * * This software may be used and distributed according to the terms of * the GNU General Public License (GPL), incorporated herein by * reference. Drivers based on or derived from this code fall under * the GPL and must retain the authorship, copyright and license * notice. * ************************************************************************** */ FILE_LICENCE ( GPL_ANY ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "etherfabric.h" #include "etherfabric_nic.h" /************************************************************************** * * Constants and macros * ************************************************************************** */ #define EFAB_REGDUMP(...) #define EFAB_TRACE(...) DBGP(__VA_ARGS__) // printf() is not allowed within drivers. Use DBG() instead. #define EFAB_LOG(...) DBG(__VA_ARGS__) #define EFAB_ERR(...) DBG(__VA_ARGS__) #define FALCON_USE_IO_BAR 0 #define HZ 100 #define EFAB_BYTE 1 /************************************************************************** * * Hardware data structures and sizing * ************************************************************************** */ extern int __invalid_queue_size; #define FQS(_prefix, _x) \ ( ( (_x) == 512 ) ? _prefix ## _SIZE_512 : \ ( ( (_x) == 1024 ) ? _prefix ## _SIZE_1K : \ ( ( (_x) == 2048 ) ? _prefix ## _SIZE_2K : \ ( ( (_x) == 4096) ? _prefix ## _SIZE_4K : \ __invalid_queue_size ) ) ) ) #define EFAB_MAX_FRAME_LEN(mtu) \ ( ( ( ( mtu ) + 4/* FCS */ ) + 7 ) & ~7 ) /************************************************************************** * * GMII routines * ************************************************************************** */ static void falcon_mdio_write (struct efab_nic *efab, int device, int location, int value ); static int falcon_mdio_read ( struct efab_nic *efab, int device, int location ); /* GMII registers */ #define GMII_PSSR 0x11 /* PHY-specific status register */ /* Pseudo extensions to the link partner ability register */ #define LPA_EF_1000FULL 0x00020000 #define LPA_EF_1000HALF 0x00010000 #define LPA_EF_10000FULL 0x00040000 #define LPA_EF_10000HALF 0x00080000 #define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) #define LPA_EF_1000 ( LPA_EF_1000FULL | LPA_EF_1000HALF ) #define LPA_EF_10000 ( LPA_EF_10000FULL | LPA_EF_10000HALF ) #define LPA_EF_DUPLEX ( LPA_10FULL | LPA_100FULL | LPA_EF_1000FULL | \ LPA_EF_10000FULL ) /* Mask of bits not associated with speed or duplexity. */ #define LPA_OTHER ~( LPA_10FULL | LPA_10HALF | LPA_100FULL | \ LPA_100HALF | LPA_EF_1000FULL | LPA_EF_1000HALF ) /* PHY-specific status register */ #define PSSR_LSTATUS 0x0400 /* Bit 10 - link status */ /** * Retrieve GMII autonegotiation advertised abilities * */ static unsigned int gmii_autoneg_advertised ( struct efab_nic *efab ) { unsigned int mii_advertise; unsigned int gmii_advertise; /* Extended bits are in bits 8 and 9 of MII_CTRL1000 */ mii_advertise = falcon_mdio_read ( efab, 0, MII_ADVERTISE ); gmii_advertise = ( ( falcon_mdio_read ( efab, 0, MII_CTRL1000 ) >> 8 ) & 0x03 ); return ( ( gmii_advertise << 16 ) | mii_advertise ); } /** * Retrieve GMII autonegotiation link partner abilities * */ static unsigned int gmii_autoneg_lpa ( struct efab_nic *efab ) { unsigned int mii_lpa; unsigned int gmii_lpa; /* Extended bits are in bits 10 and 11 of MII_STAT1000 */ mii_lpa = falcon_mdio_read ( efab, 0, MII_LPA ); gmii_lpa = ( falcon_mdio_read ( efab, 0, MII_STAT1000 ) >> 10 ) & 0x03; return ( ( gmii_lpa << 16 ) | mii_lpa ); } /** * Calculate GMII autonegotiated link technology * */ static unsigned int gmii_nway_result ( unsigned int negotiated ) { unsigned int other_bits; /* Mask out the speed and duplexity bits */ other_bits = negotiated & LPA_OTHER; if ( negotiated & LPA_EF_1000FULL ) return ( other_bits | LPA_EF_1000FULL ); else if ( negotiated & LPA_EF_1000HALF ) return ( other_bits | LPA_EF_1000HALF ); else if ( negotiated & LPA_100FULL ) return ( other_bits | LPA_100FULL ); else if ( negotiated & LPA_100BASE4 ) return ( other_bits | LPA_100BASE4 ); else if ( negotiated & LPA_100HALF ) return ( other_bits | LPA_100HALF ); else if ( negotiated & LPA_10FULL ) return ( other_bits | LPA_10FULL ); else return ( other_bits | LPA_10HALF ); } /** * Check GMII PHY link status * */ static int gmii_link_ok ( struct efab_nic *efab ) { int status; int phy_status; /* BMSR is latching - it returns "link down" if the link has * been down at any point since the last read. To get a * real-time status, we therefore read the register twice and * use the result of the second read. */ (void) falcon_mdio_read ( efab, 0, MII_BMSR ); status = falcon_mdio_read ( efab, 0, MII_BMSR ); /* Read the PHY-specific Status Register. This is * non-latching, so we need do only a single read. */ phy_status = falcon_mdio_read ( efab, 0, GMII_PSSR ); return ( ( status & BMSR_LSTATUS ) && ( phy_status & PSSR_LSTATUS ) ); } /************************************************************************** * * MDIO routines * ************************************************************************** */ /* Numbering of the MDIO Manageable Devices (MMDs) */ /* Physical Medium Attachment/ Physical Medium Dependent sublayer */ #define MDIO_MMD_PMAPMD (1) /* WAN Interface Sublayer */ #define MDIO_MMD_WIS (2) /* Physical Coding Sublayer */ #define MDIO_MMD_PCS (3) /* PHY Extender Sublayer */ #define MDIO_MMD_PHYXS (4) /* Extender Sublayer */ #define MDIO_MMD_DTEXS (5) /* Transmission convergence */ #define MDIO_MMD_TC (6) /* Auto negotiation */ #define MDIO_MMD_AN (7) /* Generic register locations */ #define MDIO_MMDREG_CTRL1 (0) #define MDIO_MMDREG_STAT1 (1) #define MDIO_MMDREG_DEVS0 (5) #define MDIO_MMDREG_STAT2 (8) /* Bits in MMDREG_CTRL1 */ /* Reset */ #define MDIO_MMDREG_CTRL1_RESET_LBN (15) #define MDIO_MMDREG_CTRL1_RESET_WIDTH (1) /* Bits in MMDREG_STAT1 */ #define MDIO_MMDREG_STAT1_FAULT_LBN (7) #define MDIO_MMDREG_STAT1_FAULT_WIDTH (1) /* Link state */ #define MDIO_MMDREG_STAT1_LINK_LBN (2) #define MDIO_MMDREG_STAT1_LINK_WIDTH (1) /* Bits in MMDREG_DEVS0. */ #define DEV_PRESENT_BIT(_b) (1 << _b) #define MDIO_MMDREG_DEVS0_DTEXS DEV_PRESENT_BIT(MDIO_MMD_DTEXS) #define MDIO_MMDREG_DEVS0_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS) #define MDIO_MMDREG_DEVS0_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS) #define MDIO_MMDREG_DEVS0_WIS DEV_PRESENT_BIT(MDIO_MMD_WIS) #define MDIO_MMDREG_DEVS0_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD) #define MDIO_MMDREG_DEVS0_AN DEV_PRESENT_BIT(MDIO_MMD_AN) /* Bits in MMDREG_STAT2 */ #define MDIO_MMDREG_STAT2_PRESENT_VAL (2) #define MDIO_MMDREG_STAT2_PRESENT_LBN (14) #define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2) /* PHY XGXS lane state */ #define MDIO_PHYXS_LANE_STATE (0x18) #define MDIO_PHYXS_LANE_ALIGNED_LBN (12) #define MDIO_PHYXS_LANE_SYNC0_LBN (0) #define MDIO_PHYXS_LANE_SYNC1_LBN (1) #define MDIO_PHYXS_LANE_SYNC2_LBN (2) #define MDIO_PHYXS_LANE_SYNC3_LBN (3) /* This ought to be ridiculous overkill. We expect it to fail rarely */ #define MDIO45_RESET_TRIES 100 #define MDIO45_RESET_SPINTIME 10 static int mdio_clause45_wait_reset_mmds ( struct efab_nic* efab ) { int tries = MDIO45_RESET_TRIES; int in_reset; while(tries) { int mask = efab->phy_op->mmds; int mmd = 0; in_reset = 0; while(mask) { if (mask & 1) { int stat = falcon_mdio_read ( efab, mmd, MDIO_MMDREG_CTRL1 ); if (stat < 0) { EFAB_ERR("Failed to read status of MMD %d\n", mmd ); in_reset = 1; break; } if (stat & (1 << MDIO_MMDREG_CTRL1_RESET_LBN)) in_reset |= (1 << mmd); } mask = mask >> 1; mmd++; } if (!in_reset) break; tries--; mdelay ( MDIO45_RESET_SPINTIME ); } if (in_reset != 0) { EFAB_ERR("Not all MMDs came out of reset in time. MMDs " "still in reset: %x\n", in_reset); return -ETIMEDOUT; } return 0; } static int mdio_clause45_reset_mmd ( struct efab_nic *efab, int mmd ) { int tries = MDIO45_RESET_TRIES; int ctrl; falcon_mdio_write ( efab, mmd, MDIO_MMDREG_CTRL1, ( 1 << MDIO_MMDREG_CTRL1_RESET_LBN ) ); /* Wait for the reset bit to clear. */ do { mdelay ( MDIO45_RESET_SPINTIME ); ctrl = falcon_mdio_read ( efab, mmd, MDIO_MMDREG_CTRL1 ); if ( ~ctrl & ( 1 << MDIO_MMDREG_CTRL1_RESET_LBN ) ) return 0; } while ( --tries ); EFAB_ERR ( "Failed to reset mmd %d\n", mmd ); return -ETIMEDOUT; } static int mdio_clause45_links_ok(struct efab_nic *efab ) { int status, good; int ok = 1; int mmd = 0; int mmd_mask = efab->phy_op->mmds; while (mmd_mask) { if (mmd_mask & 1) { /* Double reads because link state is latched, and a * read moves the current state into the register */ status = falcon_mdio_read ( efab, mmd, MDIO_MMDREG_STAT1 ); status = falcon_mdio_read ( efab, mmd, MDIO_MMDREG_STAT1 ); good = status & (1 << MDIO_MMDREG_STAT1_LINK_LBN); ok = ok && good; } mmd_mask = (mmd_mask >> 1); mmd++; } return ok; } static int mdio_clause45_check_mmds ( struct efab_nic *efab ) { int mmd = 0; int devices = falcon_mdio_read ( efab, MDIO_MMD_PHYXS, MDIO_MMDREG_DEVS0 ); int mmd_mask = efab->phy_op->mmds; /* Check all the expected MMDs are present */ if ( devices < 0 ) { EFAB_ERR ( "Failed to read devices present\n" ); return -EIO; } if ( ( devices & mmd_mask ) != mmd_mask ) { EFAB_ERR ( "required MMDs not present: got %x, wanted %x\n", devices, mmd_mask ); return -EIO; } /* Check all required MMDs are responding and happy. */ while ( mmd_mask ) { if ( mmd_mask & 1 ) { efab_dword_t reg; int status; reg.opaque = falcon_mdio_read ( efab, mmd, MDIO_MMDREG_STAT2 ); status = EFAB_DWORD_FIELD ( reg, MDIO_MMDREG_STAT2_PRESENT ); if ( status != MDIO_MMDREG_STAT2_PRESENT_VAL ) { return -EIO; } } mmd_mask >>= 1; mmd++; } return 0; } /* I/O BAR address register */ #define FCN_IOM_IND_ADR_REG 0x0 /* I/O BAR data register */ #define FCN_IOM_IND_DAT_REG 0x4 /* Address region register */ #define FCN_ADR_REGION_REG_KER 0x00 #define FCN_ADR_REGION0_LBN 0 #define FCN_ADR_REGION0_WIDTH 18 #define FCN_ADR_REGION1_LBN 32 #define FCN_ADR_REGION1_WIDTH 18 #define FCN_ADR_REGION2_LBN 64 #define FCN_ADR_REGION2_WIDTH 18 #define FCN_ADR_REGION3_LBN 96 #define FCN_ADR_REGION3_WIDTH 18 /* Interrupt enable register */ #define FCN_INT_EN_REG_KER 0x0010 #define FCN_MEM_PERR_INT_EN_KER_LBN 5 #define FCN_MEM_PERR_INT_EN_KER_WIDTH 1 #define FCN_KER_INT_CHAR_LBN 4 #define FCN_KER_INT_CHAR_WIDTH 1 #define FCN_KER_INT_KER_LBN 3 #define FCN_KER_INT_KER_WIDTH 1 #define FCN_ILL_ADR_ERR_INT_EN_KER_LBN 2 #define FCN_ILL_ADR_ERR_INT_EN_KER_WIDTH 1 #define FCN_SRM_PERR_INT_EN_KER_LBN 1 #define FCN_SRM_PERR_INT_EN_KER_WIDTH 1 #define FCN_DRV_INT_EN_KER_LBN 0 #define FCN_DRV_INT_EN_KER_WIDTH 1 /* Interrupt status register */ #define FCN_INT_ADR_REG_KER 0x0030 #define FCN_INT_ADR_KER_LBN 0 #define FCN_INT_ADR_KER_WIDTH EFAB_DMA_TYPE_WIDTH ( 64 ) /* Interrupt status register (B0 only) */ #define INT_ISR0_B0 0x90 #define INT_ISR1_B0 0xA0 /* Interrupt acknowledge register (A0/A1 only) */ #define FCN_INT_ACK_KER_REG_A1 0x0050 #define INT_ACK_DUMMY_DATA_LBN 0 #define INT_ACK_DUMMY_DATA_WIDTH 32 /* Interrupt acknowledge work-around register (A0/A1 only )*/ #define WORK_AROUND_BROKEN_PCI_READS_REG_KER_A1 0x0070 /* Hardware initialisation register */ #define FCN_HW_INIT_REG_KER 0x00c0 #define FCN_BCSR_TARGET_MASK_LBN 101 #define FCN_BCSR_TARGET_MASK_WIDTH 4 /* SPI host command register */ #define FCN_EE_SPI_HCMD_REG 0x0100 #define FCN_EE_SPI_HCMD_CMD_EN_LBN 31 #define FCN_EE_SPI_HCMD_CMD_EN_WIDTH 1 #define FCN_EE_WR_TIMER_ACTIVE_LBN 28 #define FCN_EE_WR_TIMER_ACTIVE_WIDTH 1 #define FCN_EE_SPI_HCMD_SF_SEL_LBN 24 #define FCN_EE_SPI_HCMD_SF_SEL_WIDTH 1 #define FCN_EE_SPI_EEPROM 0 #define FCN_EE_SPI_FLASH 1 #define FCN_EE_SPI_HCMD_DABCNT_LBN 16 #define FCN_EE_SPI_HCMD_DABCNT_WIDTH 5 #define FCN_EE_SPI_HCMD_READ_LBN 15 #define FCN_EE_SPI_HCMD_READ_WIDTH 1 #define FCN_EE_SPI_READ 1 #define FCN_EE_SPI_WRITE 0 #define FCN_EE_SPI_HCMD_DUBCNT_LBN 12 #define FCN_EE_SPI_HCMD_DUBCNT_WIDTH 2 #define FCN_EE_SPI_HCMD_ADBCNT_LBN 8 #define FCN_EE_SPI_HCMD_ADBCNT_WIDTH 2 #define FCN_EE_SPI_HCMD_ENC_LBN 0 #define FCN_EE_SPI_HCMD_ENC_WIDTH 8 /* SPI host address register */ #define FCN_EE_SPI_HADR_REG 0x0110 #define FCN_EE_SPI_HADR_DUBYTE_LBN 24 #define FCN_EE_SPI_HADR_DUBYTE_WIDTH 8 #define FCN_EE_SPI_HADR_ADR_LBN 0 #define FCN_EE_SPI_HADR_ADR_WIDTH 24 /* SPI host data register */ #define FCN_EE_SPI_HDATA_REG 0x0120 #define FCN_EE_SPI_HDATA3_LBN 96 #define FCN_EE_SPI_HDATA3_WIDTH 32 #define FCN_EE_SPI_HDATA2_LBN 64 #define FCN_EE_SPI_HDATA2_WIDTH 32 #define FCN_EE_SPI_HDATA1_LBN 32 #define FCN_EE_SPI_HDATA1_WIDTH 32 #define FCN_EE_SPI_HDATA0_LBN 0 #define FCN_EE_SPI_HDATA0_WIDTH 32 /* VPD Config 0 Register register */ #define FCN_EE_VPD_CFG_REG 0x0140 #define FCN_EE_VPD_EN_LBN 0 #define FCN_EE_VPD_EN_WIDTH 1 #define FCN_EE_VPD_EN_AD9_MODE_LBN 1 #define FCN_EE_VPD_EN_AD9_MODE_WIDTH 1 #define FCN_EE_EE_CLOCK_DIV_LBN 112 #define FCN_EE_EE_CLOCK_DIV_WIDTH 7 #define FCN_EE_SF_CLOCK_DIV_LBN 120 #define FCN_EE_SF_CLOCK_DIV_WIDTH 7 /* NIC status register */ #define FCN_NIC_STAT_REG 0x0200 #define FCN_ONCHIP_SRAM_LBN 16 #define FCN_ONCHIP_SRAM_WIDTH 1 #define FCN_SF_PRST_LBN 9 #define FCN_SF_PRST_WIDTH 1 #define FCN_EE_PRST_LBN 8 #define FCN_EE_PRST_WIDTH 1 #define FCN_EE_STRAP_LBN 7 #define FCN_EE_STRAP_WIDTH 1 #define FCN_PCI_PCIX_MODE_LBN 4 #define FCN_PCI_PCIX_MODE_WIDTH 3 #define FCN_PCI_PCIX_MODE_PCI33_DECODE 0 #define FCN_PCI_PCIX_MODE_PCI66_DECODE 1 #define FCN_PCI_PCIX_MODE_PCIX66_DECODE 5 #define FCN_PCI_PCIX_MODE_PCIX100_DECODE 6 #define FCN_PCI_PCIX_MODE_PCIX133_DECODE 7 #define FCN_STRAP_ISCSI_EN_LBN 3 #define FCN_STRAP_ISCSI_EN_WIDTH 1 #define FCN_STRAP_PINS_LBN 0 #define FCN_STRAP_PINS_WIDTH 3 #define FCN_STRAP_10G_LBN 2 #define FCN_STRAP_10G_WIDTH 1 #define FCN_STRAP_DUAL_PORT_LBN 1 #define FCN_STRAP_DUAL_PORT_WIDTH 1 #define FCN_STRAP_PCIE_LBN 0 #define FCN_STRAP_PCIE_WIDTH 1 /* Falcon revisions */ #define FALCON_REV_A0 0 #define FALCON_REV_A1 1 #define FALCON_REV_B0 2 /* GPIO control register */ #define FCN_GPIO_CTL_REG_KER 0x0210 #define FCN_GPIO_CTL_REG_KER 0x0210 #define FCN_GPIO3_OEN_LBN 27 #define FCN_GPIO3_OEN_WIDTH 1 #define FCN_GPIO2_OEN_LBN 26 #define FCN_GPIO2_OEN_WIDTH 1 #define FCN_GPIO1_OEN_LBN 25 #define FCN_GPIO1_OEN_WIDTH 1 #define FCN_GPIO0_OEN_LBN 24 #define FCN_GPIO0_OEN_WIDTH 1 #define FCN_GPIO3_OUT_LBN 19 #define FCN_GPIO3_OUT_WIDTH 1 #define FCN_GPIO2_OUT_LBN 18 #define FCN_GPIO2_OUT_WIDTH 1 #define FCN_GPIO1_OUT_LBN 17 #define FCN_GPIO1_OUT_WIDTH 1 #define FCN_GPIO0_OUT_LBN 16 #define FCN_GPIO0_OUT_WIDTH 1 #define FCN_GPIO3_IN_LBN 11 #define FCN_GPIO3_IN_WIDTH 1 #define FCN_GPIO2_IN_LBN 10 #define FCN_GPIO2_IN_WIDTH 1 #define FCN_GPIO1_IN_LBN 9 #define FCN_GPIO1_IN_WIDTH 1 #define FCN_GPIO0_IN_LBN 8 #define FCN_GPIO0_IN_WIDTH 1 #define FCN_FLASH_PRESENT_LBN 7 #define FCN_FLASH_PRESENT_WIDTH 1 #define FCN_EEPROM_PRESENT_LBN 6 #define FCN_EEPROM_PRESENT_WIDTH 1 #define FCN_BOOTED_USING_NVDEVICE_LBN 3 #define FCN_BOOTED_USING_NVDEVICE_WIDTH 1 /* Defines for extra non-volatile storage */ #define FCN_NV_MAGIC_NUMBER 0xFA1C /* Global control register */ #define FCN_GLB_CTL_REG_KER 0x0220 #define FCN_EXT_PHY_RST_CTL_LBN 63 #define FCN_EXT_PHY_RST_CTL_WIDTH 1 #define FCN_PCIE_SD_RST_CTL_LBN 61 #define FCN_PCIE_SD_RST_CTL_WIDTH 1 #define FCN_PCIE_STCK_RST_CTL_LBN 59 #define FCN_PCIE_STCK_RST_CTL_WIDTH 1 #define FCN_PCIE_NSTCK_RST_CTL_LBN 58 #define FCN_PCIE_NSTCK_RST_CTL_WIDTH 1 #define FCN_PCIE_CORE_RST_CTL_LBN 57 #define FCN_PCIE_CORE_RST_CTL_WIDTH 1 #define FCN_EE_RST_CTL_LBN 49 #define FCN_EE_RST_CTL_WIDTH 1 #define FCN_RST_EXT_PHY_LBN 31 #define FCN_RST_EXT_PHY_WIDTH 1 #define FCN_EXT_PHY_RST_DUR_LBN 1 #define FCN_EXT_PHY_RST_DUR_WIDTH 3 #define FCN_SWRST_LBN 0 #define FCN_SWRST_WIDTH 1 #define INCLUDE_IN_RESET 0 #define EXCLUDE_FROM_RESET 1 /* FPGA build version */ #define FCN_ALTERA_BUILD_REG_KER 0x0300 #define FCN_VER_MAJOR_LBN 24 #define FCN_VER_MAJOR_WIDTH 8 #define FCN_VER_MINOR_LBN 16 #define FCN_VER_MINOR_WIDTH 8 #define FCN_VER_BUILD_LBN 0 #define FCN_VER_BUILD_WIDTH 16 #define FCN_VER_ALL_LBN 0 #define FCN_VER_ALL_WIDTH 32 /* Spare EEPROM bits register (flash 0x390) */ #define FCN_SPARE_REG_KER 0x310 #define FCN_MEM_PERR_EN_TX_DATA_LBN 72 #define FCN_MEM_PERR_EN_TX_DATA_WIDTH 2 /* Timer table for kernel access */ #define FCN_TIMER_CMD_REG_KER 0x420 #define FCN_TIMER_MODE_LBN 12 #define FCN_TIMER_MODE_WIDTH 2 #define FCN_TIMER_MODE_DIS 0 #define FCN_TIMER_MODE_INT_HLDOFF 1 #define FCN_TIMER_VAL_LBN 0 #define FCN_TIMER_VAL_WIDTH 12 /* Receive configuration register */ #define FCN_RX_CFG_REG_KER 0x800 #define FCN_RX_XOFF_EN_LBN 0 #define FCN_RX_XOFF_EN_WIDTH 1 /* SRAM receive descriptor cache configuration register */ #define FCN_SRM_RX_DC_CFG_REG_KER 0x610 #define FCN_SRM_RX_DC_BASE_ADR_LBN 0 #define FCN_SRM_RX_DC_BASE_ADR_WIDTH 21 /* SRAM transmit descriptor cache configuration register */ #define FCN_SRM_TX_DC_CFG_REG_KER 0x620 #define FCN_SRM_TX_DC_BASE_ADR_LBN 0 #define FCN_SRM_TX_DC_BASE_ADR_WIDTH 21 /* SRAM configuration register */ #define FCN_SRM_CFG_REG_KER 0x630 #define FCN_SRAM_OOB_ADR_INTEN_LBN 5 #define FCN_SRAM_OOB_ADR_INTEN_WIDTH 1 #define FCN_SRAM_OOB_BUF_INTEN_LBN 4 #define FCN_SRAM_OOB_BUF_INTEN_WIDTH 1 #define FCN_SRAM_OOB_BT_INIT_EN_LBN 3 #define FCN_SRAM_OOB_BT_INIT_EN_WIDTH 1 #define FCN_SRM_NUM_BANK_LBN 2 #define FCN_SRM_NUM_BANK_WIDTH 1 #define FCN_SRM_BANK_SIZE_LBN 0 #define FCN_SRM_BANK_SIZE_WIDTH 2 #define FCN_SRM_NUM_BANKS_AND_BANK_SIZE_LBN 0 #define FCN_SRM_NUM_BANKS_AND_BANK_SIZE_WIDTH 3 #define FCN_RX_CFG_REG_KER 0x800 #define FCN_RX_INGR_EN_B0_LBN 47 #define FCN_RX_INGR_EN_B0_WIDTH 1 #define FCN_RX_USR_BUF_SIZE_B0_LBN 19 #define FCN_RX_USR_BUF_SIZE_B0_WIDTH 9 #define FCN_RX_XON_MAC_TH_B0_LBN 10 #define FCN_RX_XON_MAC_TH_B0_WIDTH 9 #define FCN_RX_XOFF_MAC_TH_B0_LBN 1 #define FCN_RX_XOFF_MAC_TH_B0_WIDTH 9 #define FCN_RX_XOFF_MAC_EN_B0_LBN 0 #define FCN_RX_XOFF_MAC_EN_B0_WIDTH 1 #define FCN_RX_USR_BUF_SIZE_A1_LBN 11 #define FCN_RX_USR_BUF_SIZE_A1_WIDTH 9 #define FCN_RX_XON_MAC_TH_A1_LBN 6 #define FCN_RX_XON_MAC_TH_A1_WIDTH 5 #define FCN_RX_XOFF_MAC_TH_A1_LBN 1 #define FCN_RX_XOFF_MAC_TH_A1_WIDTH 5 #define FCN_RX_XOFF_MAC_EN_A1_LBN 0 #define FCN_RX_XOFF_MAC_EN_A1_WIDTH 1 #define FCN_RX_USR_BUF_SIZE_A1_LBN 11 #define FCN_RX_USR_BUF_SIZE_A1_WIDTH 9 #define FCN_RX_XOFF_MAC_EN_A1_LBN 0 #define FCN_RX_XOFF_MAC_EN_A1_WIDTH 1 /* Receive filter control register */ #define FCN_RX_FILTER_CTL_REG_KER 0x810 #define FCN_UDP_FULL_SRCH_LIMIT_LBN 32 #define FCN_UDP_FULL_SRCH_LIMIT_WIDTH 8 #define FCN_NUM_KER_LBN 24 #define FCN_NUM_KER_WIDTH 2 #define FCN_UDP_WILD_SRCH_LIMIT_LBN 16 #define FCN_UDP_WILD_SRCH_LIMIT_WIDTH 8 #define FCN_TCP_WILD_SRCH_LIMIT_LBN 8 #define FCN_TCP_WILD_SRCH_LIMIT_WIDTH 8 #define FCN_TCP_FULL_SRCH_LIMIT_LBN 0 #define FCN_TCP_FULL_SRCH_LIMIT_WIDTH 8 /* RX queue flush register */ #define FCN_RX_FLUSH_DESCQ_REG_KER 0x0820 #define FCN_RX_FLUSH_DESCQ_CMD_LBN 24 #define FCN_RX_FLUSH_DESCQ_CMD_WIDTH 1 #define FCN_RX_FLUSH_DESCQ_LBN 0 #define FCN_RX_FLUSH_DESCQ_WIDTH 12 /* Receive descriptor update register */ #define FCN_RX_DESC_UPD_REG_KER 0x0830 #define FCN_RX_DESC_WPTR_LBN 96 #define FCN_RX_DESC_WPTR_WIDTH 12 #define FCN_RX_DESC_UPD_REG_KER_DWORD ( FCN_RX_DESC_UPD_REG_KER + 12 ) #define FCN_RX_DESC_WPTR_DWORD_LBN 0 #define FCN_RX_DESC_WPTR_DWORD_WIDTH 12 /* Receive descriptor cache configuration register */ #define FCN_RX_DC_CFG_REG_KER 0x840 #define FCN_RX_DC_SIZE_LBN 0 #define FCN_RX_DC_SIZE_WIDTH 2 #define FCN_RX_SELF_RST_REG_KER 0x890 #define FCN_RX_ISCSI_DIS_LBN 17 #define FCN_RX_ISCSI_DIS_WIDTH 1 #define FCN_RX_NODESC_WAIT_DIS_LBN 9 #define FCN_RX_NODESC_WAIT_DIS_WIDTH 1 #define FCN_RX_RECOVERY_EN_LBN 8 #define FCN_RX_RECOVERY_EN_WIDTH 1 /* TX queue flush register */ #define FCN_TX_FLUSH_DESCQ_REG_KER 0x0a00 #define FCN_TX_FLUSH_DESCQ_CMD_LBN 12 #define FCN_TX_FLUSH_DESCQ_CMD_WIDTH 1 #define FCN_TX_FLUSH_DESCQ_LBN 0 #define FCN_TX_FLUSH_DESCQ_WIDTH 12 /* Transmit configuration register 2 */ #define FCN_TX_CFG2_REG_KER 0xa80 #define FCN_TX_DIS_NON_IP_EV_LBN 17 #define FCN_TX_DIS_NON_IP_EV_WIDTH 1 /* Transmit descriptor update register */ #define FCN_TX_DESC_UPD_REG_KER 0x0a10 #define FCN_TX_DESC_WPTR_LBN 96 #define FCN_TX_DESC_WPTR_WIDTH 12 #define FCN_TX_DESC_UPD_REG_KER_DWORD ( FCN_TX_DESC_UPD_REG_KER + 12 ) #define FCN_TX_DESC_WPTR_DWORD_LBN 0 #define FCN_TX_DESC_WPTR_DWORD_WIDTH 12 /* Transmit descriptor cache configuration register */ #define FCN_TX_DC_CFG_REG_KER 0xa20 #define FCN_TX_DC_SIZE_LBN 0 #define FCN_TX_DC_SIZE_WIDTH 2 /* PHY management transmit data register */ #define FCN_MD_TXD_REG_KER 0xc00 #define FCN_MD_TXD_LBN 0 #define FCN_MD_TXD_WIDTH 16 /* PHY management receive data register */ #define FCN_MD_RXD_REG_KER 0xc10 #define FCN_MD_RXD_LBN 0 #define FCN_MD_RXD_WIDTH 16 /* PHY management configuration & status register */ #define FCN_MD_CS_REG_KER 0xc20 #define FCN_MD_GC_LBN 4 #define FCN_MD_GC_WIDTH 1 #define FCN_MD_RIC_LBN 2 #define FCN_MD_RIC_WIDTH 1 #define FCN_MD_RDC_LBN 1 #define FCN_MD_RDC_WIDTH 1 #define FCN_MD_WRC_LBN 0 #define FCN_MD_WRC_WIDTH 1 /* PHY management PHY address register */ #define FCN_MD_PHY_ADR_REG_KER 0xc30 #define FCN_MD_PHY_ADR_LBN 0 #define FCN_MD_PHY_ADR_WIDTH 16 /* PHY management ID register */ #define FCN_MD_ID_REG_KER 0xc40 #define FCN_MD_PRT_ADR_LBN 11 #define FCN_MD_PRT_ADR_WIDTH 5 #define FCN_MD_DEV_ADR_LBN 6 #define FCN_MD_DEV_ADR_WIDTH 5 /* PHY management status & mask register */ #define FCN_MD_STAT_REG_KER 0xc50 #define FCN_MD_PINT_LBN 4 #define FCN_MD_PINT_WIDTH 1 #define FCN_MD_DONE_LBN 3 #define FCN_MD_DONE_WIDTH 1 #define FCN_MD_BSERR_LBN 2 #define FCN_MD_BSERR_WIDTH 1 #define FCN_MD_LNFL_LBN 1 #define FCN_MD_LNFL_WIDTH 1 #define FCN_MD_BSY_LBN 0 #define FCN_MD_BSY_WIDTH 1 /* Port 0 and 1 MAC control registers */ #define FCN_MAC0_CTRL_REG_KER 0xc80 #define FCN_MAC1_CTRL_REG_KER 0xc90 #define FCN_MAC_XOFF_VAL_LBN 16 #define FCN_MAC_XOFF_VAL_WIDTH 16 #define FCN_MAC_BCAD_ACPT_LBN 4 #define FCN_MAC_BCAD_ACPT_WIDTH 1 #define FCN_MAC_UC_PROM_LBN 3 #define FCN_MAC_UC_PROM_WIDTH 1 #define FCN_MAC_LINK_STATUS_LBN 2 #define FCN_MAC_LINK_STATUS_WIDTH 1 #define FCN_MAC_SPEED_LBN 0 #define FCN_MAC_SPEED_WIDTH 2 /* 10Gig Xaui XGXS Default Values */ #define XX_TXDRV_DEQ_DEFAULT 0xe /* deq=.6 */ #define XX_TXDRV_DTX_DEFAULT 0x5 /* 1.25 */ #define XX_SD_CTL_DRV_DEFAULT 0 /* 20mA */ /* GMAC registers */ #define FALCON_GMAC_REGBANK 0xe00 #define FALCON_GMAC_REGBANK_SIZE 0x200 #define FALCON_GMAC_REG_SIZE 0x10 /* XGMAC registers */ #define FALCON_XMAC_REGBANK 0x1200 #define FALCON_XMAC_REGBANK_SIZE 0x200 #define FALCON_XMAC_REG_SIZE 0x10 /* XGMAC address register low */ #define FCN_XM_ADR_LO_REG_MAC 0x00 #define FCN_XM_ADR_3_LBN 24 #define FCN_XM_ADR_3_WIDTH 8 #define FCN_XM_ADR_2_LBN 16 #define FCN_XM_ADR_2_WIDTH 8 #define FCN_XM_ADR_1_LBN 8 #define FCN_XM_ADR_1_WIDTH 8 #define FCN_XM_ADR_0_LBN 0 #define FCN_XM_ADR_0_WIDTH 8 /* XGMAC address register high */ #define FCN_XM_ADR_HI_REG_MAC 0x01 #define FCN_XM_ADR_5_LBN 8 #define FCN_XM_ADR_5_WIDTH 8 #define FCN_XM_ADR_4_LBN 0 #define FCN_XM_ADR_4_WIDTH 8 /* XGMAC global configuration - port 0*/ #define FCN_XM_GLB_CFG_REG_MAC 0x02 #define FCN_XM_RX_STAT_EN_LBN 11 #define FCN_XM_RX_STAT_EN_WIDTH 1 #define FCN_XM_TX_STAT_EN_LBN 10 #define FCN_XM_TX_STAT_EN_WIDTH 1 #define FCN_XM_RX_JUMBO_MODE_LBN 6 #define FCN_XM_RX_JUMBO_MODE_WIDTH 1 #define FCN_XM_CORE_RST_LBN 0 #define FCN_XM_CORE_RST_WIDTH 1 /* XGMAC transmit configuration - port 0 */ #define FCN_XM_TX_CFG_REG_MAC 0x03 #define FCN_XM_IPG_LBN 16 #define FCN_XM_IPG_WIDTH 4 #define FCN_XM_FCNTL_LBN 10 #define FCN_XM_FCNTL_WIDTH 1 #define FCN_XM_TXCRC_LBN 8 #define FCN_XM_TXCRC_WIDTH 1 #define FCN_XM_AUTO_PAD_LBN 5 #define FCN_XM_AUTO_PAD_WIDTH 1 #define FCN_XM_TX_PRMBL_LBN 2 #define FCN_XM_TX_PRMBL_WIDTH 1 #define FCN_XM_TXEN_LBN 1 #define FCN_XM_TXEN_WIDTH 1 /* XGMAC receive configuration - port 0 */ #define FCN_XM_RX_CFG_REG_MAC 0x04 #define FCN_XM_PASS_CRC_ERR_LBN 25 #define FCN_XM_PASS_CRC_ERR_WIDTH 1 #define FCN_XM_AUTO_DEPAD_LBN 8 #define FCN_XM_AUTO_DEPAD_WIDTH 1 #define FCN_XM_RXEN_LBN 1 #define FCN_XM_RXEN_WIDTH 1 /* XGMAC management interrupt mask register */ #define FCN_XM_MGT_INT_MSK_REG_MAC_B0 0x5 #define FCN_XM_MSK_PRMBLE_ERR_LBN 2 #define FCN_XM_MSK_PRMBLE_ERR_WIDTH 1 #define FCN_XM_MSK_RMTFLT_LBN 1 #define FCN_XM_MSK_RMTFLT_WIDTH 1 #define FCN_XM_MSK_LCLFLT_LBN 0 #define FCN_XM_MSK_LCLFLT_WIDTH 1 /* XGMAC flow control register */ #define FCN_XM_FC_REG_MAC 0x7 #define FCN_XM_PAUSE_TIME_LBN 16 #define FCN_XM_PAUSE_TIME_WIDTH 16 #define FCN_XM_DIS_FCNTL_LBN 0 #define FCN_XM_DIS_FCNTL_WIDTH 1 /* XGMAC transmit parameter register */ #define FCN_XM_TX_PARAM_REG_MAC 0x0d #define FCN_XM_TX_JUMBO_MODE_LBN 31 #define FCN_XM_TX_JUMBO_MODE_WIDTH 1 #define FCN_XM_MAX_TX_FRM_SIZE_LBN 16 #define FCN_XM_MAX_TX_FRM_SIZE_WIDTH 14 #define FCN_XM_ACPT_ALL_MCAST_LBN 11 #define FCN_XM_ACPT_ALL_MCAST_WIDTH 1 /* XGMAC receive parameter register */ #define FCN_XM_RX_PARAM_REG_MAC 0x0e #define FCN_XM_MAX_RX_FRM_SIZE_LBN 0 #define FCN_XM_MAX_RX_FRM_SIZE_WIDTH 14 /* XGMAC management interrupt status register */ #define FCN_XM_MGT_INT_REG_MAC_B0 0x0f #define FCN_XM_PRMBLE_ERR 2 #define FCN_XM_PRMBLE_WIDTH 1 #define FCN_XM_RMTFLT_LBN 1 #define FCN_XM_RMTFLT_WIDTH 1 #define FCN_XM_LCLFLT_LBN 0 #define FCN_XM_LCLFLT_WIDTH 1 /* XAUI XGXS core status register */ #define FCN_XX_ALIGN_DONE_LBN 20 #define FCN_XX_ALIGN_DONE_WIDTH 1 #define FCN_XX_CORE_STAT_REG_MAC 0x16 #define FCN_XX_SYNC_STAT_LBN 16 #define FCN_XX_SYNC_STAT_WIDTH 4 #define FCN_XX_SYNC_STAT_DECODE_SYNCED 0xf #define FCN_XX_COMMA_DET_LBN 12 #define FCN_XX_COMMA_DET_WIDTH 4 #define FCN_XX_COMMA_DET_RESET 0xf #define FCN_XX_CHARERR_LBN 4 #define FCN_XX_CHARERR_WIDTH 4 #define FCN_XX_CHARERR_RESET 0xf #define FCN_XX_DISPERR_LBN 0 #define FCN_XX_DISPERR_WIDTH 4 #define FCN_XX_DISPERR_RESET 0xf /* XGXS/XAUI powerdown/reset register */ #define FCN_XX_PWR_RST_REG_MAC 0x10 #define FCN_XX_PWRDND_EN_LBN 15 #define FCN_XX_PWRDND_EN_WIDTH 1 #define FCN_XX_PWRDNC_EN_LBN 14 #define FCN_XX_PWRDNC_EN_WIDTH 1 #define FCN_XX_PWRDNB_EN_LBN 13 #define FCN_XX_PWRDNB_EN_WIDTH 1 #define FCN_XX_PWRDNA_EN_LBN 12 #define FCN_XX_PWRDNA_EN_WIDTH 1 #define FCN_XX_RSTPLLCD_EN_LBN 9 #define FCN_XX_RSTPLLCD_EN_WIDTH 1 #define FCN_XX_RSTPLLAB_EN_LBN 8 #define FCN_XX_RSTPLLAB_EN_WIDTH 1 #define FCN_XX_RESETD_EN_LBN 7 #define FCN_XX_RESETD_EN_WIDTH 1 #define FCN_XX_RESETC_EN_LBN 6 #define FCN_XX_RESETC_EN_WIDTH 1 #define FCN_XX_RESETB_EN_LBN 5 #define FCN_XX_RESETB_EN_WIDTH 1 #define FCN_XX_RESETA_EN_LBN 4 #define FCN_XX_RESETA_EN_WIDTH 1 #define FCN_XX_RSTXGXSRX_EN_LBN 2 #define FCN_XX_RSTXGXSRX_EN_WIDTH 1 #define FCN_XX_RSTXGXSTX_EN_LBN 1 #define FCN_XX_RSTXGXSTX_EN_WIDTH 1 #define FCN_XX_RST_XX_EN_LBN 0 #define FCN_XX_RST_XX_EN_WIDTH 1 /* XGXS/XAUI powerdown/reset control register */ #define FCN_XX_SD_CTL_REG_MAC 0x11 #define FCN_XX_TERMADJ1_LBN 17 #define FCN_XX_TERMADJ1_WIDTH 1 #define FCN_XX_TERMADJ0_LBN 16 #define FCN_XX_TERMADJ0_WIDTH 1 #define FCN_XX_HIDRVD_LBN 15 #define FCN_XX_HIDRVD_WIDTH 1 #define FCN_XX_LODRVD_LBN 14 #define FCN_XX_LODRVD_WIDTH 1 #define FCN_XX_HIDRVC_LBN 13 #define FCN_XX_HIDRVC_WIDTH 1 #define FCN_XX_LODRVC_LBN 12 #define FCN_XX_LODRVC_WIDTH 1 #define FCN_XX_HIDRVB_LBN 11 #define FCN_XX_HIDRVB_WIDTH 1 #define FCN_XX_LODRVB_LBN 10 #define FCN_XX_LODRVB_WIDTH 1 #define FCN_XX_HIDRVA_LBN 9 #define FCN_XX_HIDRVA_WIDTH 1 #define FCN_XX_LODRVA_LBN 8 #define FCN_XX_LODRVA_WIDTH 1 #define FCN_XX_LPBKD_LBN 3 #define FCN_XX_LPBKD_WIDTH 1 #define FCN_XX_LPBKC_LBN 2 #define FCN_XX_LPBKC_WIDTH 1 #define FCN_XX_LPBKB_LBN 1 #define FCN_XX_LPBKB_WIDTH 1 #define FCN_XX_LPBKA_LBN 0 #define FCN_XX_LPBKA_WIDTH 1 #define FCN_XX_TXDRV_CTL_REG_MAC 0x12 #define FCN_XX_DEQD_LBN 28 #define FCN_XX_DEQD_WIDTH 4 #define FCN_XX_DEQC_LBN 24 #define FCN_XX_DEQC_WIDTH 4 #define FCN_XX_DEQB_LBN 20 #define FCN_XX_DEQB_WIDTH 4 #define FCN_XX_DEQA_LBN 16 #define FCN_XX_DEQA_WIDTH 4 #define FCN_XX_DTXD_LBN 12 #define FCN_XX_DTXD_WIDTH 4 #define FCN_XX_DTXC_LBN 8 #define FCN_XX_DTXC_WIDTH 4 #define FCN_XX_DTXB_LBN 4 #define FCN_XX_DTXB_WIDTH 4 #define FCN_XX_DTXA_LBN 0 #define FCN_XX_DTXA_WIDTH 4 /* Receive filter table */ #define FCN_RX_FILTER_TBL0 0xF00000 /* Receive descriptor pointer table */ #define FCN_RX_DESC_PTR_TBL_KER_A1 0x11800 #define FCN_RX_DESC_PTR_TBL_KER_B0 0xF40000 #define FCN_RX_ISCSI_DDIG_EN_LBN 88 #define FCN_RX_ISCSI_DDIG_EN_WIDTH 1 #define FCN_RX_ISCSI_HDIG_EN_LBN 87 #define FCN_RX_ISCSI_HDIG_EN_WIDTH 1 #define FCN_RX_DESCQ_BUF_BASE_ID_LBN 36 #define FCN_RX_DESCQ_BUF_BASE_ID_WIDTH 20 #define FCN_RX_DESCQ_EVQ_ID_LBN 24 #define FCN_RX_DESCQ_EVQ_ID_WIDTH 12 #define FCN_RX_DESCQ_OWNER_ID_LBN 10 #define FCN_RX_DESCQ_OWNER_ID_WIDTH 14 #define FCN_RX_DESCQ_SIZE_LBN 3 #define FCN_RX_DESCQ_SIZE_WIDTH 2 #define FCN_RX_DESCQ_SIZE_4K 3 #define FCN_RX_DESCQ_SIZE_2K 2 #define FCN_RX_DESCQ_SIZE_1K 1 #define FCN_RX_DESCQ_SIZE_512 0 #define FCN_RX_DESCQ_TYPE_LBN 2 #define FCN_RX_DESCQ_TYPE_WIDTH 1 #define FCN_RX_DESCQ_JUMBO_LBN 1 #define FCN_RX_DESCQ_JUMBO_WIDTH 1 #define FCN_RX_DESCQ_EN_LBN 0 #define FCN_RX_DESCQ_EN_WIDTH 1 /* Transmit descriptor pointer table */ #define FCN_TX_DESC_PTR_TBL_KER_A1 0x11900 #define FCN_TX_DESC_PTR_TBL_KER_B0 0xF50000 #define FCN_TX_NON_IP_DROP_DIS_B0_LBN 91 #define FCN_TX_NON_IP_DROP_DIS_B0_WIDTH 1 #define FCN_TX_DESCQ_EN_LBN 88 #define FCN_TX_DESCQ_EN_WIDTH 1 #define FCN_TX_ISCSI_DDIG_EN_LBN 87 #define FCN_TX_ISCSI_DDIG_EN_WIDTH 1 #define FCN_TX_ISCSI_HDIG_EN_LBN 86 #define FCN_TX_ISCSI_HDIG_EN_WIDTH 1 #define FCN_TX_DESCQ_BUF_BASE_ID_LBN 36 #define FCN_TX_DESCQ_BUF_BASE_ID_WIDTH 20 #define FCN_TX_DESCQ_EVQ_ID_LBN 24 #define FCN_TX_DESCQ_EVQ_ID_WIDTH 12 #define FCN_TX_DESCQ_OWNER_ID_LBN 10 #define FCN_TX_DESCQ_OWNER_ID_WIDTH 14 #define FCN_TX_DESCQ_SIZE_LBN 3 #define FCN_TX_DESCQ_SIZE_WIDTH 2 #define FCN_TX_DESCQ_SIZE_4K 3 #define FCN_TX_DESCQ_SIZE_2K 2 #define FCN_TX_DESCQ_SIZE_1K 1 #define FCN_TX_DESCQ_SIZE_512 0 #define FCN_TX_DESCQ_TYPE_LBN 1 #define FCN_TX_DESCQ_TYPE_WIDTH 2 #define FCN_TX_DESCQ_FLUSH_LBN 0 #define FCN_TX_DESCQ_FLUSH_WIDTH 1 /* Event queue pointer */ #define FCN_EVQ_PTR_TBL_KER_A1 0x11a00 #define FCN_EVQ_PTR_TBL_KER_B0 0xf60000 #define FCN_EVQ_EN_LBN 23 #define FCN_EVQ_EN_WIDTH 1 #define FCN_EVQ_SIZE_LBN 20 #define FCN_EVQ_SIZE_WIDTH 3 #define FCN_EVQ_SIZE_32K 6 #define FCN_EVQ_SIZE_16K 5 #define FCN_EVQ_SIZE_8K 4 #define FCN_EVQ_SIZE_4K 3 #define FCN_EVQ_SIZE_2K 2 #define FCN_EVQ_SIZE_1K 1 #define FCN_EVQ_SIZE_512 0 #define FCN_EVQ_BUF_BASE_ID_LBN 0 #define FCN_EVQ_BUF_BASE_ID_WIDTH 20 /* RSS indirection table */ #define FCN_RX_RSS_INDIR_TBL_B0 0xFB0000 /* Event queue read pointer */ #define FCN_EVQ_RPTR_REG_KER_A1 0x11b00 #define FCN_EVQ_RPTR_REG_KER_B0 0xfa0000 #define FCN_EVQ_RPTR_LBN 0 #define FCN_EVQ_RPTR_WIDTH 14 #define FCN_EVQ_RPTR_REG_KER_DWORD_A1 ( FCN_EVQ_RPTR_REG_KER_A1 + 0 ) #define FCN_EVQ_RPTR_REG_KER_DWORD_B0 ( FCN_EVQ_RPTR_REG_KER_B0 + 0 ) #define FCN_EVQ_RPTR_DWORD_LBN 0 #define FCN_EVQ_RPTR_DWORD_WIDTH 14 /* Special buffer descriptors */ #define FCN_BUF_FULL_TBL_KER_A1 0x18000 #define FCN_BUF_FULL_TBL_KER_B0 0x800000 #define FCN_IP_DAT_BUF_SIZE_LBN 50 #define FCN_IP_DAT_BUF_SIZE_WIDTH 1 #define FCN_IP_DAT_BUF_SIZE_8K 1 #define FCN_IP_DAT_BUF_SIZE_4K 0 #define FCN_BUF_ADR_FBUF_LBN 14 #define FCN_BUF_ADR_FBUF_WIDTH 34 #define FCN_BUF_OWNER_ID_FBUF_LBN 0 #define FCN_BUF_OWNER_ID_FBUF_WIDTH 14 /** Offset of a GMAC register within Falcon */ #define FALCON_GMAC_REG( efab, mac_reg ) \ ( FALCON_GMAC_REGBANK + \ ( (mac_reg) * FALCON_GMAC_REG_SIZE ) ) /** Offset of an XMAC register within Falcon */ #define FALCON_XMAC_REG( efab_port, mac_reg ) \ ( FALCON_XMAC_REGBANK + \ ( (mac_reg) * FALCON_XMAC_REG_SIZE ) ) #define FCN_MAC_DATA_LBN 0 #define FCN_MAC_DATA_WIDTH 32 /* Transmit descriptor */ #define FCN_TX_KER_PORT_LBN 63 #define FCN_TX_KER_PORT_WIDTH 1 #define FCN_TX_KER_BYTE_CNT_LBN 48 #define FCN_TX_KER_BYTE_CNT_WIDTH 14 #define FCN_TX_KER_BUF_ADR_LBN 0 #define FCN_TX_KER_BUF_ADR_WIDTH EFAB_DMA_TYPE_WIDTH ( 46 ) /* Receive descriptor */ #define FCN_RX_KER_BUF_SIZE_LBN 48 #define FCN_RX_KER_BUF_SIZE_WIDTH 14 #define FCN_RX_KER_BUF_ADR_LBN 0 #define FCN_RX_KER_BUF_ADR_WIDTH EFAB_DMA_TYPE_WIDTH ( 46 ) /* Event queue entries */ #define FCN_EV_CODE_LBN 60 #define FCN_EV_CODE_WIDTH 4 #define FCN_RX_IP_EV_DECODE 0 #define FCN_TX_IP_EV_DECODE 2 #define FCN_DRIVER_EV_DECODE 5 /* Receive events */ #define FCN_RX_EV_PKT_OK_LBN 56 #define FCN_RX_EV_PKT_OK_WIDTH 1 #define FCN_RX_PORT_LBN 30 #define FCN_RX_PORT_WIDTH 1 #define FCN_RX_EV_BYTE_CNT_LBN 16 #define FCN_RX_EV_BYTE_CNT_WIDTH 14 #define FCN_RX_EV_DESC_PTR_LBN 0 #define FCN_RX_EV_DESC_PTR_WIDTH 12 /* Transmit events */ #define FCN_TX_EV_DESC_PTR_LBN 0 #define FCN_TX_EV_DESC_PTR_WIDTH 12 /******************************************************************************* * * * Low-level hardware access * * *******************************************************************************/ #define FCN_REVISION_REG(efab, reg) \ ( ( efab->pci_revision == FALCON_REV_B0 ) ? reg ## _B0 : reg ## _A1 ) #define EFAB_SET_OWORD_FIELD_VER(efab, reg, field, val) \ if ( efab->pci_revision == FALCON_REV_B0 ) \ EFAB_SET_OWORD_FIELD ( reg, field ## _B0, val ); \ else \ EFAB_SET_OWORD_FIELD ( reg, field ## _A1, val ); #if FALCON_USE_IO_BAR /* Write dword via the I/O BAR */ static inline void _falcon_writel ( struct efab_nic *efab, uint32_t value, unsigned int reg ) { outl ( reg, efab->iobase + FCN_IOM_IND_ADR_REG ); outl ( value, efab->iobase + FCN_IOM_IND_DAT_REG ); } /* Read dword via the I/O BAR */ static inline uint32_t _falcon_readl ( struct efab_nic *efab, unsigned int reg ) { outl ( reg, efab->iobase + FCN_IOM_IND_ADR_REG ); return inl ( efab->iobase + FCN_IOM_IND_DAT_REG ); } #else /* FALCON_USE_IO_BAR */ #define _falcon_writel( efab, value, reg ) \ writel ( (value), (efab)->membase + (reg) ) #define _falcon_readl( efab, reg ) readl ( (efab)->membase + (reg) ) #endif /* FALCON_USE_IO_BAR */ /** * Write to a Falcon register * */ static inline void falcon_write ( struct efab_nic *efab, efab_oword_t *value, unsigned int reg ) { EFAB_REGDUMP ( "Writing register %x with " EFAB_OWORD_FMT "\n", reg, EFAB_OWORD_VAL ( *value ) ); _falcon_writel ( efab, value->u32[0], reg + 0 ); _falcon_writel ( efab, value->u32[1], reg + 4 ); _falcon_writel ( efab, value->u32[2], reg + 8 ); wmb(); _falcon_writel ( efab, value->u32[3], reg + 12 ); wmb(); } /** * Write to Falcon SRAM * */ static inline void falcon_write_sram ( struct efab_nic *efab, efab_qword_t *value, unsigned int index ) { unsigned int reg = ( FCN_REVISION_REG ( efab, FCN_BUF_FULL_TBL_KER ) + ( index * sizeof ( *value ) ) ); EFAB_REGDUMP ( "Writing SRAM register %x with " EFAB_QWORD_FMT "\n", reg, EFAB_QWORD_VAL ( *value ) ); _falcon_writel ( efab, value->u32[0], reg + 0 ); _falcon_writel ( efab, value->u32[1], reg + 4 ); wmb(); } /** * Write dword to Falcon register that allows partial writes * */ static inline void falcon_writel ( struct efab_nic *efab, efab_dword_t *value, unsigned int reg ) { EFAB_REGDUMP ( "Writing partial register %x with " EFAB_DWORD_FMT "\n", reg, EFAB_DWORD_VAL ( *value ) ); _falcon_writel ( efab, value->u32[0], reg ); } /** * Read from a Falcon register * */ static inline void falcon_read ( struct efab_nic *efab, efab_oword_t *value, unsigned int reg ) { value->u32[0] = _falcon_readl ( efab, reg + 0 ); wmb(); value->u32[1] = _falcon_readl ( efab, reg + 4 ); value->u32[2] = _falcon_readl ( efab, reg + 8 ); value->u32[3] = _falcon_readl ( efab, reg + 12 ); EFAB_REGDUMP ( "Read from register %x, got " EFAB_OWORD_FMT "\n", reg, EFAB_OWORD_VAL ( *value ) ); } /** * Read from Falcon SRAM * */ static inline void falcon_read_sram ( struct efab_nic *efab, efab_qword_t *value, unsigned int index ) { unsigned int reg = ( FCN_REVISION_REG ( efab, FCN_BUF_FULL_TBL_KER ) + ( index * sizeof ( *value ) ) ); value->u32[0] = _falcon_readl ( efab, reg + 0 ); value->u32[1] = _falcon_readl ( efab, reg + 4 ); EFAB_REGDUMP ( "Read from SRAM register %x, got " EFAB_QWORD_FMT "\n", reg, EFAB_QWORD_VAL ( *value ) ); } /** * Read dword from a portion of a Falcon register * */ static inline void falcon_readl ( struct efab_nic *efab, efab_dword_t *value, unsigned int reg ) { value->u32[0] = _falcon_readl ( efab, reg ); EFAB_REGDUMP ( "Read from register %x, got " EFAB_DWORD_FMT "\n", reg, EFAB_DWORD_VAL ( *value ) ); } #define FCN_DUMP_REG( efab, _reg ) do { \ efab_oword_t reg; \ falcon_read ( efab, ®, _reg ); \ EFAB_LOG ( #_reg " = " EFAB_OWORD_FMT "\n", \ EFAB_OWORD_VAL ( reg ) ); \ } while ( 0 ); #define FCN_DUMP_MAC_REG( efab, _mac_reg ) do { \ efab_dword_t reg; \ efab->mac_op->mac_readl ( efab, ®, _mac_reg ); \ EFAB_LOG ( #_mac_reg " = " EFAB_DWORD_FMT "\n", \ EFAB_DWORD_VAL ( reg ) ); \ } while ( 0 ); /** * See if an event is present * * @v event Falcon event structure * @ret True An event is pending * @ret False No event is pending * * We check both the high and low dword of the event for all ones. We * wrote all ones when we cleared the event, and no valid event can * have all ones in either its high or low dwords. This approach is * robust against reordering. * * Note that using a single 64-bit comparison is incorrect; even * though the CPU read will be atomic, the DMA write may not be. */ static inline int falcon_event_present ( falcon_event_t* event ) { return ( ! ( EFAB_DWORD_IS_ALL_ONES ( event->dword[0] ) | EFAB_DWORD_IS_ALL_ONES ( event->dword[1] ) ) ); } static void falcon_eventq_read_ack ( struct efab_nic *efab, struct efab_ev_queue *ev_queue ) { efab_dword_t reg; EFAB_POPULATE_DWORD_1 ( reg, FCN_EVQ_RPTR_DWORD, ev_queue->read_ptr ); falcon_writel ( efab, ®, FCN_REVISION_REG ( efab, FCN_EVQ_RPTR_REG_KER_DWORD ) ); } #if 0 /** * Dump register contents (for debugging) * * Marked as static inline so that it will not be compiled in if not * used. */ static inline void falcon_dump_regs ( struct efab_nic *efab ) { FCN_DUMP_REG ( efab, FCN_INT_EN_REG_KER ); FCN_DUMP_REG ( efab, FCN_INT_ADR_REG_KER ); FCN_DUMP_REG ( efab, FCN_GLB_CTL_REG_KER ); FCN_DUMP_REG ( efab, FCN_TIMER_CMD_REG_KER ); FCN_DUMP_REG ( efab, FCN_SRM_RX_DC_CFG_REG_KER ); FCN_DUMP_REG ( efab, FCN_SRM_TX_DC_CFG_REG_KER ); FCN_DUMP_REG ( efab, FCN_RX_FILTER_CTL_REG_KER ); FCN_DUMP_REG ( efab, FCN_RX_DC_CFG_REG_KER ); FCN_DUMP_REG ( efab, FCN_TX_DC_CFG_REG_KER ); FCN_DUMP_REG ( efab, FCN_MAC0_CTRL_REG_KER ); FCN_DUMP_REG ( efab, FCN_MAC1_CTRL_REG_KER ); FCN_DUMP_REG ( efab, FCN_REVISION_REG ( efab, FCN_RX_DESC_PTR_TBL_KER ) ); FCN_DUMP_REG ( efab, FCN_REVISION_REG ( efab, FCN_TX_DESC_PTR_TBL_KER ) ); FCN_DUMP_REG ( efab, FCN_REVISION_REG ( efab, FCN_EVQ_PTR_TBL_KER ) ); FCN_DUMP_MAC_REG ( efab, GM_CFG1_REG_MAC ); FCN_DUMP_MAC_REG ( efab, GM_CFG2_REG_MAC ); FCN_DUMP_MAC_REG ( efab, GM_MAX_FLEN_REG_MAC ); FCN_DUMP_MAC_REG ( efab, GM_MII_MGMT_CFG_REG_MAC ); FCN_DUMP_MAC_REG ( efab, GM_ADR1_REG_MAC ); FCN_DUMP_MAC_REG ( efab, GM_ADR2_REG_MAC ); FCN_DUMP_MAC_REG ( efab, GMF_CFG0_REG_MAC ); FCN_DUMP_MAC_REG ( efab, GMF_CFG1_REG_MAC ); FCN_DUMP_MAC_REG ( efab, GMF_CFG2_REG_MAC ); FCN_DUMP_MAC_REG ( efab, GMF_CFG3_REG_MAC ); FCN_DUMP_MAC_REG ( efab, GMF_CFG4_REG_MAC ); FCN_DUMP_MAC_REG ( efab, GMF_CFG5_REG_MAC ); } #endif static void falcon_interrupts ( struct efab_nic *efab, int enabled, int force ) { efab_oword_t int_en_reg_ker; EFAB_POPULATE_OWORD_2 ( int_en_reg_ker, FCN_KER_INT_KER, force, FCN_DRV_INT_EN_KER, enabled ); falcon_write ( efab, &int_en_reg_ker, FCN_INT_EN_REG_KER ); } /******************************************************************************* * * * SPI access * * *******************************************************************************/ /** Maximum length for a single SPI transaction */ #define FALCON_SPI_MAX_LEN 16 static int falcon_spi_wait ( struct efab_nic *efab ) { efab_oword_t reg; int count; count = 0; do { udelay ( 100 ); falcon_read ( efab, ®, FCN_EE_SPI_HCMD_REG ); if ( EFAB_OWORD_FIELD ( reg, FCN_EE_SPI_HCMD_CMD_EN ) == 0 ) return 0; } while ( ++count < 1000 ); EFAB_ERR ( "Timed out waiting for SPI\n" ); return -ETIMEDOUT; } static int falcon_spi_rw ( struct spi_bus* bus, struct spi_device *device, unsigned int command, int address, const void* data_out, void *data_in, size_t len ) { struct efab_nic *efab = container_of ( bus, struct efab_nic, spi_bus ); int address_len, rc, device_id, read_cmd; efab_oword_t reg; /* falcon_init_spi_device() should have reduced the block size * down so this constraint holds */ assert ( len <= FALCON_SPI_MAX_LEN ); /* Is this the FLASH or EEPROM device? */ if ( device == &efab->spi_flash ) device_id = FCN_EE_SPI_FLASH; else if ( device == &efab->spi_eeprom ) device_id = FCN_EE_SPI_EEPROM; else { EFAB_ERR ( "Unknown device %p\n", device ); return -EINVAL; } EFAB_TRACE ( "Executing spi command %d on device %d at %d for %zd bytes\n", command, device_id, address, len ); /* The bus must be idle */ rc = falcon_spi_wait ( efab ); if ( rc ) goto fail1; /* Copy data out */ if ( data_out ) { memcpy ( ®, data_out, len ); falcon_write ( efab, ®, FCN_EE_SPI_HDATA_REG ); } /* Program address register */ if ( address >= 0 ) { EFAB_POPULATE_OWORD_1 ( reg, FCN_EE_SPI_HADR_ADR, address ); falcon_write ( efab, ®, FCN_EE_SPI_HADR_REG ); } /* Issue command */ address_len = ( address >= 0 ) ? device->address_len / 8 : 0; read_cmd = ( data_in ? FCN_EE_SPI_READ : FCN_EE_SPI_WRITE ); EFAB_POPULATE_OWORD_7 ( reg, FCN_EE_SPI_HCMD_CMD_EN, 1, FCN_EE_SPI_HCMD_SF_SEL, device_id, FCN_EE_SPI_HCMD_DABCNT, len, FCN_EE_SPI_HCMD_READ, read_cmd, FCN_EE_SPI_HCMD_DUBCNT, 0, FCN_EE_SPI_HCMD_ADBCNT, address_len, FCN_EE_SPI_HCMD_ENC, command ); falcon_write ( efab, ®, FCN_EE_SPI_HCMD_REG ); /* Wait for the command to complete */ rc = falcon_spi_wait ( efab ); if ( rc ) goto fail2; /* Copy data in */ if ( data_in ) { falcon_read ( efab, ®, FCN_EE_SPI_HDATA_REG ); memcpy ( data_in, ®, len ); } return 0; fail2: fail1: EFAB_ERR ( "Failed SPI command %d to device %d address 0x%x len 0x%zx\n", command, device_id, address, len ); return rc; } /** Portion of EEPROM available for non-volatile options */ static struct nvo_fragment falcon_nvo_fragments[] = { { 0x100, 0xf0 }, { 0, 0 } }; /******************************************************************************* * * * Falcon bit-bashed I2C interface * * *******************************************************************************/ static void falcon_i2c_bit_write ( struct bit_basher *basher, unsigned int bit_id, unsigned long data ) { struct efab_nic *efab = container_of ( basher, struct efab_nic, i2c_bb.basher ); efab_oword_t reg; falcon_read ( efab, ®, FCN_GPIO_CTL_REG_KER ); switch ( bit_id ) { case I2C_BIT_SCL: EFAB_SET_OWORD_FIELD ( reg, FCN_GPIO0_OEN, ( data ? 0 : 1 ) ); break; case I2C_BIT_SDA: EFAB_SET_OWORD_FIELD ( reg, FCN_GPIO3_OEN, ( data ? 0 : 1 ) ); break; default: EFAB_ERR ( "%s bit=%d\n", __func__, bit_id ); break; } falcon_write ( efab, ®, FCN_GPIO_CTL_REG_KER ); } static int falcon_i2c_bit_read ( struct bit_basher *basher, unsigned int bit_id ) { struct efab_nic *efab = container_of ( basher, struct efab_nic, i2c_bb.basher ); efab_oword_t reg; falcon_read ( efab, ®, FCN_GPIO_CTL_REG_KER ); switch ( bit_id ) { case I2C_BIT_SCL: return EFAB_OWORD_FIELD ( reg, FCN_GPIO0_IN ); break; case I2C_BIT_SDA: return EFAB_OWORD_FIELD ( reg, FCN_GPIO3_IN ); break; default: EFAB_ERR ( "%s bit=%d\n", __func__, bit_id ); break; } return -1; } static struct bit_basher_operations falcon_i2c_bit_ops = { .read = falcon_i2c_bit_read, .write = falcon_i2c_bit_write, }; /******************************************************************************* * * * MDIO access * * *******************************************************************************/ static int falcon_gmii_wait ( struct efab_nic *efab ) { efab_dword_t md_stat; int count; /* wait upto 10ms */ for (count = 0; count < 1000; count++) { falcon_readl ( efab, &md_stat, FCN_MD_STAT_REG_KER ); if ( EFAB_DWORD_FIELD ( md_stat, FCN_MD_BSY ) == 0 ) { if ( EFAB_DWORD_FIELD ( md_stat, FCN_MD_LNFL ) != 0 || EFAB_DWORD_FIELD ( md_stat, FCN_MD_BSERR ) != 0 ) { EFAB_ERR ( "Error from GMII access " EFAB_DWORD_FMT"\n", EFAB_DWORD_VAL ( md_stat )); return -EIO; } return 0; } udelay(10); } EFAB_ERR ( "Timed out waiting for GMII\n" ); return -ETIMEDOUT; } static void falcon_mdio_write ( struct efab_nic *efab, int device, int location, int value ) { efab_oword_t reg; EFAB_TRACE ( "Writing GMII %d register %02x with %04x\n", device, location, value ); /* Check MII not currently being accessed */ if ( falcon_gmii_wait ( efab ) ) return; /* Write the address/ID register */ EFAB_POPULATE_OWORD_1 ( reg, FCN_MD_PHY_ADR, location ); falcon_write ( efab, ®, FCN_MD_PHY_ADR_REG_KER ); if ( efab->phy_10g ) { /* clause45 */ EFAB_POPULATE_OWORD_2 ( reg, FCN_MD_PRT_ADR, efab->phy_addr, FCN_MD_DEV_ADR, device ); } else { /* clause22 */ assert ( device == 0 ); EFAB_POPULATE_OWORD_2 ( reg, FCN_MD_PRT_ADR, efab->phy_addr, FCN_MD_DEV_ADR, location ); } falcon_write ( efab, ®, FCN_MD_ID_REG_KER ); /* Write data */ EFAB_POPULATE_OWORD_1 ( reg, FCN_MD_TXD, value ); falcon_write ( efab, ®, FCN_MD_TXD_REG_KER ); EFAB_POPULATE_OWORD_2 ( reg, FCN_MD_WRC, 1, FCN_MD_GC, ( efab->phy_10g ? 0 : 1 ) ); falcon_write ( efab, ®, FCN_MD_CS_REG_KER ); /* Wait for data to be written */ if ( falcon_gmii_wait ( efab ) ) { /* Abort the write operation */ EFAB_POPULATE_OWORD_2 ( reg, FCN_MD_WRC, 0, FCN_MD_GC, 1); falcon_write ( efab, ®, FCN_MD_CS_REG_KER ); udelay(10); } } static int falcon_mdio_read ( struct efab_nic *efab, int device, int location ) { efab_oword_t reg; int value; /* Check MII not currently being accessed */ if ( falcon_gmii_wait ( efab ) ) return -1; if ( efab->phy_10g ) { /* clause45 */ EFAB_POPULATE_OWORD_1 ( reg, FCN_MD_PHY_ADR, location ); falcon_write ( efab, ®, FCN_MD_PHY_ADR_REG_KER ); EFAB_POPULATE_OWORD_2 ( reg, FCN_MD_PRT_ADR, efab->phy_addr, FCN_MD_DEV_ADR, device ); falcon_write ( efab, ®, FCN_MD_ID_REG_KER); /* request data to be read */ EFAB_POPULATE_OWORD_2 ( reg, FCN_MD_RDC, 1, FCN_MD_GC, 0 ); } else { /* clause22 */ assert ( device == 0 ); EFAB_POPULATE_OWORD_2 ( reg, FCN_MD_PRT_ADR, efab->phy_addr, FCN_MD_DEV_ADR, location ); falcon_write ( efab, ®, FCN_MD_ID_REG_KER ); /* Request data to be read */ EFAB_POPULATE_OWORD_2 ( reg, FCN_MD_RIC, 1, FCN_MD_GC, 1 ); } falcon_write ( efab, ®, FCN_MD_CS_REG_KER ); /* Wait for data to become available */ if ( falcon_gmii_wait ( efab ) ) { /* Abort the read operation */ EFAB_POPULATE_OWORD_2 ( reg, FCN_MD_RIC, 0, FCN_MD_GC, 1 ); falcon_write ( efab, ®, FCN_MD_CS_REG_KER ); udelay ( 10 ); value = -1; } else { /* Read the data */ falcon_read ( efab, ®, FCN_MD_RXD_REG_KER ); value = EFAB_OWORD_FIELD ( reg, FCN_MD_RXD ); } EFAB_TRACE ( "Read from GMII %d register %02x, got %04x\n", device, location, value ); return value; } /******************************************************************************* * * * MAC wrapper * * *******************************************************************************/ static void falcon_reconfigure_mac_wrapper ( struct efab_nic *efab ) { efab_oword_t reg; int link_speed; if ( efab->link_options & LPA_EF_10000 ) { link_speed = 0x3; } else if ( efab->link_options & LPA_EF_1000 ) { link_speed = 0x2; } else if ( efab->link_options & LPA_100 ) { link_speed = 0x1; } else { link_speed = 0x0; } EFAB_POPULATE_OWORD_5 ( reg, FCN_MAC_XOFF_VAL, 0xffff /* datasheet */, FCN_MAC_BCAD_ACPT, 1, FCN_MAC_UC_PROM, 0, FCN_MAC_LINK_STATUS, 1, FCN_MAC_SPEED, link_speed ); falcon_write ( efab, ®, FCN_MAC0_CTRL_REG_KER ); } /******************************************************************************* * * * GMAC handling * * *******************************************************************************/ /* GMAC configuration register 1 */ #define GM_CFG1_REG_MAC 0x00 #define GM_SW_RST_LBN 31 #define GM_SW_RST_WIDTH 1 #define GM_RX_FC_EN_LBN 5 #define GM_RX_FC_EN_WIDTH 1 #define GM_TX_FC_EN_LBN 4 #define GM_TX_FC_EN_WIDTH 1 #define GM_RX_EN_LBN 2 #define GM_RX_EN_WIDTH 1 #define GM_TX_EN_LBN 0 #define GM_TX_EN_WIDTH 1 /* GMAC configuration register 2 */ #define GM_CFG2_REG_MAC 0x01 #define GM_PAMBL_LEN_LBN 12 #define GM_PAMBL_LEN_WIDTH 4 #define GM_IF_MODE_LBN 8 #define GM_IF_MODE_WIDTH 2 #define GM_PAD_CRC_EN_LBN 2 #define GM_PAD_CRC_EN_WIDTH 1 #define GM_FD_LBN 0 #define GM_FD_WIDTH 1 /* GMAC maximum frame length register */ #define GM_MAX_FLEN_REG_MAC 0x04 #define GM_MAX_FLEN_LBN 0 #define GM_MAX_FLEN_WIDTH 16 /* GMAC MII management configuration register */ #define GM_MII_MGMT_CFG_REG_MAC 0x08 #define GM_MGMT_CLK_SEL_LBN 0 #define GM_MGMT_CLK_SEL_WIDTH 3 /* GMAC MII management command register */ #define GM_MII_MGMT_CMD_REG_MAC 0x09 #define GM_MGMT_SCAN_CYC_LBN 1 #define GM_MGMT_SCAN_CYC_WIDTH 1 #define GM_MGMT_RD_CYC_LBN 0 #define GM_MGMT_RD_CYC_WIDTH 1 /* GMAC MII management address register */ #define GM_MII_MGMT_ADR_REG_MAC 0x0a #define GM_MGMT_PHY_ADDR_LBN 8 #define GM_MGMT_PHY_ADDR_WIDTH 5 #define GM_MGMT_REG_ADDR_LBN 0 #define GM_MGMT_REG_ADDR_WIDTH 5 /* GMAC MII management control register */ #define GM_MII_MGMT_CTL_REG_MAC 0x0b #define GM_MGMT_CTL_LBN 0 #define GM_MGMT_CTL_WIDTH 16 /* GMAC MII management status register */ #define GM_MII_MGMT_STAT_REG_MAC 0x0c #define GM_MGMT_STAT_LBN 0 #define GM_MGMT_STAT_WIDTH 16 /* GMAC MII management indicators register */ #define GM_MII_MGMT_IND_REG_MAC 0x0d #define GM_MGMT_BUSY_LBN 0 #define GM_MGMT_BUSY_WIDTH 1 /* GMAC station address register 1 */ #define GM_ADR1_REG_MAC 0x10 #define GM_HWADDR_5_LBN 24 #define GM_HWADDR_5_WIDTH 8 #define GM_HWADDR_4_LBN 16 #define GM_HWADDR_4_WIDTH 8 #define GM_HWADDR_3_LBN 8 #define GM_HWADDR_3_WIDTH 8 #define GM_HWADDR_2_LBN 0 #define GM_HWADDR_2_WIDTH 8 /* GMAC station address register 2 */ #define GM_ADR2_REG_MAC 0x11 #define GM_HWADDR_1_LBN 24 #define GM_HWADDR_1_WIDTH 8 #define GM_HWADDR_0_LBN 16 #define GM_HWADDR_0_WIDTH 8 /* GMAC FIFO configuration register 0 */ #define GMF_CFG0_REG_MAC 0x12 #define GMF_FTFENREQ_LBN 12 #define GMF_FTFENREQ_WIDTH 1 #define GMF_STFENREQ_LBN 11 #define GMF_STFENREQ_WIDTH 1 #define GMF_FRFENREQ_LBN 10 #define GMF_FRFENREQ_WIDTH 1 #define GMF_SRFENREQ_LBN 9 #define GMF_SRFENREQ_WIDTH 1 #define GMF_WTMENREQ_LBN 8 #define GMF_WTMENREQ_WIDTH 1 /* GMAC FIFO configuration register 1 */ #define GMF_CFG1_REG_MAC 0x13 #define GMF_CFGFRTH_LBN 16 #define GMF_CFGFRTH_WIDTH 5 #define GMF_CFGXOFFRTX_LBN 0 #define GMF_CFGXOFFRTX_WIDTH 16 /* GMAC FIFO configuration register 2 */ #define GMF_CFG2_REG_MAC 0x14 #define GMF_CFGHWM_LBN 16 #define GMF_CFGHWM_WIDTH 6 #define GMF_CFGLWM_LBN 0 #define GMF_CFGLWM_WIDTH 6 /* GMAC FIFO configuration register 3 */ #define GMF_CFG3_REG_MAC 0x15 #define GMF_CFGHWMFT_LBN 16 #define GMF_CFGHWMFT_WIDTH 6 #define GMF_CFGFTTH_LBN 0 #define GMF_CFGFTTH_WIDTH 6 /* GMAC FIFO configuration register 4 */ #define GMF_CFG4_REG_MAC 0x16 #define GMF_HSTFLTRFRM_PAUSE_LBN 12 #define GMF_HSTFLTRFRM_PAUSE_WIDTH 12 /* GMAC FIFO configuration register 5 */ #define GMF_CFG5_REG_MAC 0x17 #define GMF_CFGHDPLX_LBN 22 #define GMF_CFGHDPLX_WIDTH 1 #define GMF_CFGBYTMODE_LBN 19 #define GMF_CFGBYTMODE_WIDTH 1 #define GMF_HSTDRPLT64_LBN 18 #define GMF_HSTDRPLT64_WIDTH 1 #define GMF_HSTFLTRFRMDC_PAUSE_LBN 12 #define GMF_HSTFLTRFRMDC_PAUSE_WIDTH 1 static void falcon_gmac_writel ( struct efab_nic *efab, efab_dword_t *value, unsigned int mac_reg ) { efab_oword_t temp; EFAB_POPULATE_OWORD_1 ( temp, FCN_MAC_DATA, EFAB_DWORD_FIELD ( *value, FCN_MAC_DATA ) ); falcon_write ( efab, &temp, FALCON_GMAC_REG ( efab, mac_reg ) ); } static void falcon_gmac_readl ( struct efab_nic *efab, efab_dword_t *value, unsigned int mac_reg ) { efab_oword_t temp; falcon_read ( efab, &temp, FALCON_GMAC_REG ( efab, mac_reg ) ); EFAB_POPULATE_DWORD_1 ( *value, FCN_MAC_DATA, EFAB_OWORD_FIELD ( temp, FCN_MAC_DATA ) ); } static void mentormac_reset ( struct efab_nic *efab ) { efab_dword_t reg; /* Take into reset */ EFAB_POPULATE_DWORD_1 ( reg, GM_SW_RST, 1 ); falcon_gmac_writel ( efab, ®, GM_CFG1_REG_MAC ); udelay ( 1000 ); /* Take out of reset */ EFAB_POPULATE_DWORD_1 ( reg, GM_SW_RST, 0 ); falcon_gmac_writel ( efab, ®, GM_CFG1_REG_MAC ); udelay ( 1000 ); /* Configure GMII interface so PHY is accessible. Note that * GMII interface is connected only to port 0, and that on * Falcon this is a no-op. */ EFAB_POPULATE_DWORD_1 ( reg, GM_MGMT_CLK_SEL, 0x4 ); falcon_gmac_writel ( efab, ®, GM_MII_MGMT_CFG_REG_MAC ); udelay ( 10 ); } static void mentormac_init ( struct efab_nic *efab ) { int pause, if_mode, full_duplex, bytemode, half_duplex; efab_dword_t reg; /* Configuration register 1 */ pause = ( efab->link_options & LPA_PAUSE_CAP ) ? 1 : 0; if ( ! ( efab->link_options & LPA_EF_DUPLEX ) ) { /* Half-duplex operation requires TX flow control */ pause = 1; } EFAB_POPULATE_DWORD_4 ( reg, GM_TX_EN, 1, GM_TX_FC_EN, pause, GM_RX_EN, 1, GM_RX_FC_EN, 1 ); falcon_gmac_writel ( efab, ®, GM_CFG1_REG_MAC ); udelay ( 10 ); /* Configuration register 2 */ if_mode = ( efab->link_options & LPA_EF_1000 ) ? 2 : 1; full_duplex = ( efab->link_options & LPA_EF_DUPLEX ) ? 1 : 0; EFAB_POPULATE_DWORD_4 ( reg, GM_IF_MODE, if_mode, GM_PAD_CRC_EN, 1, GM_FD, full_duplex, GM_PAMBL_LEN, 0x7 /* ? */ ); falcon_gmac_writel ( efab, ®, GM_CFG2_REG_MAC ); udelay ( 10 ); /* Max frame len register */ EFAB_POPULATE_DWORD_1 ( reg, GM_MAX_FLEN, EFAB_MAX_FRAME_LEN ( ETH_FRAME_LEN ) ); falcon_gmac_writel ( efab, ®, GM_MAX_FLEN_REG_MAC ); udelay ( 10 ); /* FIFO configuration register 0 */ EFAB_POPULATE_DWORD_5 ( reg, GMF_FTFENREQ, 1, GMF_STFENREQ, 1, GMF_FRFENREQ, 1, GMF_SRFENREQ, 1, GMF_WTMENREQ, 1 ); falcon_gmac_writel ( efab, ®, GMF_CFG0_REG_MAC ); udelay ( 10 ); /* FIFO configuration register 1 */ EFAB_POPULATE_DWORD_2 ( reg, GMF_CFGFRTH, 0x12, GMF_CFGXOFFRTX, 0xffff ); falcon_gmac_writel ( efab, ®, GMF_CFG1_REG_MAC ); udelay ( 10 ); /* FIFO configuration register 2 */ EFAB_POPULATE_DWORD_2 ( reg, GMF_CFGHWM, 0x3f, GMF_CFGLWM, 0xa ); falcon_gmac_writel ( efab, ®, GMF_CFG2_REG_MAC ); udelay ( 10 ); /* FIFO configuration register 3 */ EFAB_POPULATE_DWORD_2 ( reg, GMF_CFGHWMFT, 0x1c, GMF_CFGFTTH, 0x08 ); falcon_gmac_writel ( efab, ®, GMF_CFG3_REG_MAC ); udelay ( 10 ); /* FIFO configuration register 4 */ EFAB_POPULATE_DWORD_1 ( reg, GMF_HSTFLTRFRM_PAUSE, 1 ); falcon_gmac_writel ( efab, ®, GMF_CFG4_REG_MAC ); udelay ( 10 ); /* FIFO configuration register 5 */ bytemode = ( efab->link_options & LPA_EF_1000 ) ? 1 : 0; half_duplex = ( efab->link_options & LPA_EF_DUPLEX ) ? 0 : 1; falcon_gmac_readl ( efab, ®, GMF_CFG5_REG_MAC ); EFAB_SET_DWORD_FIELD ( reg, GMF_CFGBYTMODE, bytemode ); EFAB_SET_DWORD_FIELD ( reg, GMF_CFGHDPLX, half_duplex ); EFAB_SET_DWORD_FIELD ( reg, GMF_HSTDRPLT64, half_duplex ); EFAB_SET_DWORD_FIELD ( reg, GMF_HSTFLTRFRMDC_PAUSE, 0 ); falcon_gmac_writel ( efab, ®, GMF_CFG5_REG_MAC ); udelay ( 10 ); /* MAC address */ EFAB_POPULATE_DWORD_4 ( reg, GM_HWADDR_5, efab->mac_addr[5], GM_HWADDR_4, efab->mac_addr[4], GM_HWADDR_3, efab->mac_addr[3], GM_HWADDR_2, efab->mac_addr[2] ); falcon_gmac_writel ( efab, ®, GM_ADR1_REG_MAC ); udelay ( 10 ); EFAB_POPULATE_DWORD_2 ( reg, GM_HWADDR_1, efab->mac_addr[1], GM_HWADDR_0, efab->mac_addr[0] ); falcon_gmac_writel ( efab, ®, GM_ADR2_REG_MAC ); udelay ( 10 ); } static int falcon_init_gmac ( struct efab_nic *efab ) { /* Reset the MAC */ mentormac_reset ( efab ); /* Initialise PHY */ efab->phy_op->init ( efab ); /* check the link is up */ if ( !efab->link_up ) return -EAGAIN; /* Initialise MAC */ mentormac_init ( efab ); /* reconfigure the MAC wrapper */ falcon_reconfigure_mac_wrapper ( efab ); return 0; } static struct efab_mac_operations falcon_gmac_operations = { .init = falcon_init_gmac, }; /******************************************************************************* * * * XMAC handling * * *******************************************************************************/ /** * Write dword to a Falcon XMAC register * */ static void falcon_xmac_writel ( struct efab_nic *efab, efab_dword_t *value, unsigned int mac_reg ) { efab_oword_t temp; EFAB_POPULATE_OWORD_1 ( temp, FCN_MAC_DATA, EFAB_DWORD_FIELD ( *value, FCN_MAC_DATA ) ); falcon_write ( efab, &temp, FALCON_XMAC_REG ( efab, mac_reg ) ); } /** * Read dword from a Falcon XMAC register * */ static void falcon_xmac_readl ( struct efab_nic *efab, efab_dword_t *value, unsigned int mac_reg ) { efab_oword_t temp; falcon_read ( efab, &temp, FALCON_XMAC_REG ( efab, mac_reg ) ); EFAB_POPULATE_DWORD_1 ( *value, FCN_MAC_DATA, EFAB_OWORD_FIELD ( temp, FCN_MAC_DATA ) ); } /** * Configure Falcon XAUI output */ static void falcon_setup_xaui ( struct efab_nic *efab ) { efab_dword_t sdctl, txdrv; falcon_xmac_readl ( efab, &sdctl, FCN_XX_SD_CTL_REG_MAC ); EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_HIDRVD, XX_SD_CTL_DRV_DEFAULT ); EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_LODRVD, XX_SD_CTL_DRV_DEFAULT ); EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_HIDRVC, XX_SD_CTL_DRV_DEFAULT ); EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_LODRVC, XX_SD_CTL_DRV_DEFAULT ); EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_HIDRVB, XX_SD_CTL_DRV_DEFAULT ); EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_LODRVB, XX_SD_CTL_DRV_DEFAULT ); EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_HIDRVA, XX_SD_CTL_DRV_DEFAULT ); EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_LODRVA, XX_SD_CTL_DRV_DEFAULT ); falcon_xmac_writel ( efab, &sdctl, FCN_XX_SD_CTL_REG_MAC ); EFAB_POPULATE_DWORD_8 ( txdrv, FCN_XX_DEQD, XX_TXDRV_DEQ_DEFAULT, FCN_XX_DEQC, XX_TXDRV_DEQ_DEFAULT, FCN_XX_DEQB, XX_TXDRV_DEQ_DEFAULT, FCN_XX_DEQA, XX_TXDRV_DEQ_DEFAULT, FCN_XX_DTXD, XX_TXDRV_DTX_DEFAULT, FCN_XX_DTXC, XX_TXDRV_DTX_DEFAULT, FCN_XX_DTXB, XX_TXDRV_DTX_DEFAULT, FCN_XX_DTXA, XX_TXDRV_DTX_DEFAULT); falcon_xmac_writel ( efab, &txdrv, FCN_XX_TXDRV_CTL_REG_MAC); } static int falcon_xgmii_status ( struct efab_nic *efab ) { efab_dword_t reg; if ( efab->pci_revision < FALCON_REV_B0 ) return 1; /* The ISR latches, so clear it and re-read */ falcon_xmac_readl ( efab, ®, FCN_XM_MGT_INT_REG_MAC_B0 ); falcon_xmac_readl ( efab, ®, FCN_XM_MGT_INT_REG_MAC_B0 ); if ( EFAB_DWORD_FIELD ( reg, FCN_XM_LCLFLT ) || EFAB_DWORD_FIELD ( reg, FCN_XM_RMTFLT ) ) { EFAB_TRACE ( "MGT_INT: "EFAB_DWORD_FMT"\n", EFAB_DWORD_VAL ( reg ) ); return 0; } return 1; } static void falcon_mask_status_intr ( struct efab_nic *efab, int enable ) { efab_dword_t reg; if ( efab->pci_revision < FALCON_REV_B0 ) return; /* Flush the ISR */ if ( enable ) falcon_xmac_readl ( efab, ®, FCN_XM_MGT_INT_REG_MAC_B0 ); EFAB_POPULATE_DWORD_2 ( reg, FCN_XM_MSK_RMTFLT, !enable, FCN_XM_MSK_LCLFLT, !enable); falcon_xmac_readl ( efab, ®, FCN_XM_MGT_INT_MSK_REG_MAC_B0 ); } /** * Reset 10G MAC connected to port * */ static int falcon_reset_xmac ( struct efab_nic *efab ) { efab_dword_t reg; int count; EFAB_POPULATE_DWORD_1 ( reg, FCN_XM_CORE_RST, 1 ); falcon_xmac_writel ( efab, ®, FCN_XM_GLB_CFG_REG_MAC ); for ( count = 0 ; count < 1000 ; count++ ) { udelay ( 10 ); falcon_xmac_readl ( efab, ®, FCN_XM_GLB_CFG_REG_MAC ); if ( EFAB_DWORD_FIELD ( reg, FCN_XM_CORE_RST ) == 0 ) return 0; } return -ETIMEDOUT; } static int falcon_reset_xaui ( struct efab_nic *efab ) { efab_dword_t reg; int count; if (!efab->is_asic) return 0; EFAB_POPULATE_DWORD_1 ( reg, FCN_XX_RST_XX_EN, 1 ); falcon_xmac_writel ( efab, ®, FCN_XX_PWR_RST_REG_MAC ); /* Give some time for the link to establish */ for (count = 0; count < 1000; count++) { /* wait upto 10ms */ falcon_xmac_readl ( efab, ®, FCN_XX_PWR_RST_REG_MAC ); if ( EFAB_DWORD_FIELD ( reg, FCN_XX_RST_XX_EN ) == 0 ) { falcon_setup_xaui ( efab ); return 0; } udelay(10); } EFAB_ERR ( "timed out waiting for XAUI/XGXS reset\n" ); return -ETIMEDOUT; } static int falcon_xaui_link_ok ( struct efab_nic *efab ) { efab_dword_t reg; int align_done, lane_status, sync; int has_phyxs; int link_ok = 1; /* Read Falcon XAUI side */ if ( efab->is_asic ) { /* Read link status */ falcon_xmac_readl ( efab, ®, FCN_XX_CORE_STAT_REG_MAC ); align_done = EFAB_DWORD_FIELD ( reg, FCN_XX_ALIGN_DONE ); sync = EFAB_DWORD_FIELD ( reg, FCN_XX_SYNC_STAT ); sync = ( sync == FCN_XX_SYNC_STAT_DECODE_SYNCED ); link_ok = align_done && sync; } /* Clear link status ready for next read */ EFAB_SET_DWORD_FIELD ( reg, FCN_XX_COMMA_DET, FCN_XX_COMMA_DET_RESET ); EFAB_SET_DWORD_FIELD ( reg, FCN_XX_CHARERR, FCN_XX_CHARERR_RESET); EFAB_SET_DWORD_FIELD ( reg, FCN_XX_DISPERR, FCN_XX_DISPERR_RESET); falcon_xmac_writel ( efab, ®, FCN_XX_CORE_STAT_REG_MAC ); has_phyxs = ( efab->phy_op->mmds & ( 1 << MDIO_MMD_PHYXS ) ); if ( link_ok && has_phyxs ) { lane_status = falcon_mdio_read ( efab, MDIO_MMD_PHYXS, MDIO_PHYXS_LANE_STATE ); link_ok = ( lane_status & ( 1 << MDIO_PHYXS_LANE_ALIGNED_LBN ) ); if (!link_ok ) EFAB_LOG ( "XGXS lane status: %x\n", lane_status ); } return link_ok; } /** * Initialise XMAC * */ static void falcon_reconfigure_xmac ( struct efab_nic *efab ) { efab_dword_t reg; int max_frame_len; /* Configure MAC - cut-thru mode is hard wired on */ EFAB_POPULATE_DWORD_3 ( reg, FCN_XM_RX_JUMBO_MODE, 1, FCN_XM_TX_STAT_EN, 1, FCN_XM_RX_STAT_EN, 1); falcon_xmac_writel ( efab, ®, FCN_XM_GLB_CFG_REG_MAC ); /* Configure TX */ EFAB_POPULATE_DWORD_6 ( reg, FCN_XM_TXEN, 1, FCN_XM_TX_PRMBL, 1, FCN_XM_AUTO_PAD, 1, FCN_XM_TXCRC, 1, FCN_XM_FCNTL, 1, FCN_XM_IPG, 0x3 ); falcon_xmac_writel ( efab, ®, FCN_XM_TX_CFG_REG_MAC ); /* Configure RX */ EFAB_POPULATE_DWORD_4 ( reg, FCN_XM_RXEN, 1, FCN_XM_AUTO_DEPAD, 0, FCN_XM_ACPT_ALL_MCAST, 1, FCN_XM_PASS_CRC_ERR, 1 ); falcon_xmac_writel ( efab, ®, FCN_XM_RX_CFG_REG_MAC ); /* Set frame length */ max_frame_len = EFAB_MAX_FRAME_LEN ( ETH_FRAME_LEN ); EFAB_POPULATE_DWORD_1 ( reg, FCN_XM_MAX_RX_FRM_SIZE, max_frame_len ); falcon_xmac_writel ( efab, ®, FCN_XM_RX_PARAM_REG_MAC ); EFAB_POPULATE_DWORD_2 ( reg, FCN_XM_MAX_TX_FRM_SIZE, max_frame_len, FCN_XM_TX_JUMBO_MODE, 1 ); falcon_xmac_writel ( efab, ®, FCN_XM_TX_PARAM_REG_MAC ); /* Enable flow control receipt */ EFAB_POPULATE_DWORD_2 ( reg, FCN_XM_PAUSE_TIME, 0xfffe, FCN_XM_DIS_FCNTL, 0 ); falcon_xmac_writel ( efab, ®, FCN_XM_FC_REG_MAC ); /* Set MAC address */ EFAB_POPULATE_DWORD_4 ( reg, FCN_XM_ADR_0, efab->mac_addr[0], FCN_XM_ADR_1, efab->mac_addr[1], FCN_XM_ADR_2, efab->mac_addr[2], FCN_XM_ADR_3, efab->mac_addr[3] ); falcon_xmac_writel ( efab, ®, FCN_XM_ADR_LO_REG_MAC ); EFAB_POPULATE_DWORD_2 ( reg, FCN_XM_ADR_4, efab->mac_addr[4], FCN_XM_ADR_5, efab->mac_addr[5] ); falcon_xmac_writel ( efab, ®, FCN_XM_ADR_HI_REG_MAC ); } static int falcon_init_xmac ( struct efab_nic *efab ) { int count, rc; /* Mask the PHY management interrupt */ falcon_mask_status_intr ( efab, 0 ); /* Initialise the PHY to instantiate the clock. */ rc = efab->phy_op->init ( efab ); if ( rc ) { EFAB_ERR ( "unable to initialise PHY\n" ); goto fail1; } falcon_reset_xaui ( efab ); /* Give the PHY and MAC time to faff */ mdelay ( 100 ); /* Reset and reconfigure the XMAC */ rc = falcon_reset_xmac ( efab ); if ( rc ) goto fail2; falcon_reconfigure_xmac ( efab ); falcon_reconfigure_mac_wrapper ( efab ); /** * Now wait for the link to come up. This may take a while * for some slower PHY's. */ for (count=0; count<50; count++) { int link_ok = 1; /* Wait a while for the link to come up. */ mdelay ( 100 ); if ((count % 5) == 0) putchar ( '.' ); /* Does the PHY think the wire-side link is up? */ link_ok = mdio_clause45_links_ok ( efab ); /* Ensure the XAUI link to the PHY is good */ if ( link_ok ) { link_ok = falcon_xaui_link_ok ( efab ); if ( !link_ok ) falcon_reset_xaui ( efab ); } /* Check fault indication */ if ( link_ok ) link_ok = falcon_xgmii_status ( efab ); efab->link_up = link_ok; if ( link_ok ) { /* unmask the status interrupt */ falcon_mask_status_intr ( efab, 1 ); return 0; } } /* Link failed to come up, but initialisation was fine. */ rc = -ETIMEDOUT; fail2: fail1: return rc; } static struct efab_mac_operations falcon_xmac_operations = { .init = falcon_init_xmac, }; /******************************************************************************* * * * Null PHY handling * * *******************************************************************************/ static int falcon_xaui_phy_init ( struct efab_nic *efab ) { /* CX4 is always 10000FD only */ efab->link_options = LPA_EF_10000FULL; /* There is no PHY! */ return 0; } static struct efab_phy_operations falcon_xaui_phy_ops = { .init = falcon_xaui_phy_init, .mmds = 0, }; /******************************************************************************* * * * Alaska PHY * * *******************************************************************************/ /** * Initialise Alaska PHY * */ static int alaska_init ( struct efab_nic *efab ) { unsigned int advertised, lpa; /* Read link up status */ efab->link_up = gmii_link_ok ( efab ); if ( ! efab->link_up ) return -EIO; /* Determine link options from PHY. */ advertised = gmii_autoneg_advertised ( efab ); lpa = gmii_autoneg_lpa ( efab ); efab->link_options = gmii_nway_result ( advertised & lpa ); return 0; } static struct efab_phy_operations falcon_alaska_phy_ops = { .init = alaska_init, }; /******************************************************************************* * * * xfp * * *******************************************************************************/ #define XFP_REQUIRED_DEVS ( MDIO_MMDREG_DEVS0_PCS | \ MDIO_MMDREG_DEVS0_PMAPMD | \ MDIO_MMDREG_DEVS0_PHYXS ) static int falcon_xfp_phy_init ( struct efab_nic *efab ) { int rc; /* Optical link is always 10000FD only */ efab->link_options = LPA_EF_10000FULL; /* Reset the PHY */ rc = mdio_clause45_reset_mmd ( efab, MDIO_MMD_PHYXS ); if ( rc ) return rc; return 0; } static struct efab_phy_operations falcon_xfp_phy_ops = { .init = falcon_xfp_phy_init, .mmds = XFP_REQUIRED_DEVS, }; /******************************************************************************* * * * txc43128 * * *******************************************************************************/ /* Command register */ #define TXC_GLRGS_GLCMD (0xc004) #define TXC_GLCMD_LMTSWRST_LBN (14) /* Amplitude on lanes 0+1, 2+3 */ #define TXC_ALRGS_ATXAMP0 (0xc041) #define TXC_ALRGS_ATXAMP1 (0xc042) /* Bit position of value for lane 0+2, 1+3 */ #define TXC_ATXAMP_LANE02_LBN (3) #define TXC_ATXAMP_LANE13_LBN (11) #define TXC_ATXAMP_1280_mV (0) #define TXC_ATXAMP_1200_mV (8) #define TXC_ATXAMP_1120_mV (12) #define TXC_ATXAMP_1060_mV (14) #define TXC_ATXAMP_0820_mV (25) #define TXC_ATXAMP_0720_mV (26) #define TXC_ATXAMP_0580_mV (27) #define TXC_ATXAMP_0440_mV (28) #define TXC_ATXAMP_0820_BOTH ( (TXC_ATXAMP_0820_mV << TXC_ATXAMP_LANE02_LBN) | \ (TXC_ATXAMP_0820_mV << TXC_ATXAMP_LANE13_LBN) ) #define TXC_ATXAMP_DEFAULT (0x6060) /* From databook */ /* Preemphasis on lanes 0+1, 2+3 */ #define TXC_ALRGS_ATXPRE0 (0xc043) #define TXC_ALRGS_ATXPRE1 (0xc044) #define TXC_ATXPRE_NONE (0) #define TXC_ATXPRE_DEFAULT (0x1010) /* From databook */ #define TXC_REQUIRED_DEVS ( MDIO_MMDREG_DEVS0_PCS | \ MDIO_MMDREG_DEVS0_PMAPMD | \ MDIO_MMDREG_DEVS0_PHYXS ) static int falcon_txc_logic_reset ( struct efab_nic *efab ) { int val; int tries = 50; val = falcon_mdio_read ( efab, MDIO_MMD_PCS, TXC_GLRGS_GLCMD ); val |= (1 << TXC_GLCMD_LMTSWRST_LBN); falcon_mdio_write ( efab, MDIO_MMD_PCS, TXC_GLRGS_GLCMD, val ); while ( tries--) { val = falcon_mdio_read ( efab, MDIO_MMD_PCS, TXC_GLRGS_GLCMD ); if ( ~val & ( 1 << TXC_GLCMD_LMTSWRST_LBN ) ) return 0; udelay(1); } EFAB_ERR ( "logic reset failed\n" ); return -ETIMEDOUT; } static int falcon_txc_phy_init ( struct efab_nic *efab ) { int rc; /* CX4 is always 10000FD only */ efab->link_options = LPA_EF_10000FULL; /* reset the phy */ rc = mdio_clause45_reset_mmd ( efab, MDIO_MMD_PMAPMD ); if ( rc ) goto fail1; rc = mdio_clause45_check_mmds ( efab ); if ( rc ) goto fail2; /* Turn amplitude down and preemphasis off on the host side * (PHY<->MAC) as this is believed less likely to upset falcon * and no adverse effects have been noted. It probably also * saves a picowatt or two */ /* Turn off preemphasis */ falcon_mdio_write ( efab, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE0, TXC_ATXPRE_NONE ); falcon_mdio_write ( efab, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE1, TXC_ATXPRE_NONE ); /* Turn down the amplitude */ falcon_mdio_write ( efab, MDIO_MMD_PHYXS, TXC_ALRGS_ATXAMP0, TXC_ATXAMP_0820_BOTH ); falcon_mdio_write ( efab, MDIO_MMD_PHYXS, TXC_ALRGS_ATXAMP1, TXC_ATXAMP_0820_BOTH ); /* Set the line side amplitude and preemphasis to the databook * defaults as an erratum causes them to be 0 on at least some * PHY rev.s */ falcon_mdio_write ( efab, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXPRE0, TXC_ATXPRE_DEFAULT ); falcon_mdio_write ( efab, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXPRE1, TXC_ATXPRE_DEFAULT ); falcon_mdio_write ( efab, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXAMP0, TXC_ATXAMP_DEFAULT ); falcon_mdio_write ( efab, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXAMP1, TXC_ATXAMP_DEFAULT ); rc = falcon_txc_logic_reset ( efab ); if ( rc ) goto fail3; return 0; fail3: fail2: fail1: return rc; } static struct efab_phy_operations falcon_txc_phy_ops = { .init = falcon_txc_phy_init, .mmds = TXC_REQUIRED_DEVS, }; /******************************************************************************* * * * tenxpress * * *******************************************************************************/ #define TENXPRESS_REQUIRED_DEVS ( MDIO_MMDREG_DEVS0_PMAPMD | \ MDIO_MMDREG_DEVS0_PCS | \ MDIO_MMDREG_DEVS0_PHYXS ) #define PCS_TEST_SELECT_REG 0xd807 /* PRM 10.5.8 */ #define CLK312_EN_LBN 3 #define CLK312_EN_WIDTH 1 #define PCS_CLOCK_CTRL_REG 0xd801 #define PLL312_RST_N_LBN 2 /* Special Software reset register */ #define PMA_PMD_EXT_CTRL_REG 49152 #define PMA_PMD_EXT_SSR_LBN 15 /* Boot status register */ #define PCS_BOOT_STATUS_REG 0xd000 #define PCS_BOOT_FATAL_ERR_LBN 0 #define PCS_BOOT_PROGRESS_LBN 1 #define PCS_BOOT_PROGRESS_WIDTH 2 #define PCS_BOOT_COMPLETE_LBN 3 #define PCS_SOFT_RST2_REG 0xd806 #define SERDES_RST_N_LBN 13 #define XGXS_RST_N_LBN 12 static int falcon_tenxpress_check_c11 ( struct efab_nic *efab ) { int count; uint32_t boot_stat; /* Check that the C11 CPU has booted */ for (count=0; count<10; count++) { boot_stat = falcon_mdio_read ( efab, MDIO_MMD_PCS, PCS_BOOT_STATUS_REG ); if ( boot_stat & ( 1 << PCS_BOOT_COMPLETE_LBN ) ) return 0; udelay(10); } EFAB_ERR ( "C11 failed to boot\n" ); return -ETIMEDOUT; } static int falcon_tenxpress_phy_init ( struct efab_nic *efab ) { int rc, reg; /* 10XPRESS is always 10000FD (at the moment) */ efab->link_options = LPA_EF_10000FULL; /* Wait for the blocks to come out of reset */ rc = mdio_clause45_wait_reset_mmds ( efab ); if ( rc ) goto fail1; rc = mdio_clause45_check_mmds ( efab ); if ( rc ) goto fail2; /* Turn on the clock */ reg = (1 << CLK312_EN_LBN); falcon_mdio_write ( efab, MDIO_MMD_PCS, PCS_TEST_SELECT_REG, reg); /* Wait 200ms for the PHY to boot */ mdelay(200); rc = falcon_tenxpress_check_c11 ( efab ); if ( rc ) goto fail3; return 0; fail3: fail2: fail1: return rc; } static struct efab_phy_operations falcon_tenxpress_phy_ops = { .init = falcon_tenxpress_phy_init, .mmds = TENXPRESS_REQUIRED_DEVS, }; /******************************************************************************* * * * PM8358 * * *******************************************************************************/ /* The PM8358 just presents a DTE XS */ #define PM8358_REQUIRED_DEVS (MDIO_MMDREG_DEVS0_DTEXS) /* PHY-specific definitions */ /* Master ID and Global Performance Monitor Update */ #define PMC_MASTER_REG (0xd000) /* Analog Tx Rx settings under software control */ #define PMC_MASTER_ANLG_CTRL (1<< 11) /* Master Configuration register 2 */ #define PMC_MCONF2_REG (0xd002) /* Drive Tx off centre of data eye (1) vs. clock edge (0) */ #define PMC_MCONF2_TEDGE (1 << 2) /* Drive Rx off centre of data eye (1) vs. clock edge (0) */ #define PMC_MCONF2_REDGE (1 << 3) /* Analog Rx settings */ #define PMC_ANALOG_RX_CFG0 (0xd025) #define PMC_ANALOG_RX_CFG1 (0xd02d) #define PMC_ANALOG_RX_CFG2 (0xd035) #define PMC_ANALOG_RX_CFG3 (0xd03d) #define PMC_ANALOG_RX_TERM (1 << 15) /* Bit 15 of RX CFG: 0 for 100 ohms float, 1 for 50 to 1.2V */ #define PMC_ANALOG_RX_EQ_MASK (3 << 8) #define PMC_ANALOG_RX_EQ_NONE (0 << 8) #define PMC_ANALOG_RX_EQ_HALF (1 << 8) #define PMC_ANALOG_RX_EQ_FULL (2 << 8) #define PMC_ANALOG_RX_EQ_RSVD (3 << 8) static int falcon_pm8358_phy_init ( struct efab_nic *efab ) { int rc, reg, i; /* This is a XAUI retimer part */ efab->link_options = LPA_EF_10000FULL; rc = mdio_clause45_reset_mmd ( efab, MDIO_MMDREG_DEVS0_DTEXS ); if ( rc ) return rc; /* Enable software control of analogue settings */ reg = falcon_mdio_read ( efab, MDIO_MMD_DTEXS, PMC_MASTER_REG ); reg |= PMC_MASTER_ANLG_CTRL; falcon_mdio_write ( efab, MDIO_MMD_DTEXS, PMC_MASTER_REG, reg ); /* Turn rx eq on for all channels */ for (i=0; i< 3; i++) { /* The analog CFG registers are evenly spaced 8 apart */ uint16_t addr = PMC_ANALOG_RX_CFG0 + 8*i; reg = falcon_mdio_read ( efab, MDIO_MMD_DTEXS, addr ); reg = ( reg & ~PMC_ANALOG_RX_EQ_MASK ) | PMC_ANALOG_RX_EQ_FULL; falcon_mdio_write ( efab, MDIO_MMD_DTEXS, addr, reg ); } /* Set TEDGE, clear REDGE */ reg = falcon_mdio_read ( efab, MDIO_MMD_DTEXS, PMC_MCONF2_REG ); reg = ( reg & ~PMC_MCONF2_REDGE) | PMC_MCONF2_TEDGE; falcon_mdio_write ( efab, MDIO_MMD_DTEXS, PMC_MCONF2_REG, reg ); return 0; } static struct efab_phy_operations falcon_pm8358_phy_ops = { .init = falcon_pm8358_phy_init, .mmds = PM8358_REQUIRED_DEVS, }; /******************************************************************************* * * * SFE4001 support * * *******************************************************************************/ #define MAX_TEMP_THRESH 90 /* I2C Expander */ #define PCA9539 0x74 #define P0_IN 0x00 #define P0_OUT 0x02 #define P0_CONFIG 0x06 #define P0_EN_1V0X_LBN 0 #define P0_EN_1V0X_WIDTH 1 #define P0_EN_1V2_LBN 1 #define P0_EN_1V2_WIDTH 1 #define P0_EN_2V5_LBN 2 #define P0_EN_2V5_WIDTH 1 #define P0_EN_3V3X_LBN 3 #define P0_EN_3V3X_WIDTH 1 #define P0_EN_5V_LBN 4 #define P0_EN_5V_WIDTH 1 #define P0_X_TRST_LBN 6 #define P0_X_TRST_WIDTH 1 #define P1_IN 0x01 #define P1_CONFIG 0x07 #define P1_AFE_PWD_LBN 0 #define P1_AFE_PWD_WIDTH 1 #define P1_DSP_PWD25_LBN 1 #define P1_DSP_PWD25_WIDTH 1 #define P1_SPARE_LBN 4 #define P1_SPARE_WIDTH 4 /* Temperature Sensor */ #define MAX6647 0x4e #define RSL 0x02 #define RLHN 0x05 #define WLHO 0x0b static struct i2c_device i2c_pca9539 = { .dev_addr = PCA9539, .dev_addr_len = 1, .word_addr_len = 1, }; static struct i2c_device i2c_max6647 = { .dev_addr = MAX6647, .dev_addr_len = 1, .word_addr_len = 1, }; static int sfe4001_init ( struct efab_nic *efab ) { struct i2c_interface *i2c = &efab->i2c_bb.i2c; efab_dword_t reg; uint8_t in, cfg, out; int count, rc; EFAB_LOG ( "Initialise SFE4001 board\n" ); /* Ensure XGXS and XAUI SerDes are held in reset */ EFAB_POPULATE_DWORD_7 ( reg, FCN_XX_PWRDNA_EN, 1, FCN_XX_PWRDNB_EN, 1, FCN_XX_RSTPLLAB_EN, 1, FCN_XX_RESETA_EN, 1, FCN_XX_RESETB_EN, 1, FCN_XX_RSTXGXSRX_EN, 1, FCN_XX_RSTXGXSTX_EN, 1 ); falcon_xmac_writel ( efab, ®, FCN_XX_PWR_RST_REG_MAC); udelay(10); /* Set DSP over-temperature alert threshold */ cfg = MAX_TEMP_THRESH; rc = i2c->write ( i2c, &i2c_max6647, WLHO, &cfg, EFAB_BYTE ); if ( rc ) goto fail1; /* Read it back and verify */ rc = i2c->read ( i2c, &i2c_max6647, RLHN, &in, EFAB_BYTE ); if ( rc ) goto fail2; if ( in != MAX_TEMP_THRESH ) { EFAB_ERR ( "Unable to verify MAX6647 limit (requested=%d " "confirmed=%d)\n", cfg, in ); rc = -EIO; goto fail3; } /* Clear any previous over-temperature alert */ rc = i2c->read ( i2c, &i2c_max6647, RSL, &in, EFAB_BYTE ); if ( rc ) goto fail4; /* Enable port 0 and 1 outputs on IO expander */ cfg = 0x00; rc = i2c->write ( i2c, &i2c_pca9539, P0_CONFIG, &cfg, EFAB_BYTE ); if ( rc ) goto fail5; cfg = 0xff & ~(1 << P1_SPARE_LBN); rc = i2c->write ( i2c, &i2c_pca9539, P1_CONFIG, &cfg, EFAB_BYTE ); if ( rc ) goto fail6; /* Turn all power off then wait 1 sec. This ensures PHY is reset */ out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) | (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) | (0 << P0_EN_1V0X_LBN)); rc = i2c->write ( i2c, &i2c_pca9539, P0_OUT, &out, EFAB_BYTE ); if ( rc ) goto fail7; mdelay(1000); for (count=0; count<20; count++) { /* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */ out = 0xff & ~( (1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) | (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) | (1 << P0_X_TRST_LBN) ); rc = i2c->write ( i2c, &i2c_pca9539, P0_OUT, &out, EFAB_BYTE ); if ( rc ) goto fail8; mdelay ( 10 ); /* Turn on the 1V power rail */ out &= ~( 1 << P0_EN_1V0X_LBN ); rc = i2c->write ( i2c, &i2c_pca9539, P0_OUT, &out, EFAB_BYTE ); if ( rc ) goto fail9; EFAB_LOG ( "Waiting for power...(attempt %d)\n", count); mdelay ( 1000 ); /* Check DSP is powered */ rc = i2c->read ( i2c, &i2c_pca9539, P1_IN, &in, EFAB_BYTE ); if ( rc ) goto fail10; if ( in & ( 1 << P1_AFE_PWD_LBN ) ) return 0; } rc = -ETIMEDOUT; fail10: fail9: fail8: fail7: /* Turn off power rails */ out = 0xff; (void) i2c->write ( i2c, &i2c_pca9539, P0_OUT, &out, EFAB_BYTE ); /* Disable port 1 outputs on IO expander */ out = 0xff; (void) i2c->write ( i2c, &i2c_pca9539, P1_CONFIG, &out, EFAB_BYTE ); fail6: /* Disable port 0 outputs */ out = 0xff; (void) i2c->write ( i2c, &i2c_pca9539, P1_CONFIG, &out, EFAB_BYTE ); fail5: fail4: fail3: fail2: fail1: EFAB_ERR ( "Failed initialising SFE4001 board\n" ); return rc; } static void sfe4001_fini ( struct efab_nic *efab ) { struct i2c_interface *i2c = &efab->i2c_bb.i2c; uint8_t in, cfg, out; EFAB_ERR ( "Turning off SFE4001\n" ); /* Turn off all power rails */ out = 0xff; (void) i2c->write ( i2c, &i2c_pca9539, P0_OUT, &out, EFAB_BYTE ); /* Disable port 1 outputs on IO expander */ cfg = 0xff; (void) i2c->write ( i2c, &i2c_pca9539, P1_CONFIG, &cfg, EFAB_BYTE ); /* Disable port 0 outputs on IO expander */ cfg = 0xff; (void) i2c->write ( i2c, &i2c_pca9539, P0_CONFIG, &cfg, EFAB_BYTE ); /* Clear any over-temperature alert */ (void) i2c->read ( i2c, &i2c_max6647, RSL, &in, EFAB_BYTE ); } struct efab_board_operations sfe4001_ops = { .init = sfe4001_init, .fini = sfe4001_fini, }; static int sfe4002_init ( struct efab_nic *efab __attribute__((unused)) ) { return 0; } static void sfe4002_fini ( struct efab_nic *efab __attribute__((unused)) ) { } struct efab_board_operations sfe4002_ops = { .init = sfe4002_init, .fini = sfe4002_fini, }; static int sfe4003_init ( struct efab_nic *efab __attribute__((unused)) ) { return 0; } static void sfe4003_fini ( struct efab_nic *efab __attribute__((unused)) ) { } struct efab_board_operations sfe4003_ops = { .init = sfe4003_init, .fini = sfe4003_fini, }; /******************************************************************************* * * * Hardware initialisation * * *******************************************************************************/ static void falcon_free_special_buffer ( void *p ) { /* We don't bother cleaning up the buffer table entries - * we're hardly limited */ free_dma ( p, EFAB_BUF_ALIGN ); } static void* falcon_alloc_special_buffer ( struct efab_nic *efab, int bytes, struct efab_special_buffer *entry ) { void* buffer; int remaining; efab_qword_t buf_desc; unsigned long dma_addr; /* Allocate the buffer, aligned on a buffer address boundary */ buffer = malloc_dma ( bytes, EFAB_BUF_ALIGN ); if ( ! buffer ) return NULL; /* Push buffer table entries to back the buffer */ entry->id = efab->buffer_head; entry->dma_addr = dma_addr = virt_to_bus ( buffer ); assert ( ( dma_addr & ( EFAB_BUF_ALIGN - 1 ) ) == 0 ); remaining = bytes; while ( remaining > 0 ) { EFAB_POPULATE_QWORD_3 ( buf_desc, FCN_IP_DAT_BUF_SIZE, FCN_IP_DAT_BUF_SIZE_4K, FCN_BUF_ADR_FBUF, ( dma_addr >> 12 ), FCN_BUF_OWNER_ID_FBUF, 0 ); falcon_write_sram ( efab, &buf_desc, efab->buffer_head ); ++efab->buffer_head; dma_addr += EFAB_BUF_ALIGN; remaining -= EFAB_BUF_ALIGN; } EFAB_TRACE ( "Allocated 0x%x bytes at %p backed by buffer table " "entries 0x%x..0x%x\n", bytes, buffer, entry->id, efab->buffer_head - 1 ); return buffer; } static void clear_b0_fpga_memories ( struct efab_nic *efab) { efab_oword_t blanko, temp; efab_dword_t blankd; int offset; EFAB_ZERO_OWORD ( blanko ); EFAB_ZERO_DWORD ( blankd ); /* Clear the address region register */ EFAB_POPULATE_OWORD_4 ( temp, FCN_ADR_REGION0, 0, FCN_ADR_REGION1, ( 1 << 16 ), FCN_ADR_REGION2, ( 2 << 16 ), FCN_ADR_REGION3, ( 3 << 16 ) ); falcon_write ( efab, &temp, FCN_ADR_REGION_REG_KER ); EFAB_TRACE ( "Clearing filter and RSS tables\n" ); for ( offset = FCN_RX_FILTER_TBL0 ; offset < FCN_RX_RSS_INDIR_TBL_B0+0x800 ; offset += 0x10 ) { falcon_write ( efab, &blanko, offset ); } EFAB_TRACE ( "Wiping buffer tables\n" ); /* Notice the 8 byte access mode */ for ( offset = 0x2800000 ; offset < 0x3000000 ; offset += 0x8) { _falcon_writel ( efab, 0, offset ); _falcon_writel ( efab, 0, offset + 4 ); wmb(); } } static int falcon_reset ( struct efab_nic *efab ) { efab_oword_t glb_ctl_reg_ker; /* Initiate software reset */ EFAB_POPULATE_OWORD_6 ( glb_ctl_reg_ker, FCN_PCIE_CORE_RST_CTL, EXCLUDE_FROM_RESET, FCN_PCIE_NSTCK_RST_CTL, EXCLUDE_FROM_RESET, FCN_PCIE_SD_RST_CTL, EXCLUDE_FROM_RESET, FCN_EE_RST_CTL, EXCLUDE_FROM_RESET, FCN_EXT_PHY_RST_DUR, 0x7, /* 10ms */ FCN_SWRST, 1 ); falcon_write ( efab, &glb_ctl_reg_ker, FCN_GLB_CTL_REG_KER ); /* Allow 50ms for reset */ mdelay ( 50 ); /* Check for device reset complete */ falcon_read ( efab, &glb_ctl_reg_ker, FCN_GLB_CTL_REG_KER ); if ( EFAB_OWORD_FIELD ( glb_ctl_reg_ker, FCN_SWRST ) != 0 ) { EFAB_ERR ( "Reset failed\n" ); return -ETIMEDOUT; } if ( ( efab->pci_revision == FALCON_REV_B0 ) && !efab->is_asic ) { clear_b0_fpga_memories ( efab ); } return 0; } /** Offset of MAC address within EEPROM or Flash */ #define FALCON_MAC_ADDRESS_OFFSET 0x310 /* * Falcon EEPROM structure */ #define SF_NV_CONFIG_BASE 0x300 #define SF_NV_CONFIG_EXTRA 0xA0 struct falcon_nv_config_ver2 { uint16_t nports; uint8_t port0_phy_addr; uint8_t port0_phy_type; uint8_t port1_phy_addr; uint8_t port1_phy_type; uint16_t asic_sub_revision; uint16_t board_revision; uint8_t mac_location; }; struct falcon_nv_extra { uint16_t magicnumber; uint16_t structure_version; uint16_t checksum; union { struct falcon_nv_config_ver2 ver2; } ver_specific; }; #define BOARD_TYPE(_rev) (_rev >> 8) static void falcon_probe_nic_variant ( struct efab_nic *efab, struct pci_device *pci ) { efab_oword_t altera_build, nic_stat; int is_pcie, fpga_version; uint8_t revision; /* PCI revision */ pci_read_config_byte ( pci, PCI_CLASS_REVISION, &revision ); efab->pci_revision = revision; /* Asic vs FPGA */ falcon_read ( efab, &altera_build, FCN_ALTERA_BUILD_REG_KER ); fpga_version = EFAB_OWORD_FIELD ( altera_build, FCN_VER_ALL ); efab->is_asic = (fpga_version == 0); /* MAC and PCI type */ falcon_read ( efab, &nic_stat, FCN_NIC_STAT_REG ); if ( efab->pci_revision == FALCON_REV_B0 ) { is_pcie = 1; efab->phy_10g = EFAB_OWORD_FIELD ( nic_stat, FCN_STRAP_10G ); } else if ( efab->is_asic ) { is_pcie = EFAB_OWORD_FIELD ( nic_stat, FCN_STRAP_PCIE ); efab->phy_10g = EFAB_OWORD_FIELD ( nic_stat, FCN_STRAP_10G ); } else { int minor = EFAB_OWORD_FIELD ( altera_build, FCN_VER_MINOR ); is_pcie = 0; efab->phy_10g = ( minor == 0x14 ); } } static void falcon_init_spi_device ( struct efab_nic *efab, struct spi_device *spi ) { /* Falcon's SPI interface only supports reads/writes of up to 16 bytes. * Reduce the nvs block size down to satisfy this - which means callers * should use the nvs_* functions rather than spi_*. */ if ( spi->nvs.block_size > FALCON_SPI_MAX_LEN ) spi->nvs.block_size = FALCON_SPI_MAX_LEN; spi->bus = &efab->spi_bus; efab->spi = spi; } static int falcon_probe_spi ( struct efab_nic *efab ) { efab_oword_t nic_stat, gpio_ctl, ee_vpd_cfg; int has_flash, has_eeprom, ad9bit; falcon_read ( efab, &nic_stat, FCN_NIC_STAT_REG ); falcon_read ( efab, &gpio_ctl, FCN_GPIO_CTL_REG_KER ); falcon_read ( efab, &ee_vpd_cfg, FCN_EE_VPD_CFG_REG ); /* determine if FLASH / EEPROM is present */ if ( ( efab->pci_revision >= FALCON_REV_B0 ) || efab->is_asic ) { has_flash = EFAB_OWORD_FIELD ( nic_stat, FCN_SF_PRST ); has_eeprom = EFAB_OWORD_FIELD ( nic_stat, FCN_EE_PRST ); } else { has_flash = EFAB_OWORD_FIELD ( gpio_ctl, FCN_FLASH_PRESENT ); has_eeprom = EFAB_OWORD_FIELD ( gpio_ctl, FCN_EEPROM_PRESENT ); } ad9bit = EFAB_OWORD_FIELD ( ee_vpd_cfg, FCN_EE_VPD_EN_AD9_MODE ); /* Configure the SPI and I2C bus */ efab->spi_bus.rw = falcon_spi_rw; init_i2c_bit_basher ( &efab->i2c_bb, &falcon_i2c_bit_ops ); /* Configure the EEPROM SPI device. Generally, an Atmel 25040 * (or similar) is used, but this is only possible if there is also * a flash device present to store the boot-time chip configuration. */ if ( has_eeprom ) { if ( has_flash && ad9bit ) init_at25040 ( &efab->spi_eeprom ); else init_mc25xx640 ( &efab->spi_eeprom ); falcon_init_spi_device ( efab, &efab->spi_eeprom ); } /* Configure the FLASH SPI device */ if ( has_flash ) { init_at25f1024 ( &efab->spi_flash ); falcon_init_spi_device ( efab, &efab->spi_flash ); } EFAB_LOG ( "flash is %s, EEPROM is %s%s\n", ( has_flash ? "present" : "absent" ), ( has_eeprom ? "present " : "absent" ), ( has_eeprom ? (ad9bit ? "(9bit)" : "(16bit)") : "") ); /* The device MUST have flash or eeprom */ if ( ! efab->spi ) { EFAB_ERR ( "Device appears to have no flash or eeprom\n" ); return -EIO; } /* If the device has EEPROM attached, then advertise NVO space */ if ( has_eeprom ) nvo_init ( &efab->nvo, &efab->spi_eeprom.nvs, falcon_nvo_fragments, &efab->netdev->refcnt ); return 0; } static int falcon_probe_nvram ( struct efab_nic *efab ) { struct nvs_device *nvs = &efab->spi->nvs; struct falcon_nv_extra nv; int rc, board_revision; /* Read the MAC address */ rc = nvs_read ( nvs, FALCON_MAC_ADDRESS_OFFSET, efab->mac_addr, ETH_ALEN ); if ( rc ) return rc; /* Poke through the NVRAM structure for the PHY type. */ rc = nvs_read ( nvs, SF_NV_CONFIG_BASE + SF_NV_CONFIG_EXTRA, &nv, sizeof ( nv ) ); if ( rc ) return rc; /* Handle each supported NVRAM version */ if ( ( le16_to_cpu ( nv.magicnumber ) == FCN_NV_MAGIC_NUMBER ) && ( le16_to_cpu ( nv.structure_version ) >= 2 ) ) { struct falcon_nv_config_ver2* ver2 = &nv.ver_specific.ver2; /* Get the PHY type */ efab->phy_addr = le16_to_cpu ( ver2->port0_phy_addr ); efab->phy_type = le16_to_cpu ( ver2->port0_phy_type ); board_revision = le16_to_cpu ( ver2->board_revision ); } else { EFAB_ERR ( "NVram is not recognised\n" ); return -EINVAL; } efab->board_type = BOARD_TYPE ( board_revision ); EFAB_TRACE ( "Falcon board %d phy %d @ addr %d\n", efab->board_type, efab->phy_type, efab->phy_addr ); /* Patch in the board operations */ switch ( efab->board_type ) { case EFAB_BOARD_SFE4001: efab->board_op = &sfe4001_ops; break; case EFAB_BOARD_SFE4002: efab->board_op = &sfe4002_ops; break; case EFAB_BOARD_SFE4003: efab->board_op = &sfe4003_ops; break; default: EFAB_ERR ( "Unrecognised board type\n" ); return -EINVAL; } /* Patch in MAC operations */ if ( efab->phy_10g ) efab->mac_op = &falcon_xmac_operations; else efab->mac_op = &falcon_gmac_operations; /* Hook in the PHY ops */ switch ( efab->phy_type ) { case PHY_TYPE_10XPRESS: efab->phy_op = &falcon_tenxpress_phy_ops; break; case PHY_TYPE_CX4: efab->phy_op = &falcon_xaui_phy_ops; break; case PHY_TYPE_XFP: efab->phy_op = &falcon_xfp_phy_ops; break; case PHY_TYPE_CX4_RTMR: efab->phy_op = &falcon_txc_phy_ops; break; case PHY_TYPE_PM8358: efab->phy_op = &falcon_pm8358_phy_ops; break; case PHY_TYPE_1GIG_ALASKA: efab->phy_op = &falcon_alaska_phy_ops; break; default: EFAB_ERR ( "Unknown PHY type: %d\n", efab->phy_type ); return -EINVAL; } return 0; } static int falcon_init_sram ( struct efab_nic *efab ) { efab_oword_t reg; int count; /* use card in internal SRAM mode */ falcon_read ( efab, ®, FCN_NIC_STAT_REG ); EFAB_SET_OWORD_FIELD ( reg, FCN_ONCHIP_SRAM, 1 ); falcon_write ( efab, ®, FCN_NIC_STAT_REG ); /* Deactivate any external SRAM that might be present */ EFAB_POPULATE_OWORD_2 ( reg, FCN_GPIO1_OEN, 1, FCN_GPIO1_OUT, 1 ); falcon_write ( efab, ®, FCN_GPIO_CTL_REG_KER ); /* Initiate SRAM reset */ EFAB_POPULATE_OWORD_2 ( reg, FCN_SRAM_OOB_BT_INIT_EN, 1, FCN_SRM_NUM_BANKS_AND_BANK_SIZE, 0 ); falcon_write ( efab, ®, FCN_SRM_CFG_REG_KER ); /* Wait for SRAM reset to complete */ count = 0; do { /* SRAM reset is slow; expect around 16ms */ mdelay ( 20 ); /* Check for reset complete */ falcon_read ( efab, ®, FCN_SRM_CFG_REG_KER ); if ( !EFAB_OWORD_FIELD ( reg, FCN_SRAM_OOB_BT_INIT_EN ) ) return 0; } while (++count < 20); /* wait upto 0.4 sec */ EFAB_ERR ( "timed out waiting for SRAM reset\n"); return -ETIMEDOUT; } static void falcon_setup_nic ( struct efab_nic *efab ) { efab_dword_t timer_cmd; efab_oword_t reg; int tx_fc, xoff_thresh, xon_thresh; /* bug5129: Clear the parity enables on the TX data fifos as * they produce false parity errors because of timing issues */ falcon_read ( efab, ®, FCN_SPARE_REG_KER ); EFAB_SET_OWORD_FIELD ( reg, FCN_MEM_PERR_EN_TX_DATA, 0 ); falcon_write ( efab, ®, FCN_SPARE_REG_KER ); /* Set up TX and RX descriptor caches in SRAM */ EFAB_POPULATE_OWORD_1 ( reg, FCN_SRM_TX_DC_BASE_ADR, 0x130000 ); falcon_write ( efab, ®, FCN_SRM_TX_DC_CFG_REG_KER ); EFAB_POPULATE_OWORD_1 ( reg, FCN_TX_DC_SIZE, 1 /* 16 descriptors */ ); falcon_write ( efab, ®, FCN_TX_DC_CFG_REG_KER ); EFAB_POPULATE_OWORD_1 ( reg, FCN_SRM_RX_DC_BASE_ADR, 0x100000 ); falcon_write ( efab, ®, FCN_SRM_RX_DC_CFG_REG_KER ); EFAB_POPULATE_OWORD_1 ( reg, FCN_RX_DC_SIZE, 2 /* 32 descriptors */ ); falcon_write ( efab, ®, FCN_RX_DC_CFG_REG_KER ); /* Set number of RSS CPUs * bug7244: Increase filter depth to reduce RX_RESET likelyhood */ EFAB_POPULATE_OWORD_5 ( reg, FCN_NUM_KER, 0, FCN_UDP_FULL_SRCH_LIMIT, 8, FCN_UDP_WILD_SRCH_LIMIT, 8, FCN_TCP_WILD_SRCH_LIMIT, 8, FCN_TCP_FULL_SRCH_LIMIT, 8); falcon_write ( efab, ®, FCN_RX_FILTER_CTL_REG_KER ); udelay ( 1000 ); /* Setup RX. Wait for descriptor is broken and must * be disabled. RXDP recovery shouldn't be needed, but is. * disable ISCSI parsing because we don't need it */ falcon_read ( efab, ®, FCN_RX_SELF_RST_REG_KER ); EFAB_SET_OWORD_FIELD ( reg, FCN_RX_NODESC_WAIT_DIS, 1 ); EFAB_SET_OWORD_FIELD ( reg, FCN_RX_RECOVERY_EN, 1 ); EFAB_SET_OWORD_FIELD ( reg, FCN_RX_ISCSI_DIS, 1 ); falcon_write ( efab, ®, FCN_RX_SELF_RST_REG_KER ); /* Determine recommended flow control settings. * * Flow control is qualified on B0 and A1/1G, not on A1/10G */ if ( efab->pci_revision == FALCON_REV_B0 ) { tx_fc = 1; xoff_thresh = 54272; /* ~80Kb - 3*max MTU */ xon_thresh = 27648; /* ~3*max MTU */ } else if ( !efab->phy_10g ) { tx_fc = 1; xoff_thresh = 2048; xon_thresh = 512; } else { tx_fc = xoff_thresh = xon_thresh = 0; } /* Setup TX and RX */ falcon_read ( efab, ®, FCN_TX_CFG2_REG_KER ); EFAB_SET_OWORD_FIELD ( reg, FCN_TX_DIS_NON_IP_EV, 1 ); falcon_write ( efab, ®, FCN_TX_CFG2_REG_KER ); falcon_read ( efab, ®, FCN_RX_CFG_REG_KER ); EFAB_SET_OWORD_FIELD_VER ( efab, reg, FCN_RX_USR_BUF_SIZE, (3*4096) / 32 ); if ( efab->pci_revision == FALCON_REV_B0) EFAB_SET_OWORD_FIELD ( reg, FCN_RX_INGR_EN_B0, 1 ); EFAB_SET_OWORD_FIELD_VER ( efab, reg, FCN_RX_XON_MAC_TH, xon_thresh / 256); EFAB_SET_OWORD_FIELD_VER ( efab, reg, FCN_RX_XOFF_MAC_TH, xoff_thresh / 256); EFAB_SET_OWORD_FIELD_VER ( efab, reg, FCN_RX_XOFF_MAC_EN, tx_fc); falcon_write ( efab, ®, FCN_RX_CFG_REG_KER ); /* Set timer register */ EFAB_POPULATE_DWORD_2 ( timer_cmd, FCN_TIMER_MODE, FCN_TIMER_MODE_DIS, FCN_TIMER_VAL, 0 ); falcon_writel ( efab, &timer_cmd, FCN_TIMER_CMD_REG_KER ); } static void falcon_init_resources ( struct efab_nic *efab ) { struct efab_ev_queue *ev_queue = &efab->ev_queue; struct efab_rx_queue *rx_queue = &efab->rx_queue; struct efab_tx_queue *tx_queue = &efab->tx_queue; efab_oword_t reg; int jumbo; /* Initialise the ptrs */ tx_queue->read_ptr = tx_queue->write_ptr = 0; rx_queue->read_ptr = rx_queue->write_ptr = 0; ev_queue->read_ptr = 0; /* Push the event queue to the hardware */ EFAB_POPULATE_OWORD_3 ( reg, FCN_EVQ_EN, 1, FCN_EVQ_SIZE, FQS(FCN_EVQ, EFAB_EVQ_SIZE), FCN_EVQ_BUF_BASE_ID, ev_queue->entry.id ); falcon_write ( efab, ®, FCN_REVISION_REG ( efab, FCN_EVQ_PTR_TBL_KER ) ); /* Push the tx queue to the hardware */ EFAB_POPULATE_OWORD_8 ( reg, FCN_TX_DESCQ_EN, 1, FCN_TX_ISCSI_DDIG_EN, 0, FCN_TX_ISCSI_DDIG_EN, 0, FCN_TX_DESCQ_BUF_BASE_ID, tx_queue->entry.id, FCN_TX_DESCQ_EVQ_ID, 0, FCN_TX_DESCQ_SIZE, FQS(FCN_TX_DESCQ, EFAB_TXD_SIZE), FCN_TX_DESCQ_TYPE, 0 /* kernel queue */, FCN_TX_NON_IP_DROP_DIS_B0, 1 ); falcon_write ( efab, ®, FCN_REVISION_REG ( efab, FCN_TX_DESC_PTR_TBL_KER ) ); /* Push the rx queue to the hardware */ jumbo = ( efab->pci_revision == FALCON_REV_B0 ) ? 0 : 1; EFAB_POPULATE_OWORD_8 ( reg, FCN_RX_ISCSI_DDIG_EN, 0, FCN_RX_ISCSI_HDIG_EN, 0, FCN_RX_DESCQ_BUF_BASE_ID, rx_queue->entry.id, FCN_RX_DESCQ_EVQ_ID, 0, FCN_RX_DESCQ_SIZE, FQS(FCN_RX_DESCQ, EFAB_RXD_SIZE), FCN_RX_DESCQ_TYPE, 0 /* kernel queue */, FCN_RX_DESCQ_JUMBO, jumbo, FCN_RX_DESCQ_EN, 1 ); falcon_write ( efab, ®, FCN_REVISION_REG ( efab, FCN_RX_DESC_PTR_TBL_KER ) ); /* Program INT_ADR_REG_KER */ EFAB_POPULATE_OWORD_1 ( reg, FCN_INT_ADR_KER, virt_to_bus ( &efab->int_ker ) ); falcon_write ( efab, ®, FCN_INT_ADR_REG_KER ); /* Ack the event queue */ falcon_eventq_read_ack ( efab, ev_queue ); } static void falcon_fini_resources ( struct efab_nic *efab ) { efab_oword_t cmd; /* Disable interrupts */ falcon_interrupts ( efab, 0, 0 ); /* Flush the dma queues */ EFAB_POPULATE_OWORD_2 ( cmd, FCN_TX_FLUSH_DESCQ_CMD, 1, FCN_TX_FLUSH_DESCQ, 0 ); falcon_write ( efab, &cmd, FCN_REVISION_REG ( efab, FCN_TX_DESC_PTR_TBL_KER ) ); EFAB_POPULATE_OWORD_2 ( cmd, FCN_RX_FLUSH_DESCQ_CMD, 1, FCN_RX_FLUSH_DESCQ, 0 ); falcon_write ( efab, &cmd, FCN_REVISION_REG ( efab, FCN_RX_DESC_PTR_TBL_KER ) ); mdelay ( 100 ); /* Remove descriptor rings from card */ EFAB_ZERO_OWORD ( cmd ); falcon_write ( efab, &cmd, FCN_REVISION_REG ( efab, FCN_TX_DESC_PTR_TBL_KER ) ); falcon_write ( efab, &cmd, FCN_REVISION_REG ( efab, FCN_RX_DESC_PTR_TBL_KER ) ); falcon_write ( efab, &cmd, FCN_REVISION_REG ( efab, FCN_EVQ_PTR_TBL_KER ) ); } /******************************************************************************* * * * Hardware rx path * * *******************************************************************************/ static void falcon_build_rx_desc ( falcon_rx_desc_t *rxd, struct io_buffer *iob ) { EFAB_POPULATE_QWORD_2 ( *rxd, FCN_RX_KER_BUF_SIZE, EFAB_RX_BUF_SIZE, FCN_RX_KER_BUF_ADR, virt_to_bus ( iob->data ) ); } static void falcon_notify_rx_desc ( struct efab_nic *efab, struct efab_rx_queue *rx_queue ) { efab_dword_t reg; int ptr = rx_queue->write_ptr % EFAB_RXD_SIZE; EFAB_POPULATE_DWORD_1 ( reg, FCN_RX_DESC_WPTR_DWORD, ptr ); falcon_writel ( efab, ®, FCN_RX_DESC_UPD_REG_KER_DWORD ); } /******************************************************************************* * * * Hardware tx path * * *******************************************************************************/ static void falcon_build_tx_desc ( falcon_tx_desc_t *txd, struct io_buffer *iob ) { EFAB_POPULATE_QWORD_2 ( *txd, FCN_TX_KER_BYTE_CNT, iob_len ( iob ), FCN_TX_KER_BUF_ADR, virt_to_bus ( iob->data ) ); } static void falcon_notify_tx_desc ( struct efab_nic *efab, struct efab_tx_queue *tx_queue ) { efab_dword_t reg; int ptr = tx_queue->write_ptr % EFAB_TXD_SIZE; EFAB_POPULATE_DWORD_1 ( reg, FCN_TX_DESC_WPTR_DWORD, ptr ); falcon_writel ( efab, ®, FCN_TX_DESC_UPD_REG_KER_DWORD ); } /******************************************************************************* * * * Software receive interface * * *******************************************************************************/ static int efab_fill_rx_queue ( struct efab_nic *efab, struct efab_rx_queue *rx_queue ) { int fill_level = rx_queue->write_ptr - rx_queue->read_ptr; int space = EFAB_NUM_RX_DESC - fill_level - 1; int pushed = 0; while ( space ) { int buf_id = rx_queue->write_ptr % EFAB_NUM_RX_DESC; int desc_id = rx_queue->write_ptr % EFAB_RXD_SIZE; struct io_buffer *iob; falcon_rx_desc_t *rxd; assert ( rx_queue->buf[buf_id] == NULL ); iob = alloc_iob ( EFAB_RX_BUF_SIZE ); if ( !iob ) break; EFAB_TRACE ( "pushing rx_buf[%d] iob %p data %p\n", buf_id, iob, iob->data ); rx_queue->buf[buf_id] = iob; rxd = rx_queue->ring + desc_id; falcon_build_rx_desc ( rxd, iob ); ++rx_queue->write_ptr; ++pushed; --space; } if ( pushed ) { /* Push the ptr to hardware */ falcon_notify_rx_desc ( efab, rx_queue ); fill_level = rx_queue->write_ptr - rx_queue->read_ptr; EFAB_TRACE ( "pushed %d rx buffers to fill level %d\n", pushed, fill_level ); } if ( fill_level == 0 ) return -ENOMEM; return 0; } static void efab_receive ( struct efab_nic *efab, unsigned int id, int len, int drop ) { struct efab_rx_queue *rx_queue = &efab->rx_queue; struct io_buffer *iob; unsigned int read_ptr = rx_queue->read_ptr % EFAB_RXD_SIZE; unsigned int buf_ptr = rx_queue->read_ptr % EFAB_NUM_RX_DESC; assert ( id == read_ptr ); /* Pop this rx buffer out of the software ring */ iob = rx_queue->buf[buf_ptr]; rx_queue->buf[buf_ptr] = NULL; EFAB_TRACE ( "popping rx_buf[%d] iob %p data %p with %d bytes %s\n", id, iob, iob->data, len, drop ? "bad" : "ok" ); /* Pass the packet up if required */ if ( drop ) free_iob ( iob ); else { iob_put ( iob, len ); netdev_rx ( efab->netdev, iob ); } ++rx_queue->read_ptr; } /******************************************************************************* * * * Software transmit interface * * *******************************************************************************/ static int efab_transmit ( struct net_device *netdev, struct io_buffer *iob ) { struct efab_nic *efab = netdev_priv ( netdev ); struct efab_tx_queue *tx_queue = &efab->tx_queue; int fill_level, space; falcon_tx_desc_t *txd; int buf_id; fill_level = tx_queue->write_ptr - tx_queue->read_ptr; space = EFAB_TXD_SIZE - fill_level - 1; if ( space < 1 ) return -ENOBUFS; /* Save the iobuffer for later completion */ buf_id = tx_queue->write_ptr % EFAB_TXD_SIZE; assert ( tx_queue->buf[buf_id] == NULL ); tx_queue->buf[buf_id] = iob; EFAB_TRACE ( "tx_buf[%d] for iob %p data %p len %zd\n", buf_id, iob, iob->data, iob_len ( iob ) ); /* Form the descriptor, and push it to hardware */ txd = tx_queue->ring + buf_id; falcon_build_tx_desc ( txd, iob ); ++tx_queue->write_ptr; falcon_notify_tx_desc ( efab, tx_queue ); return 0; } static int efab_transmit_done ( struct efab_nic *efab, int id ) { struct efab_tx_queue *tx_queue = &efab->tx_queue; unsigned int read_ptr, stop; /* Complete all buffers from read_ptr up to and including id */ read_ptr = tx_queue->read_ptr % EFAB_TXD_SIZE; stop = ( id + 1 ) % EFAB_TXD_SIZE; while ( read_ptr != stop ) { struct io_buffer *iob = tx_queue->buf[read_ptr]; assert ( iob ); /* Complete the tx buffer */ if ( iob ) netdev_tx_complete ( efab->netdev, iob ); tx_queue->buf[read_ptr] = NULL; ++tx_queue->read_ptr; read_ptr = tx_queue->read_ptr % EFAB_TXD_SIZE; } return 0; } /******************************************************************************* * * * Hardware event path * * *******************************************************************************/ static void falcon_clear_interrupts ( struct efab_nic *efab ) { efab_dword_t reg; if ( efab->pci_revision == FALCON_REV_B0 ) { /* read the ISR */ falcon_readl( efab, ®, INT_ISR0_B0 ); } else { /* write to the INT_ACK register */ falcon_writel ( efab, 0, FCN_INT_ACK_KER_REG_A1 ); mb(); falcon_readl ( efab, ®, WORK_AROUND_BROKEN_PCI_READS_REG_KER_A1 ); } } static void falcon_handle_event ( struct efab_nic *efab, falcon_event_t *evt ) { int ev_code, desc_ptr, len, drop; /* Decode event */ ev_code = EFAB_QWORD_FIELD ( *evt, FCN_EV_CODE ); switch ( ev_code ) { case FCN_TX_IP_EV_DECODE: desc_ptr = EFAB_QWORD_FIELD ( *evt, FCN_TX_EV_DESC_PTR ); efab_transmit_done ( efab, desc_ptr ); break; case FCN_RX_IP_EV_DECODE: desc_ptr = EFAB_QWORD_FIELD ( *evt, FCN_RX_EV_DESC_PTR ); len = EFAB_QWORD_FIELD ( *evt, FCN_RX_EV_BYTE_CNT ); drop = !EFAB_QWORD_FIELD ( *evt, FCN_RX_EV_PKT_OK ); efab_receive ( efab, desc_ptr, len, drop ); break; default: EFAB_TRACE ( "Unknown event type %d\n", ev_code ); break; } } /******************************************************************************* * * * Software (polling) interrupt handler * * *******************************************************************************/ static void efab_poll ( struct net_device *netdev ) { struct efab_nic *efab = netdev_priv ( netdev ); struct efab_ev_queue *ev_queue = &efab->ev_queue; struct efab_rx_queue *rx_queue = &efab->rx_queue; falcon_event_t *evt; /* Read the event queue by directly looking for events * (we don't even bother to read the eventq write ptr) */ evt = ev_queue->ring + ev_queue->read_ptr; while ( falcon_event_present ( evt ) ) { EFAB_TRACE ( "Event at index 0x%x address %p is " EFAB_QWORD_FMT "\n", ev_queue->read_ptr, evt, EFAB_QWORD_VAL ( *evt ) ); falcon_handle_event ( efab, evt ); /* Clear the event */ EFAB_SET_QWORD ( *evt ); /* Move to the next event. We don't ack the event * queue until the end */ ev_queue->read_ptr = ( ( ev_queue->read_ptr + 1 ) % EFAB_EVQ_SIZE ); evt = ev_queue->ring + ev_queue->read_ptr; } /* Push more buffers if needed */ (void) efab_fill_rx_queue ( efab, rx_queue ); /* Clear any pending interrupts */ falcon_clear_interrupts ( efab ); /* Ack the event queue */ falcon_eventq_read_ack ( efab, ev_queue ); } static void efab_irq ( struct net_device *netdev, int enable ) { struct efab_nic *efab = netdev_priv ( netdev ); struct efab_ev_queue *ev_queue = &efab->ev_queue; switch ( enable ) { case 0: falcon_interrupts ( efab, 0, 0 ); break; case 1: falcon_interrupts ( efab, 1, 0 ); falcon_eventq_read_ack ( efab, ev_queue ); break; case 2: falcon_interrupts ( efab, 1, 1 ); break; } } /******************************************************************************* * * * Software open/close * * *******************************************************************************/ static void efab_free_resources ( struct efab_nic *efab ) { struct efab_ev_queue *ev_queue = &efab->ev_queue; struct efab_rx_queue *rx_queue = &efab->rx_queue; struct efab_tx_queue *tx_queue = &efab->tx_queue; int i; for ( i = 0; i < EFAB_NUM_RX_DESC; i++ ) { if ( rx_queue->buf[i] ) free_iob ( rx_queue->buf[i] ); } for ( i = 0; i < EFAB_TXD_SIZE; i++ ) { if ( tx_queue->buf[i] ) netdev_tx_complete ( efab->netdev, tx_queue->buf[i] ); } if ( rx_queue->ring ) falcon_free_special_buffer ( rx_queue->ring ); if ( tx_queue->ring ) falcon_free_special_buffer ( tx_queue->ring ); if ( ev_queue->ring ) falcon_free_special_buffer ( ev_queue->ring ); memset ( rx_queue, 0, sizeof ( *rx_queue ) ); memset ( tx_queue, 0, sizeof ( *tx_queue ) ); memset ( ev_queue, 0, sizeof ( *ev_queue ) ); /* Ensure subsequent buffer allocations start at id 0 */ efab->buffer_head = 0; } static int efab_alloc_resources ( struct efab_nic *efab ) { struct efab_ev_queue *ev_queue = &efab->ev_queue; struct efab_rx_queue *rx_queue = &efab->rx_queue; struct efab_tx_queue *tx_queue = &efab->tx_queue; size_t bytes; /* Allocate the hardware event queue */ bytes = sizeof ( falcon_event_t ) * EFAB_TXD_SIZE; ev_queue->ring = falcon_alloc_special_buffer ( efab, bytes, &ev_queue->entry ); if ( !ev_queue->ring ) goto fail1; /* Initialise the hardware event queue */ memset ( ev_queue->ring, 0xff, bytes ); /* Allocate the hardware tx queue */ bytes = sizeof ( falcon_tx_desc_t ) * EFAB_TXD_SIZE; tx_queue->ring = falcon_alloc_special_buffer ( efab, bytes, &tx_queue->entry ); if ( ! tx_queue->ring ) goto fail2; /* Allocate the hardware rx queue */ bytes = sizeof ( falcon_rx_desc_t ) * EFAB_RXD_SIZE; rx_queue->ring = falcon_alloc_special_buffer ( efab, bytes, &rx_queue->entry ); if ( ! rx_queue->ring ) goto fail3; return 0; fail3: falcon_free_special_buffer ( tx_queue->ring ); tx_queue->ring = NULL; fail2: falcon_free_special_buffer ( ev_queue->ring ); ev_queue->ring = NULL; fail1: return -ENOMEM; } static int efab_init_mac ( struct efab_nic *efab ) { int count, rc; /* This can take several seconds */ EFAB_LOG ( "Waiting for link..\n" ); for ( count=0; count<5; count++ ) { rc = efab->mac_op->init ( efab ); if ( rc ) { EFAB_ERR ( "Failed reinitialising MAC, error %s\n", strerror ( rc )); return rc; } /* Sleep for 2s to wait for the link to settle, either * because we want to use it, or because we're about * to reset the mac anyway */ sleep ( 2 ); if ( ! efab->link_up ) { EFAB_ERR ( "!\n" ); continue; } EFAB_LOG ( "\n%dMbps %s-duplex\n", ( efab->link_options & LPA_EF_10000 ? 10000 : ( efab->link_options & LPA_EF_1000 ? 1000 : ( efab->link_options & LPA_100 ? 100 : 10 ) ) ), ( efab->link_options & LPA_EF_DUPLEX ? "full" : "half" ) ); /* TODO: Move link state handling to the poll() routine */ netdev_link_up ( efab->netdev ); return 0; } EFAB_ERR ( "timed initialising MAC\n" ); return -ETIMEDOUT; } static void efab_close ( struct net_device *netdev ) { struct efab_nic *efab = netdev_priv ( netdev ); falcon_fini_resources ( efab ); efab_free_resources ( efab ); efab->board_op->fini ( efab ); falcon_reset ( efab ); } static int efab_open ( struct net_device *netdev ) { struct efab_nic *efab = netdev_priv ( netdev ); struct efab_rx_queue *rx_queue = &efab->rx_queue; int rc; rc = falcon_reset ( efab ); if ( rc ) goto fail1; rc = efab->board_op->init ( efab ); if ( rc ) goto fail2; rc = falcon_init_sram ( efab ); if ( rc ) goto fail3; /* Configure descriptor caches before pushing hardware queues */ falcon_setup_nic ( efab ); rc = efab_alloc_resources ( efab ); if ( rc ) goto fail4; falcon_init_resources ( efab ); /* Push rx buffers */ rc = efab_fill_rx_queue ( efab, rx_queue ); if ( rc ) goto fail5; /* Try and bring the interface up */ rc = efab_init_mac ( efab ); if ( rc ) goto fail6; return 0; fail6: fail5: efab_free_resources ( efab ); fail4: fail3: efab->board_op->fini ( efab ); fail2: falcon_reset ( efab ); fail1: return rc; } static struct net_device_operations efab_operations = { .open = efab_open, .close = efab_close, .transmit = efab_transmit, .poll = efab_poll, .irq = efab_irq, }; static void efab_remove ( struct pci_device *pci ) { struct net_device *netdev = pci_get_drvdata ( pci ); struct efab_nic *efab = netdev_priv ( netdev ); if ( efab->membase ) { falcon_reset ( efab ); iounmap ( efab->membase ); efab->membase = NULL; } if ( efab->nvo.nvs ) { unregister_nvo ( &efab->nvo ); efab->nvo.nvs = NULL; } unregister_netdev ( netdev ); netdev_nullify ( netdev ); netdev_put ( netdev ); } static int efab_probe ( struct pci_device *pci, const struct pci_device_id *id ) { struct net_device *netdev; struct efab_nic *efab; unsigned long mmio_start, mmio_len; int rc; /* Create the network adapter */ netdev = alloc_etherdev ( sizeof ( struct efab_nic ) ); if ( ! netdev ) { rc = -ENOMEM; goto fail1; } /* Initialise the network adapter, and initialise private storage */ netdev_init ( netdev, &efab_operations ); pci_set_drvdata ( pci, netdev ); netdev->dev = &pci->dev; efab = netdev_priv ( netdev ); memset ( efab, 0, sizeof ( *efab ) ); efab->netdev = netdev; /* Get iobase/membase */ mmio_start = pci_bar_start ( pci, PCI_BASE_ADDRESS_2 ); mmio_len = pci_bar_size ( pci, PCI_BASE_ADDRESS_2 ); efab->membase = ioremap ( mmio_start, mmio_len ); EFAB_TRACE ( "BAR of %lx bytes at phys %lx mapped at %p\n", mmio_len, mmio_start, efab->membase ); /* Enable the PCI device */ adjust_pci_device ( pci ); efab->iobase = pci->ioaddr & ~3; /* Determine the NIC variant */ falcon_probe_nic_variant ( efab, pci ); /* Read the SPI interface and determine the MAC address, * and the board and phy variant. Hook in the op tables */ rc = falcon_probe_spi ( efab ); if ( rc ) goto fail2; rc = falcon_probe_nvram ( efab ); if ( rc ) goto fail3; memcpy ( netdev->hw_addr, efab->mac_addr, ETH_ALEN ); netdev_link_up ( netdev ); rc = register_netdev ( netdev ); if ( rc ) goto fail4; /* Advertise non-volatile storage */ if ( efab->nvo.nvs ) { rc = register_nvo ( &efab->nvo, netdev_settings ( netdev ) ); if ( rc ) goto fail5; } EFAB_LOG ( "Found %s EtherFabric %s %s revision %d\n", id->name, efab->is_asic ? "ASIC" : "FPGA", efab->phy_10g ? "10G" : "1G", efab->pci_revision ); return 0; fail5: unregister_netdev ( netdev ); fail4: fail3: fail2: iounmap ( efab->membase ); efab->membase = NULL; netdev_put ( netdev ); fail1: return rc; } static struct pci_device_id efab_nics[] = { PCI_ROM(0x1924, 0x0703, "falcon", "EtherFabric Falcon", 0), PCI_ROM(0x1924, 0x0710, "falconb0", "EtherFabric FalconB0", 0), }; struct pci_driver etherfabric_driver __pci_driver = { .ids = efab_nics, .id_count = sizeof ( efab_nics ) / sizeof ( efab_nics[0] ), .probe = efab_probe, .remove = efab_remove, }; /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/pcnet32.c0000664000000000000000000007014112524662415020634 0ustar /************************************************************************** * * pcnet32.c -- Etherboot device driver for the AMD PCnet32 * Written 2003-2003 by Timothy Legge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Portions of this code based on: * pcnet32.c: An AMD PCnet32 ethernet driver for linux: * * (C) 1996-1999 Thomas Bogendoerfer * See Linux Driver for full information * * The transmit and poll functions were written with reference to: * lance.c - LANCE NIC driver for Etherboot written by Ken Yap * * Linux Driver Version 1.27a, 10.02.2002 * * * REVISION HISTORY: * ================ * v1.0 08-06-2003 timlegge Initial port of Linux driver * v1.1 08-23-2003 timlegge Add multicast support * v1.2 01-17-2004 timlegge Initial driver output cleanup * v1.3 03-29-2004 timlegge More driver cleanup * * Indent Options: indent -kr -i8 ***************************************************************************/ FILE_LICENCE ( GPL2_OR_LATER ); #include "etherboot.h" #include "nic.h" #include #include #include "mii.h" /* void hex_dump(const char *data, const unsigned int len); */ /* Etherboot Specific definations */ #define drv_version "v1.3" #define drv_date "03-29-2004" static u32 ioaddr; /* Globally used for the card's io address */ static struct nic_operations pcnet32_operations; #ifdef EDEBUG #define dprintf(x) printf x #else #define dprintf(x) #endif /* Condensed operations for readability. */ #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) /* End Etherboot Specific */ static int cards_found = 0 /* __initdata */ ; #ifdef REMOVE /* FIXME: Remove these they are probably pointless */ /* * VLB I/O addresses */ static unsigned int pcnet32_portlist[] /*__initdata */ = { 0x300, 0x320, 0x340, 0x360, 0 }; static int pcnet32_debug = 1; static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */ static int pcnet32vlb; /* check for VLB cards ? */ static struct net_device *pcnet32_dev; static int max_interrupt_work = 80; static int rx_copybreak = 200; #endif #define PCNET32_PORT_AUI 0x00 #define PCNET32_PORT_10BT 0x01 #define PCNET32_PORT_GPSI 0x02 #define PCNET32_PORT_MII 0x03 #define PCNET32_PORT_PORTSEL 0x03 #define PCNET32_PORT_ASEL 0x04 #define PCNET32_PORT_100 0x40 #define PCNET32_PORT_FD 0x80 #define PCNET32_DMA_MASK 0xffffffff /* * table to translate option values from tulip * to internal options */ static unsigned char options_mapping[] = { PCNET32_PORT_ASEL, /* 0 Auto-select */ PCNET32_PORT_AUI, /* 1 BNC/AUI */ PCNET32_PORT_AUI, /* 2 AUI/BNC */ PCNET32_PORT_ASEL, /* 3 not supported */ PCNET32_PORT_10BT | PCNET32_PORT_FD, /* 4 10baseT-FD */ PCNET32_PORT_ASEL, /* 5 not supported */ PCNET32_PORT_ASEL, /* 6 not supported */ PCNET32_PORT_ASEL, /* 7 not supported */ PCNET32_PORT_ASEL, /* 8 not supported */ PCNET32_PORT_MII, /* 9 MII 10baseT */ PCNET32_PORT_MII | PCNET32_PORT_FD, /* 10 MII 10baseT-FD */ PCNET32_PORT_MII, /* 11 MII (autosel) */ PCNET32_PORT_10BT, /* 12 10BaseT */ PCNET32_PORT_MII | PCNET32_PORT_100, /* 13 MII 100BaseTx */ PCNET32_PORT_MII | PCNET32_PORT_100 | PCNET32_PORT_FD, /* 14 MII 100BaseTx-FD */ PCNET32_PORT_ASEL /* 15 not supported */ }; #define MAX_UNITS 8 /* More are supported, limit only on options */ static int options[MAX_UNITS]; static int full_duplex[MAX_UNITS]; /* * Theory of Operation * * This driver uses the same software structure as the normal lance * driver. So look for a verbose description in lance.c. The differences * to the normal lance driver is the use of the 32bit mode of PCnet32 * and PCnetPCI chips. Because these chips are 32bit chips, there is no * 16MB limitation and we don't need bounce buffers. */ /* * Set the number of Tx and Rx buffers, using Log_2(# buffers). * Reasonable default values are 4 Tx buffers, and 16 Rx buffers. * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4). */ #ifndef PCNET32_LOG_TX_BUFFERS #define PCNET32_LOG_TX_BUFFERS 1 #define PCNET32_LOG_RX_BUFFERS 2 #endif #define TX_RING_SIZE (1 << (PCNET32_LOG_TX_BUFFERS)) #define TX_RING_MOD_MASK (TX_RING_SIZE - 1) /* FIXME: Fix this to allow multiple tx_ring descriptors */ #define TX_RING_LEN_BITS 0x0000 /*PCNET32_LOG_TX_BUFFERS) << 12) */ #define RX_RING_SIZE (1 << (PCNET32_LOG_RX_BUFFERS)) #define RX_RING_MOD_MASK (RX_RING_SIZE - 1) #define RX_RING_LEN_BITS ((PCNET32_LOG_RX_BUFFERS) << 4) #define PKT_BUF_SZ 1544 /* Offsets from base I/O address. */ #define PCNET32_WIO_RDP 0x10 #define PCNET32_WIO_RAP 0x12 #define PCNET32_WIO_RESET 0x14 #define PCNET32_WIO_BDP 0x16 #define PCNET32_DWIO_RDP 0x10 #define PCNET32_DWIO_RAP 0x14 #define PCNET32_DWIO_RESET 0x18 #define PCNET32_DWIO_BDP 0x1C #define PCNET32_TOTAL_SIZE 0x20 /* The PCNET32 Rx and Tx ring descriptors. */ struct pcnet32_rx_head { u32 base; s16 buf_length; s16 status; u32 msg_length; u32 reserved; }; struct pcnet32_tx_head { u32 base; s16 length; s16 status; u32 misc; u32 reserved; }; /* The PCNET32 32-Bit initialization block, described in databook. */ struct pcnet32_init_block { u16 mode; u16 tlen_rlen; u8 phys_addr[6]; u16 reserved; u32 filter[2]; /* Receive and transmit ring base, along with extra bits. */ u32 rx_ring; u32 tx_ring; }; /* PCnet32 access functions */ struct pcnet32_access { u16(*read_csr) (unsigned long, int); void (*write_csr) (unsigned long, int, u16); u16(*read_bcr) (unsigned long, int); void (*write_bcr) (unsigned long, int, u16); u16(*read_rap) (unsigned long); void (*write_rap) (unsigned long, u16); void (*reset) (unsigned long); }; /* Define the TX and RX Descriptors and Rings */ struct { struct pcnet32_tx_head tx_ring[TX_RING_SIZE] __attribute__ ((aligned(16))); struct pcnet32_rx_head rx_ring[RX_RING_SIZE] __attribute__ ((aligned(16))); unsigned char txb[TX_RING_SIZE][PKT_BUF_SZ]; unsigned char rxb[RX_RING_SIZE][PKT_BUF_SZ]; } pcnet32_bufs __shared; /* * The first three fields of pcnet32_private are read by the ethernet device * so we allocate the structure should be allocated by pci_alloc_consistent(). */ #define MII_CNT 4 struct pcnet32_private { struct pcnet32_init_block init_block; struct pci_dev *pci_dev; /* Pointer to the associated pci device structure */ const char *name; /* The saved address of a sent-in-place packet/buffer, for skfree(). */ struct sk_buff *tx_skbuff[TX_RING_SIZE]; struct sk_buff *rx_skbuff[RX_RING_SIZE]; struct pcnet32_access a; unsigned int cur_rx, cur_tx; /* The next free ring entry */ char tx_full; int options; int shared_irq:1, /* shared irq possible */ ltint:1, /* enable TxDone-intr inhibitor */ dxsuflo:1, /* disable transmit stop on uflo */ mii:1; /* mii port available */ struct mii_if_info mii_if; unsigned char phys[MII_CNT]; struct net_device *next; int full_duplex:1; } lpx; static struct pcnet32_private *lp; static int mdio_read(struct nic *nic __unused, int phy_id, int reg_num); #if 0 static void mdio_write(struct nic *nic __unused, int phy_id, int reg_num, int val); #endif enum pci_flags_bit { PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4, PCI_ADDR0 = 0x10 << 0, PCI_ADDR1 = 0x10 << 1, PCI_ADDR2 = 0x10 << 2, PCI_ADDR3 = 0x10 << 3, }; static u16 pcnet32_wio_read_csr(unsigned long addr, int index) { outw(index, addr + PCNET32_WIO_RAP); return inw(addr + PCNET32_WIO_RDP); } static void pcnet32_wio_write_csr(unsigned long addr, int index, u16 val) { outw(index, addr + PCNET32_WIO_RAP); outw(val, addr + PCNET32_WIO_RDP); } static u16 pcnet32_wio_read_bcr(unsigned long addr, int index) { outw(index, addr + PCNET32_WIO_RAP); return inw(addr + PCNET32_WIO_BDP); } static void pcnet32_wio_write_bcr(unsigned long addr, int index, u16 val) { outw(index, addr + PCNET32_WIO_RAP); outw(val, addr + PCNET32_WIO_BDP); } static u16 pcnet32_wio_read_rap(unsigned long addr) { return inw(addr + PCNET32_WIO_RAP); } static void pcnet32_wio_write_rap(unsigned long addr, u16 val) { outw(val, addr + PCNET32_WIO_RAP); } static void pcnet32_wio_reset(unsigned long addr) { inw(addr + PCNET32_WIO_RESET); } static int pcnet32_wio_check(unsigned long addr) { outw(88, addr + PCNET32_WIO_RAP); return (inw(addr + PCNET32_WIO_RAP) == 88); } static struct pcnet32_access pcnet32_wio = { read_csr:pcnet32_wio_read_csr, write_csr:pcnet32_wio_write_csr, read_bcr:pcnet32_wio_read_bcr, write_bcr:pcnet32_wio_write_bcr, read_rap:pcnet32_wio_read_rap, write_rap:pcnet32_wio_write_rap, reset:pcnet32_wio_reset }; static u16 pcnet32_dwio_read_csr(unsigned long addr, int index) { outl(index, addr + PCNET32_DWIO_RAP); return (inl(addr + PCNET32_DWIO_RDP) & 0xffff); } static void pcnet32_dwio_write_csr(unsigned long addr, int index, u16 val) { outl(index, addr + PCNET32_DWIO_RAP); outl(val, addr + PCNET32_DWIO_RDP); } static u16 pcnet32_dwio_read_bcr(unsigned long addr, int index) { outl(index, addr + PCNET32_DWIO_RAP); return (inl(addr + PCNET32_DWIO_BDP) & 0xffff); } static void pcnet32_dwio_write_bcr(unsigned long addr, int index, u16 val) { outl(index, addr + PCNET32_DWIO_RAP); outl(val, addr + PCNET32_DWIO_BDP); } static u16 pcnet32_dwio_read_rap(unsigned long addr) { return (inl(addr + PCNET32_DWIO_RAP) & 0xffff); } static void pcnet32_dwio_write_rap(unsigned long addr, u16 val) { outl(val, addr + PCNET32_DWIO_RAP); } static void pcnet32_dwio_reset(unsigned long addr) { inl(addr + PCNET32_DWIO_RESET); } static int pcnet32_dwio_check(unsigned long addr) { outl(88, addr + PCNET32_DWIO_RAP); return ((inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88); } static struct pcnet32_access pcnet32_dwio = { read_csr:pcnet32_dwio_read_csr, write_csr:pcnet32_dwio_write_csr, read_bcr:pcnet32_dwio_read_bcr, write_bcr:pcnet32_dwio_write_bcr, read_rap:pcnet32_dwio_read_rap, write_rap:pcnet32_dwio_write_rap, reset:pcnet32_dwio_reset }; /* Initialize the PCNET32 Rx and Tx rings. */ static int pcnet32_init_ring(struct nic *nic) { int i; lp->tx_full = 0; lp->cur_rx = lp->cur_tx = 0; for (i = 0; i < RX_RING_SIZE; i++) { pcnet32_bufs.rx_ring[i].base = virt_to_le32desc(&pcnet32_bufs.rxb[i]); pcnet32_bufs.rx_ring[i].buf_length = le16_to_cpu(-PKT_BUF_SZ); pcnet32_bufs.rx_ring[i].status = le16_to_cpu(0x8000); } /* The Tx buffer address is filled in as needed, but we do need to clear the upper ownership bit. */ for (i = 0; i < TX_RING_SIZE; i++) { pcnet32_bufs.tx_ring[i].base = 0; pcnet32_bufs.tx_ring[i].status = 0; } lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS); for (i = 0; i < 6; i++) lp->init_block.phys_addr[i] = nic->node_addr[i]; lp->init_block.rx_ring = virt_to_le32desc(&pcnet32_bufs.rx_ring[0]); lp->init_block.tx_ring = virt_to_le32desc(&pcnet32_bufs.tx_ring[0]); return 0; } /************************************************************************** RESET - Reset adapter ***************************************************************************/ static void pcnet32_reset(struct nic *nic) { /* put the card in its initial state */ u16 val; int i; /* Reset the PCNET32 */ lp->a.reset(ioaddr); /* switch pcnet32 to 32bit mode */ lp->a.write_bcr(ioaddr, 20, 2); /* set/reset autoselect bit */ val = lp->a.read_bcr(ioaddr, 2) & ~2; if (lp->options & PCNET32_PORT_ASEL) val |= 2; lp->a.write_bcr(ioaddr, 2, val); /* handle full duplex setting */ if (lp->full_duplex) { val = lp->a.read_bcr(ioaddr, 9) & ~3; if (lp->options & PCNET32_PORT_FD) { val |= 1; if (lp->options == (PCNET32_PORT_FD | PCNET32_PORT_AUI)) val |= 2; } else if (lp->options & PCNET32_PORT_ASEL) { /* workaround of xSeries250, turn on for 79C975 only */ i = ((lp->a. read_csr(ioaddr, 88) | (lp->a.read_csr(ioaddr, 89) << 16)) >> 12) & 0xffff; if (i == 0x2627) val |= 3; } lp->a.write_bcr(ioaddr, 9, val); } /* set/reset GPSI bit in test register */ val = lp->a.read_csr(ioaddr, 124) & ~0x10; if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI) val |= 0x10; lp->a.write_csr(ioaddr, 124, val); if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) { val = lp->a.read_bcr(ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */ if (lp->options & PCNET32_PORT_FD) val |= 0x10; if (lp->options & PCNET32_PORT_100) val |= 0x08; lp->a.write_bcr(ioaddr, 32, val); } else { if (lp->options & PCNET32_PORT_ASEL) { /* enable auto negotiate, setup, disable fd */ val = lp->a.read_bcr(ioaddr, 32) & ~0x98; val |= 0x20; lp->a.write_bcr(ioaddr, 32, val); } } #ifdef DO_DXSUFLO if (lp->dxsuflo) { /* Disable transmit stop on underflow */ val = lp->a.read_csr(ioaddr, 3); val |= 0x40; lp->a.write_csr(ioaddr, 3, val); } #endif if (1) { //disable interrupts val = lp->a.read_csr(ioaddr, 3); val = val | (1 << 14) //BABLM intr disabled | (1 << 12) //MISSM missed frame mask intr disabled | (1 << 10) //RINTM receive intr disabled | (1 << 9) //TINTM transmit intr disabled | (1 << 8) //IDONM init done intr disabled ; lp->a.write_csr(ioaddr, 3, val); } if (lp->ltint) { /* Enable TxDone-intr inhibitor */ val = lp->a.read_csr(ioaddr, 5); val |= (1 << 14); lp->a.write_csr(ioaddr, 5, val); } lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); lp->init_block.filter[0] = 0xffffffff; lp->init_block.filter[1] = 0xffffffff; pcnet32_init_ring(nic); /* Re-initialize the PCNET32, and start it when done. */ lp->a.write_csr(ioaddr, 1, (virt_to_bus(&lp->init_block)) & 0xffff); lp->a.write_csr(ioaddr, 2, (virt_to_bus(&lp->init_block)) >> 16); lp->a.write_csr(ioaddr, 4, 0x0915); lp->a.write_csr(ioaddr, 0, 0x0001); i = 0; while (i++ < 100) if (lp->a.read_csr(ioaddr, 0) & 0x0100) break; /* * We used to clear the InitDone bit, 0x0100, here but Mark Stockton * reports that doing so triggers a bug in the '974. */ lp->a.write_csr(ioaddr, 0, 0x0042); dprintf(("pcnet32 open, csr0 %hX.\n", lp->a.read_csr(ioaddr, 0))); } /************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int pcnet32_poll(struct nic *nic __unused, int retrieve) { /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ /* nic->packetlen should contain length of data */ signed char status; int entry; entry = lp->cur_rx & RX_RING_MOD_MASK; status = (le16_to_cpu(pcnet32_bufs.rx_ring[entry].status) >> 8); if (status < 0) return 0; if ( ! retrieve ) return 1; if (status == 0x03) { nic->packetlen = (le32_to_cpu(pcnet32_bufs.rx_ring[entry].msg_length) & 0xfff) - 4; memcpy(nic->packet, &pcnet32_bufs.rxb[entry], nic->packetlen); /* Andrew Boyd of QNX reports that some revs of the 79C765 * clear the buffer length */ pcnet32_bufs.rx_ring[entry].buf_length = le16_to_cpu(-PKT_BUF_SZ); /* prime for next receive */ pcnet32_bufs.rx_ring[entry].status |= le16_to_cpu(0x8000); /* Switch to the next Rx ring buffer */ lp->cur_rx++; } else { return 0; } return 1; } /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void pcnet32_transmit(struct nic *nic __unused, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) { /* Packet */ /* send the packet to destination */ unsigned long time; u8 *ptxb; u16 nstype; u16 status; int entry = 0; /*lp->cur_tx & TX_RING_MOD_MASK; */ status = 0x8300; /* point to the current txb incase multiple tx_rings are used */ ptxb = pcnet32_bufs.txb[lp->cur_tx]; /* copy the packet to ring buffer */ memcpy(ptxb, d, ETH_ALEN); /* dst */ memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */ nstype = htons((u16) t); /* type */ memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); /* type */ memcpy(ptxb + ETH_HLEN, p, s); s += ETH_HLEN; while (s < ETH_ZLEN) /* pad to min length */ ptxb[s++] = '\0'; pcnet32_bufs.tx_ring[entry].length = le16_to_cpu(-s); pcnet32_bufs.tx_ring[entry].misc = 0x00000000; pcnet32_bufs.tx_ring[entry].base = (u32) virt_to_le32desc(ptxb); /* we set the top byte as the very last thing */ pcnet32_bufs.tx_ring[entry].status = le16_to_cpu(status); /* Trigger an immediate send poll */ lp->a.write_csr(ioaddr, 0, 0x0048); /* wait for transmit complete */ lp->cur_tx = 0; /* (lp->cur_tx + 1); */ time = currticks() + TICKS_PER_SEC; /* wait one second */ while (currticks() < time && ((short) le16_to_cpu(pcnet32_bufs.tx_ring[entry].status) < 0)); if ((short) le16_to_cpu(pcnet32_bufs.tx_ring[entry].status) < 0) printf("PCNET32 timed out on transmit\n"); /* Stop pointing at the current txb * otherwise the card continues to send the packet */ pcnet32_bufs.tx_ring[entry].base = 0; } /************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void pcnet32_disable ( struct nic *nic __unused ) { /* Stop the PCNET32 here -- it ocassionally polls memory if we don't */ lp->a.write_csr(ioaddr, 0, 0x0004); /* * Switch back to 16-bit mode to avoid problems with dumb * DOS packet driver after a warm reboot */ lp->a.write_bcr(ioaddr, 20, 0); } /************************************************************************** IRQ - Enable, Disable, or Force interrupts ***************************************************************************/ static void pcnet32_irq(struct nic *nic __unused, irq_action_t action __unused) { switch ( action ) { case DISABLE : break; case ENABLE : break; case FORCE : break; } } /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside You should omit the last argument struct pci_device * for a non-PCI NIC ***************************************************************************/ static int pcnet32_probe ( struct nic *nic, struct pci_device *pci ) { int i, media; int fdx, mii, fset, dxsuflo, ltint; int chip_version; struct pcnet32_access *a = NULL; char *chipname; u8 promaddr[6]; int shared = 1; if (pci->ioaddr == 0) return 0; /* BASE is used throughout to address the card */ ioaddr = pci->ioaddr; printf("pcnet32.c: Found %s, Vendor=0x%hX Device=0x%hX\n", pci->driver_name, pci->vendor, pci->device); nic->irqno = 0; nic->ioaddr = pci->ioaddr & ~3; /* reset the chip */ pcnet32_wio_reset(ioaddr); /* NOTE: 16-bit check is first, otherwise some older PCnet chips fail */ if (pcnet32_wio_read_csr(ioaddr, 0) == 4 && pcnet32_wio_check(ioaddr)) { a = &pcnet32_wio; } else { pcnet32_dwio_reset(ioaddr); if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 && pcnet32_dwio_check(ioaddr)) { a = &pcnet32_dwio; } else return 0; } chip_version = a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr, 89) << 16); dprintf(("PCnet chip version is 0x%X\n", chip_version)); if ((chip_version & 0xfff) != 0x003) return 0; /* initialize variables */ fdx = mii = fset = dxsuflo = ltint = 0; chip_version = (chip_version >> 12) & 0xffff; switch (chip_version) { case 0x2420: chipname = "PCnet/PCI 79C970"; /* PCI */ break; case 0x2430: if (shared) chipname = "PCnet/PCI 79C970"; /* 970 gives the wrong chip id back */ else chipname = "PCnet/32 79C965"; /* 486/VL bus */ break; case 0x2621: chipname = "PCnet/PCI II 79C970A"; /* PCI */ fdx = 1; break; case 0x2623: chipname = "PCnet/FAST 79C971"; /* PCI */ fdx = 1; mii = 1; fset = 1; ltint = 1; break; case 0x2624: chipname = "PCnet/FAST+ 79C972"; /* PCI */ fdx = 1; mii = 1; fset = 1; break; case 0x2625: chipname = "PCnet/FAST III 79C973"; /* PCI */ fdx = 1; mii = 1; break; case 0x2626: chipname = "PCnet/Home 79C978"; /* PCI */ fdx = 1; /* * This is based on specs published at www.amd.com. This section * assumes that a card with a 79C978 wants to go into 1Mb HomePNA * mode. The 79C978 can also go into standard ethernet, and there * probably should be some sort of module option to select the * mode by which the card should operate */ /* switch to home wiring mode */ media = a->read_bcr(ioaddr, 49); printf("media reset to %#x.\n", media); a->write_bcr(ioaddr, 49, media); break; case 0x2627: chipname = "PCnet/FAST III 79C975"; /* PCI */ fdx = 1; mii = 1; break; default: chipname = "UNKNOWN"; printf("PCnet version %#x, no PCnet32 chip.\n", chip_version); return 0; } /* * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit * starting until the packet is loaded. Strike one for reliability, lose * one for latency - although on PCI this isnt a big loss. Older chips * have FIFO's smaller than a packet, so you can't do this. */ if (fset) { a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0800)); a->write_csr(ioaddr, 80, (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00); dxsuflo = 1; ltint = 1; } DBG ( "%s at %hX,", chipname, (unsigned int) ioaddr ); /* read PROM address */ for (i = 0; i < 6; i++) promaddr[i] = inb(ioaddr + i); /* Update the nic structure with the MAC Address */ for (i = 0; i < ETH_ALEN; i++) { nic->node_addr[i] = promaddr[i]; } /* Print out some hardware info */ DBG ( "%s: IO Addr 0x%hX, MAC Addr %s\n ", chipname, (unsigned int) ioaddr, eth_ntoa ( nic->node_addr ) ); /* Set to pci bus master */ adjust_pci_device(pci); /* point to private storage */ lp = &lpx; #if EBDEBUG if (((chip_version + 1) & 0xfffe) == 0x2624) { /* Version 0x2623 or 0x2624 */ i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */ dprintf((" tx_start_pt(0x%hX):", i)); switch (i >> 10) { case 0: dprintf((" 20 bytes,")); break; case 1: dprintf((" 64 bytes,")); break; case 2: dprintf((" 128 bytes,")); break; case 3: dprintf(("~220 bytes,")); break; } i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */ dprintf((" BCR18(%hX):", i & 0xffff)); if (i & (1 << 5)) dprintf(("BurstWrEn ")); if (i & (1 << 6)) dprintf(("BurstRdEn ")); if (i & (1 << 7)) dprintf(("DWordIO ")); if (i & (1 << 11)) dprintf(("NoUFlow ")); i = a->read_bcr(ioaddr, 25); dprintf((" SRAMSIZE=0x%hX,", i << 8)); i = a->read_bcr(ioaddr, 26); dprintf((" SRAM_BND=0x%hX,", i << 8)); i = a->read_bcr(ioaddr, 27); if (i & (1 << 14)) dprintf(("LowLatRx")); } #endif lp->name = chipname; lp->shared_irq = shared; lp->full_duplex = fdx; lp->dxsuflo = dxsuflo; lp->ltint = ltint; lp->mii = mii; /* FIXME: Fix Options for only one card */ if ((cards_found >= MAX_UNITS) || ((unsigned int) options[cards_found] > sizeof(options_mapping))) lp->options = PCNET32_PORT_ASEL; else lp->options = options_mapping[options[cards_found]]; if (fdx && !(lp->options & PCNET32_PORT_ASEL) && ((cards_found >= MAX_UNITS) || full_duplex[cards_found])) lp->options |= PCNET32_PORT_FD; if (!a) { printf("No access methods\n"); return 0; } // lp->a = *a; // Causes a loader: // bin/blib.a(pcnet32.o)(.text+0x6b6): In function `pcnet32_probe': // drivers/net/pcnet32.c:871: undefined reference to `memcpy' // make: *** [bin/pcnet32.dsk.tmp] Error 1 // So we do: memcpy ( &lp->a, a, sizeof ( lp->a ) ); // To explicity call memcpy. /* detect special T1/E1 WAN card by checking for MAC address */ if (nic->node_addr[0] == 0x00 && nic->node_addr[1] == 0xe0 && nic->node_addr[2] == 0x75) lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI; lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */ lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS); for (i = 0; i < 6; i++) lp->init_block.phys_addr[i] = nic->node_addr[i]; lp->init_block.filter[0] = 0xffffffff; lp->init_block.filter[1] = 0xffffffff; lp->init_block.rx_ring = virt_to_bus(&pcnet32_bufs.rx_ring); lp->init_block.tx_ring = virt_to_bus(&pcnet32_bufs.tx_ring); /* switch pcnet32 to 32bit mode */ a->write_bcr(ioaddr, 20, 2); a->write_csr(ioaddr, 1, (virt_to_bus(&lp->init_block)) & 0xffff); a->write_csr(ioaddr, 2, (virt_to_bus(&lp->init_block)) >> 16); /* * To auto-IRQ we enable the initialization-done and DMA error * interrupts. For ISA boards we get a DMA error, but VLB and PCI * boards will work. */ /* Trigger an initialization just for the interrupt. */ // a->write_csr(ioaddr, 0, 0x41); // mdelay(1); cards_found++; /* point to NIC specific routines */ pcnet32_reset(nic); if (mii) { int tmp; int phy, phy_idx = 0; u16 mii_lpa; lp->phys[0] = 1; /* Default Setting */ for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) { int mii_status = mdio_read(nic, phy, MII_BMSR); if (mii_status != 0xffff && mii_status != 0x0000) { lp->phys[phy_idx++] = phy; lp->mii_if.advertising = mdio_read(nic, phy, MII_ADVERTISE); if ((mii_status & 0x0040) == 0) { tmp = phy; dprintf (("MII PHY found at address %d, status " "%hX advertising %hX\n", phy, mii_status, lp->mii_if.advertising)); } } } if (phy_idx == 0) printf("No MII transceiver found!\n"); lp->mii_if.phy_id = lp->phys[0]; lp->mii_if.advertising = mdio_read(nic, lp->phys[0], MII_ADVERTISE); mii_lpa = mdio_read(nic, lp->phys[0], MII_LPA); lp->mii_if.advertising &= mii_lpa; if (lp->mii_if.advertising & ADVERTISE_100FULL) printf("100Mbps Full-Duplex\n"); else if (lp->mii_if.advertising & ADVERTISE_100HALF) printf("100Mbps Half-Duplex\n"); else if (lp->mii_if.advertising & ADVERTISE_10FULL) printf("10Mbps Full-Duplex\n"); else if (lp->mii_if.advertising & ADVERTISE_10HALF) printf("10Mbps Half-Duplex\n"); else printf("\n"); } else { /* The older chips are fixed 10Mbps, and some support full duplex, * although not via autonegotiation, but only via configuration. */ if (fdx) printf("10Mbps Full-Duplex\n"); else printf("10Mbps Half-Duplex\n"); } nic->nic_op = &pcnet32_operations; return 1; } static int mdio_read(struct nic *nic __unused, int phy_id, int reg_num) { u16 val_out; int phyaddr; if (!lp->mii) return 0; phyaddr = lp->a.read_bcr(ioaddr, 33); lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f)); val_out = lp->a.read_bcr(ioaddr, 34); lp->a.write_bcr(ioaddr, 33, phyaddr); return val_out; } #if 0 static void mdio_write(struct nic *nic __unused, int phy_id, int reg_num, int val) { int phyaddr; if (!lp->mii) return; phyaddr = lp->a.read_bcr(ioaddr, 33); lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f)); lp->a.write_bcr(ioaddr, 34, val); lp->a.write_bcr(ioaddr, 33, phyaddr); } #endif static struct nic_operations pcnet32_operations = { .connect = dummy_connect, .poll = pcnet32_poll, .transmit = pcnet32_transmit, .irq = pcnet32_irq, }; static struct pci_device_id pcnet32_nics[] = { PCI_ROM(0x1022, 0x2000, "pcnet32", "AMD PCnet/PCI", 0), PCI_ROM(0x1022, 0x2625, "pcnetfastiii", "AMD PCNet FAST III", 0), PCI_ROM(0x1022, 0x2001, "amdhomepna", "AMD PCnet/HomePNA", 0), }; PCI_DRIVER ( pcnet32_driver, pcnet32_nics, PCI_NO_CLASS ); DRIVER ( "PCNET32/PCI", nic_driver, pci_driver, pcnet32_driver, pcnet32_probe, pcnet32_disable ); /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/net/r8169.c0000664000000000000000000015330212524662415020150 0ustar /* * Copyright (c) 2008 Marty Connor * Copyright (c) 2008 Entity Cyber, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * This driver is based on rtl8169 data sheets and work by: * * Copyright (c) 2002 ShuChen * Copyright (c) 2003 - 2007 Francois Romieu * Copyright (c) a lot of people too. Please respect their work. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "r8169.h" /*** Low level hardware routines ***/ static void mdio_write(void *ioaddr, int reg_addr, int value) { int i; DBGP ( "mdio_write\n" ); RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff)); for (i = 20; i > 0; i--) { /* * Check if the RTL8169 has completed writing to the specified * MII register. */ if (!(RTL_R32(PHYAR) & 0x80000000)) break; udelay(25); } } static int mdio_read(void *ioaddr, int reg_addr) { int i, value = -1; DBGP ( "mdio_read\n" ); RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16); for (i = 20; i > 0; i--) { /* * Check if the RTL8169 has completed retrieving data from * the specified MII register. */ if (RTL_R32(PHYAR) & 0x80000000) { value = RTL_R32(PHYAR) & 0xffff; break; } udelay(25); } return value; } static void mdio_patch(void *ioaddr, int reg_addr, int value) { DBGP ( "mdio_patch\n" ); mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value); } static void rtl_ephy_write(void *ioaddr, int reg_addr, int value) { unsigned int i; DBGP ( "rtl_ephy_write\n" ); RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) | (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); for (i = 0; i < 100; i++) { if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG)) break; udelay(10); } } static u16 rtl_ephy_read(void *ioaddr, int reg_addr) { u16 value = 0xffff; unsigned int i; DBGP ( "rtl_ephy_read\n" ); RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); for (i = 0; i < 100; i++) { if (RTL_R32(EPHYAR) & EPHYAR_FLAG) { value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK; break; } udelay(10); } return value; } static void rtl_csi_write(void *ioaddr, int addr, int value) { unsigned int i; DBGP ( "rtl_csi_write\n" ); RTL_W32(CSIDR, value); RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) | CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); for (i = 0; i < 100; i++) { if (!(RTL_R32(CSIAR) & CSIAR_FLAG)) break; udelay(10); } } static u32 rtl_csi_read(void *ioaddr, int addr) { u32 value = ~0x00; unsigned int i; DBGP ( "rtl_csi_read\n" ); RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) | CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); for (i = 0; i < 100; i++) { if (RTL_R32(CSIAR) & CSIAR_FLAG) { value = RTL_R32(CSIDR); break; } udelay(10); } return value; } static void rtl8169_irq_mask_and_ack(void *ioaddr) { DBGP ( "rtl8169_irq_mask_and_ack\n" ); RTL_W16(IntrMask, 0x0000); RTL_W16(IntrStatus, 0xffff); } static unsigned int rtl8169_tbi_reset_pending(void *ioaddr) { DBGP ( "rtl8169_tbi_reset_pending\n" ); return RTL_R32(TBICSR) & TBIReset; } static unsigned int rtl8169_xmii_reset_pending(void *ioaddr) { DBGP ( "rtl8169_xmii_reset_pending\n" ); return mdio_read(ioaddr, MII_BMCR) & BMCR_RESET; } static unsigned int rtl8169_tbi_link_ok(void *ioaddr) { DBGP ( "rtl8169_tbi_link_ok\n" ); return RTL_R32(TBICSR) & TBILinkOk; } static unsigned int rtl8169_xmii_link_ok(void *ioaddr) { DBGP ( "rtl8169_xmii_link_ok\n" ); return RTL_R8(PHYstatus) & LinkStatus; } static void rtl8169_tbi_reset_enable(void *ioaddr) { DBGP ( "rtl8169_tbi_reset_enable\n" ); RTL_W32(TBICSR, RTL_R32(TBICSR) | TBIReset); } static void rtl8169_xmii_reset_enable(void *ioaddr) { unsigned int val; DBGP ( "rtl8169_xmii_reset_enable\n" ); val = mdio_read(ioaddr, MII_BMCR) | BMCR_RESET; mdio_write(ioaddr, MII_BMCR, val & 0xffff); } static int rtl8169_set_speed_tbi(struct net_device *dev, u8 autoneg, u16 speed, u8 duplex) { struct rtl8169_private *tp = netdev_priv(dev); void *ioaddr = tp->mmio_addr; int ret = 0; u32 reg; DBGP ( "rtl8169_set_speed_tbi\n" ); reg = RTL_R32(TBICSR); if ((autoneg == AUTONEG_DISABLE) && (speed == SPEED_1000) && (duplex == DUPLEX_FULL)) { RTL_W32(TBICSR, reg & ~(TBINwEnable | TBINwRestart)); } else if (autoneg == AUTONEG_ENABLE) RTL_W32(TBICSR, reg | TBINwEnable | TBINwRestart); else { DBG ( "incorrect speed setting refused in TBI mode\n" ); ret = -EOPNOTSUPP; } return ret; } static int rtl8169_set_speed_xmii(struct net_device *dev, u8 autoneg, u16 speed, u8 duplex) { struct rtl8169_private *tp = netdev_priv(dev); void *ioaddr = tp->mmio_addr; int auto_nego, giga_ctrl; DBGP ( "rtl8169_set_speed_xmii\n" ); auto_nego = mdio_read(ioaddr, MII_ADVERTISE); auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | ADVERTISE_100FULL); giga_ctrl = mdio_read(ioaddr, MII_CTRL1000); giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); if (autoneg == AUTONEG_ENABLE) { auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | ADVERTISE_100FULL); giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; } else { if (speed == SPEED_10) auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL; else if (speed == SPEED_100) auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL; else if (speed == SPEED_1000) giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; if (duplex == DUPLEX_HALF) auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL); if (duplex == DUPLEX_FULL) auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF); /* This tweak comes straight from Realtek's driver. */ if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) && ((tp->mac_version == RTL_GIGA_MAC_VER_13) || (tp->mac_version == RTL_GIGA_MAC_VER_16))) { auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA; } } /* The 8100e/8101e/8102e do Fast Ethernet only. */ if ((tp->mac_version == RTL_GIGA_MAC_VER_07) || (tp->mac_version == RTL_GIGA_MAC_VER_08) || (tp->mac_version == RTL_GIGA_MAC_VER_09) || (tp->mac_version == RTL_GIGA_MAC_VER_10) || (tp->mac_version == RTL_GIGA_MAC_VER_13) || (tp->mac_version == RTL_GIGA_MAC_VER_14) || (tp->mac_version == RTL_GIGA_MAC_VER_15) || (tp->mac_version == RTL_GIGA_MAC_VER_16)) { if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF))) { DBG ( "PHY does not support 1000Mbps.\n" ); } giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); } auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; if ((tp->mac_version == RTL_GIGA_MAC_VER_11) || (tp->mac_version == RTL_GIGA_MAC_VER_12) || (tp->mac_version >= RTL_GIGA_MAC_VER_17)) { /* * Wake up the PHY. * Vendor specific (0x1f) and reserved (0x0e) MII registers. */ mdio_write(ioaddr, 0x1f, 0x0000); mdio_write(ioaddr, 0x0e, 0x0000); } tp->phy_auto_nego_reg = auto_nego; tp->phy_1000_ctrl_reg = giga_ctrl; mdio_write(ioaddr, MII_ADVERTISE, auto_nego); mdio_write(ioaddr, MII_CTRL1000, giga_ctrl); mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); return 0; } static int rtl8169_set_speed(struct net_device *dev, u8 autoneg, u16 speed, u8 duplex) { struct rtl8169_private *tp = netdev_priv(dev); int ret; DBGP ( "rtl8169_set_speed\n" ); ret = tp->set_speed(dev, autoneg, speed, duplex); return ret; } static void rtl8169_write_gmii_reg_bit(void *ioaddr, int reg, int bitnum, int bitval) { int val; DBGP ( "rtl8169_write_gmii_reg_bit\n" ); val = mdio_read(ioaddr, reg); val = (bitval == 1) ? val | (bitval << bitnum) : val & ~(0x0001 << bitnum); mdio_write(ioaddr, reg, val & 0xffff); } static void rtl8169_get_mac_version(struct rtl8169_private *tp, void *ioaddr) { /* * The driver currently handles the 8168Bf and the 8168Be identically * but they can be identified more specifically through the test below * if needed: * * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be * * Same thing for the 8101Eb and the 8101Ec: * * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec */ const struct { u32 mask; u32 val; int mac_version; } mac_info[] = { /* 8168D family. */ { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_25 }, /* 8168C family. */ { 0x7cf00000, 0x3ca00000, RTL_GIGA_MAC_VER_24 }, { 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 }, { 0x7cf00000, 0x3c800000, RTL_GIGA_MAC_VER_18 }, { 0x7c800000, 0x3c800000, RTL_GIGA_MAC_VER_24 }, { 0x7cf00000, 0x3c000000, RTL_GIGA_MAC_VER_19 }, { 0x7cf00000, 0x3c200000, RTL_GIGA_MAC_VER_20 }, { 0x7cf00000, 0x3c300000, RTL_GIGA_MAC_VER_21 }, { 0x7cf00000, 0x3c400000, RTL_GIGA_MAC_VER_22 }, { 0x7c800000, 0x3c000000, RTL_GIGA_MAC_VER_22 }, /* 8168B family. */ { 0x7cf00000, 0x38000000, RTL_GIGA_MAC_VER_12 }, { 0x7cf00000, 0x38500000, RTL_GIGA_MAC_VER_17 }, { 0x7c800000, 0x38000000, RTL_GIGA_MAC_VER_17 }, { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, /* 8101 family. */ { 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 }, { 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 }, { 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 }, { 0x7cf00000, 0x24900000, RTL_GIGA_MAC_VER_08 }, { 0x7cf00000, 0x34800000, RTL_GIGA_MAC_VER_07 }, { 0x7cf00000, 0x24800000, RTL_GIGA_MAC_VER_07 }, { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 }, { 0x7cf00000, 0x34300000, RTL_GIGA_MAC_VER_10 }, { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 }, { 0x7c800000, 0x34800000, RTL_GIGA_MAC_VER_09 }, { 0x7c800000, 0x24800000, RTL_GIGA_MAC_VER_09 }, { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 }, /* FIXME: where did these entries come from ? -- FR */ { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 }, { 0xfc800000, 0x30800000, RTL_GIGA_MAC_VER_14 }, /* 8110 family. */ { 0xfc800000, 0x98000000, RTL_GIGA_MAC_VER_06 }, { 0xfc800000, 0x18000000, RTL_GIGA_MAC_VER_05 }, { 0xfc800000, 0x10000000, RTL_GIGA_MAC_VER_04 }, { 0xfc800000, 0x04000000, RTL_GIGA_MAC_VER_03 }, { 0xfc800000, 0x00800000, RTL_GIGA_MAC_VER_02 }, { 0xfc800000, 0x00000000, RTL_GIGA_MAC_VER_01 }, { 0x00000000, 0x00000000, RTL_GIGA_MAC_VER_01 } /* Catch-all */ }, *p = mac_info; u32 reg; DBGP ( "rtl8169_get_mac_version\n" ); reg = RTL_R32(TxConfig); while ((reg & p->mask) != p->val) p++; tp->mac_version = p->mac_version; DBG ( "tp->mac_version = %d\n", tp->mac_version ); if (p->mask == 0x00000000) { DBG ( "unknown MAC (%08x)\n", reg ); } } struct phy_reg { u16 reg; u16 val; }; static void rtl_phy_write(void *ioaddr, struct phy_reg *regs, int len) { DBGP ( "rtl_phy_write\n" ); while (len-- > 0) { mdio_write(ioaddr, regs->reg, regs->val); regs++; } } static void rtl8169s_hw_phy_config(void *ioaddr) { struct { u16 regs[5]; /* Beware of bit-sign propagation */ } phy_magic[5] = { { { 0x0000, //w 4 15 12 0 0x00a1, //w 3 15 0 00a1 0x0008, //w 2 15 0 0008 0x1020, //w 1 15 0 1020 0x1000 } },{ //w 0 15 0 1000 { 0x7000, //w 4 15 12 7 0xff41, //w 3 15 0 ff41 0xde60, //w 2 15 0 de60 0x0140, //w 1 15 0 0140 0x0077 } },{ //w 0 15 0 0077 { 0xa000, //w 4 15 12 a 0xdf01, //w 3 15 0 df01 0xdf20, //w 2 15 0 df20 0xff95, //w 1 15 0 ff95 0xfa00 } },{ //w 0 15 0 fa00 { 0xb000, //w 4 15 12 b 0xff41, //w 3 15 0 ff41 0xde20, //w 2 15 0 de20 0x0140, //w 1 15 0 0140 0x00bb } },{ //w 0 15 0 00bb { 0xf000, //w 4 15 12 f 0xdf01, //w 3 15 0 df01 0xdf20, //w 2 15 0 df20 0xff95, //w 1 15 0 ff95 0xbf00 } //w 0 15 0 bf00 } }, *p = phy_magic; unsigned int i; DBGP ( "rtl8169s_hw_phy_config\n" ); mdio_write(ioaddr, 0x1f, 0x0001); //w 31 2 0 1 mdio_write(ioaddr, 0x15, 0x1000); //w 21 15 0 1000 mdio_write(ioaddr, 0x18, 0x65c7); //w 24 15 0 65c7 rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0 for (i = 0; i < ARRAY_SIZE(phy_magic); i++, p++) { int val, pos = 4; val = (mdio_read(ioaddr, pos) & 0x0fff) | (p->regs[0] & 0xffff); mdio_write(ioaddr, pos, val); while (--pos >= 0) mdio_write(ioaddr, pos, p->regs[4 - pos] & 0xffff); rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 1); //w 4 11 11 1 rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0 } mdio_write(ioaddr, 0x1f, 0x0000); //w 31 2 0 0 } static void rtl8169sb_hw_phy_config(void *ioaddr) { struct phy_reg phy_reg_init[] = { { 0x1f, 0x0002 }, { 0x01, 0x90d0 }, { 0x1f, 0x0000 } }; DBGP ( "rtl8169sb_hw_phy_config\n" ); rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } static void rtl8168bb_hw_phy_config(void *ioaddr) { struct phy_reg phy_reg_init[] = { { 0x10, 0xf41b }, { 0x1f, 0x0000 } }; mdio_write(ioaddr, 0x1f, 0x0001); mdio_patch(ioaddr, 0x16, 1 << 0); DBGP ( "rtl8168bb_hw_phy_config\n" ); rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } static void rtl8168bef_hw_phy_config(void *ioaddr) { struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, { 0x10, 0xf41b }, { 0x1f, 0x0000 } }; DBGP ( "rtl8168bef_hw_phy_config\n" ); rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } static void rtl8168cp_1_hw_phy_config(void *ioaddr) { struct phy_reg phy_reg_init[] = { { 0x1f, 0x0000 }, { 0x1d, 0x0f00 }, { 0x1f, 0x0002 }, { 0x0c, 0x1ec8 }, { 0x1f, 0x0000 } }; DBGP ( "rtl8168cp_1_hw_phy_config\n" ); rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } static void rtl8168cp_2_hw_phy_config(void *ioaddr) { struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, { 0x1d, 0x3d98 }, { 0x1f, 0x0000 } }; DBGP ( "rtl8168cp_2_hw_phy_config\n" ); mdio_write(ioaddr, 0x1f, 0x0000); mdio_patch(ioaddr, 0x14, 1 << 5); mdio_patch(ioaddr, 0x0d, 1 << 5); rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } static void rtl8168c_1_hw_phy_config(void *ioaddr) { struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, { 0x12, 0x2300 }, { 0x1f, 0x0002 }, { 0x00, 0x88d4 }, { 0x01, 0x82b1 }, { 0x03, 0x7002 }, { 0x08, 0x9e30 }, { 0x09, 0x01f0 }, { 0x0a, 0x5500 }, { 0x0c, 0x00c8 }, { 0x1f, 0x0003 }, { 0x12, 0xc096 }, { 0x16, 0x000a }, { 0x1f, 0x0000 }, { 0x1f, 0x0000 }, { 0x09, 0x2000 }, { 0x09, 0x0000 } }; DBGP ( "rtl8168c_1_hw_phy_config\n" ); rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); mdio_patch(ioaddr, 0x14, 1 << 5); mdio_patch(ioaddr, 0x0d, 1 << 5); mdio_write(ioaddr, 0x1f, 0x0000); } static void rtl8168c_2_hw_phy_config(void *ioaddr) { struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, { 0x12, 0x2300 }, { 0x03, 0x802f }, { 0x02, 0x4f02 }, { 0x01, 0x0409 }, { 0x00, 0xf099 }, { 0x04, 0x9800 }, { 0x04, 0x9000 }, { 0x1d, 0x3d98 }, { 0x1f, 0x0002 }, { 0x0c, 0x7eb8 }, { 0x06, 0x0761 }, { 0x1f, 0x0003 }, { 0x16, 0x0f0a }, { 0x1f, 0x0000 } }; DBGP ( "rtl8168c_2_hw_phy_config\n" ); rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); mdio_patch(ioaddr, 0x16, 1 << 0); mdio_patch(ioaddr, 0x14, 1 << 5); mdio_patch(ioaddr, 0x0d, 1 << 5); mdio_write(ioaddr, 0x1f, 0x0000); } static void rtl8168c_3_hw_phy_config(void *ioaddr) { struct phy_reg phy_reg_init[] = { { 0x1f, 0x0001 }, { 0x12, 0x2300 }, { 0x1d, 0x3d98 }, { 0x1f, 0x0002 }, { 0x0c, 0x7eb8 }, { 0x06, 0x5461 }, { 0x1f, 0x0003 }, { 0x16, 0x0f0a }, { 0x1f, 0x0000 } }; DBGP ( "rtl8168c_3_hw_phy_config\n" ); rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); mdio_patch(ioaddr, 0x16, 1 << 0); mdio_patch(ioaddr, 0x14, 1 << 5); mdio_patch(ioaddr, 0x0d, 1 << 5); mdio_write(ioaddr, 0x1f, 0x0000); } static void rtl8168c_4_hw_phy_config(void *ioaddr) { DBGP ( "rtl8168c_4_hw_phy_config\n" ); rtl8168c_3_hw_phy_config(ioaddr); } static void rtl8168d_hw_phy_config(void *ioaddr) { struct phy_reg phy_reg_init_0[] = { { 0x1f, 0x0001 }, { 0x09, 0x2770 }, { 0x08, 0x04d0 }, { 0x0b, 0xad15 }, { 0x0c, 0x5bf0 }, { 0x1c, 0xf101 }, { 0x1f, 0x0003 }, { 0x14, 0x94d7 }, { 0x12, 0xf4d6 }, { 0x09, 0xca0f }, { 0x1f, 0x0002 }, { 0x0b, 0x0b10 }, { 0x0c, 0xd1f7 }, { 0x1f, 0x0002 }, { 0x06, 0x5461 }, { 0x1f, 0x0002 }, { 0x05, 0x6662 }, { 0x1f, 0x0000 }, { 0x14, 0x0060 }, { 0x1f, 0x0000 }, { 0x0d, 0xf8a0 }, { 0x1f, 0x0005 }, { 0x05, 0xffc2 } }; DBGP ( "rtl8168d_hw_phy_config\n" ); rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); if (mdio_read(ioaddr, 0x06) == 0xc400) { struct phy_reg phy_reg_init_1[] = { { 0x1f, 0x0005 }, { 0x01, 0x0300 }, { 0x1f, 0x0000 }, { 0x11, 0x401c }, { 0x16, 0x4100 }, { 0x1f, 0x0005 }, { 0x07, 0x0010 }, { 0x05, 0x83dc }, { 0x06, 0x087d }, { 0x05, 0x8300 }, { 0x06, 0x0101 }, { 0x06, 0x05f8 }, { 0x06, 0xf9fa }, { 0x06, 0xfbef }, { 0x06, 0x79e2 }, { 0x06, 0x835f }, { 0x06, 0xe0f8 }, { 0x06, 0x9ae1 }, { 0x06, 0xf89b }, { 0x06, 0xef31 }, { 0x06, 0x3b65 }, { 0x06, 0xaa07 }, { 0x06, 0x81e4 }, { 0x06, 0xf89a }, { 0x06, 0xe5f8 }, { 0x06, 0x9baf }, { 0x06, 0x06ae }, { 0x05, 0x83dc }, { 0x06, 0x8300 }, }; rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1)); } mdio_write(ioaddr, 0x1f, 0x0000); } static void rtl8102e_hw_phy_config(void *ioaddr) { struct phy_reg phy_reg_init[] = { { 0x1f, 0x0003 }, { 0x08, 0x441d }, { 0x01, 0x9100 }, { 0x1f, 0x0000 } }; DBGP ( "rtl8102e_hw_phy_config\n" ); mdio_write(ioaddr, 0x1f, 0x0000); mdio_patch(ioaddr, 0x11, 1 << 12); mdio_patch(ioaddr, 0x19, 1 << 13); rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } static void rtl_hw_phy_config(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void *ioaddr = tp->mmio_addr; DBGP ( "rtl_hw_phy_config\n" ); DBG ( "mac_version = 0x%02x\n", tp->mac_version ); switch (tp->mac_version) { case RTL_GIGA_MAC_VER_01: break; case RTL_GIGA_MAC_VER_02: case RTL_GIGA_MAC_VER_03: rtl8169s_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_04: rtl8169sb_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_07: case RTL_GIGA_MAC_VER_08: case RTL_GIGA_MAC_VER_09: rtl8102e_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_11: rtl8168bb_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_12: rtl8168bef_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_17: rtl8168bef_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_18: rtl8168cp_1_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_19: rtl8168c_1_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_20: rtl8168c_2_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_21: rtl8168c_3_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_22: rtl8168c_4_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_23: case RTL_GIGA_MAC_VER_24: rtl8168cp_2_hw_phy_config(ioaddr); break; case RTL_GIGA_MAC_VER_25: rtl8168d_hw_phy_config(ioaddr); break; default: break; } } static void rtl8169_phy_reset(struct net_device *dev __unused, struct rtl8169_private *tp) { void *ioaddr = tp->mmio_addr; unsigned int i; DBGP ( "rtl8169_phy_reset\n" ); tp->phy_reset_enable(ioaddr); for (i = 0; i < 100; i++) { if (!tp->phy_reset_pending(ioaddr)) return; mdelay ( 1 ); } DBG ( "PHY reset failed.\n" ); } static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) { void *ioaddr = tp->mmio_addr; DBGP ( "rtl8169_init_phy\n" ); rtl_hw_phy_config(dev); if (tp->mac_version <= RTL_GIGA_MAC_VER_06) { DBG ( "Set MAC Reg C+CR Offset 0x82h = 0x01h\n" ); RTL_W8(0x82, 0x01); } pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); if (tp->mac_version <= RTL_GIGA_MAC_VER_06) pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08); if (tp->mac_version == RTL_GIGA_MAC_VER_02) { DBG ( "Set MAC Reg C+CR Offset 0x82h = 0x01h\n" ); RTL_W8(0x82, 0x01); DBG ( "Set PHY Reg 0x0bh = 0x00h\n" ); mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0 } rtl8169_phy_reset(dev, tp); /* * rtl8169_set_speed_xmii takes good care of the Fast Ethernet * only 8101. Don't panic. */ rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL); if ((RTL_R8(PHYstatus) & TBI_Enable)) DBG ( "TBI auto-negotiating\n" ); } static const struct rtl_cfg_info { void (*hw_start)(struct net_device *); unsigned int region; unsigned int align; u16 intr_event; u16 napi_event; unsigned features; } rtl_cfg_infos [] = { [RTL_CFG_0] = { .hw_start = rtl_hw_start_8169, .region = 1, .align = 0, .intr_event = SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, .features = RTL_FEATURE_GMII }, [RTL_CFG_1] = { .hw_start = rtl_hw_start_8168, .region = 2, .align = 8, .intr_event = SYSErr | LinkChg | RxOverflow | TxErr | TxOK | RxOK | RxErr, .napi_event = TxErr | TxOK | RxOK | RxOverflow, .features = RTL_FEATURE_GMII }, [RTL_CFG_2] = { .hw_start = rtl_hw_start_8101, .region = 2, .align = 8, .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, } }; static void rtl8169_hw_reset(void *ioaddr) { DBGP ( "rtl8169_hw_reset\n" ); /* Disable interrupts */ rtl8169_irq_mask_and_ack(ioaddr); /* Reset the chipset */ RTL_W8(ChipCmd, CmdReset); /* PCI commit */ RTL_R8(ChipCmd); } static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) { void *ioaddr = tp->mmio_addr; u32 cfg = rtl8169_rx_config; DBGP ( "rtl_set_rx_tx_config_registers\n" ); cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); RTL_W32(RxConfig, cfg); /* Set DMA burst size and Interframe Gap Time */ RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | (InterFrameGap << TxInterFrameGapShift)); } static void rtl_soft_reset ( struct net_device *dev ) { struct rtl8169_private *tp = netdev_priv(dev); void *ioaddr = tp->mmio_addr; unsigned int i; DBGP ( "rtl_hw_soft_reset\n" ); /* Soft reset the chip. */ RTL_W8(ChipCmd, CmdReset); /* Check that the chip has finished the reset. */ for (i = 0; i < 100; i++) { if ((RTL_R8(ChipCmd) & CmdReset) == 0) break; mdelay ( 1 ); } if ( i == 100 ) { DBG ( "Reset Failed! (> 100 iterations)\n" ); } } static void rtl_hw_start ( struct net_device *dev ) { struct rtl8169_private *tp = netdev_priv ( dev ); DBGP ( "rtl_hw_start\n" ); /* Soft reset NIC */ rtl_soft_reset ( dev ); tp->hw_start ( dev ); } static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp, void *ioaddr) { DBGP ( "rtl_set_rx_tx_desc_registers\n" ); /* * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh * register to be written before TxDescAddrLow to work. * Switching from MMIO to I/O access fixes the issue as well. */ RTL_W32 ( TxDescStartAddrHigh, 0 ); RTL_W32 ( TxDescStartAddrLow, virt_to_bus ( tp->tx_base ) ); RTL_W32 ( RxDescAddrHigh, 0 ); RTL_W32 ( RxDescAddrLow, virt_to_bus ( tp->rx_base ) ); } static u16 rtl_rw_cpluscmd(void *ioaddr) { u16 cmd; DBGP ( "rtl_rw_cpluscmd\n" ); cmd = RTL_R16(CPlusCmd); RTL_W16(CPlusCmd, cmd); return cmd; } static void rtl_set_rx_max_size(void *ioaddr) { DBGP ( "rtl_set_rx_max_size\n" ); RTL_W16 ( RxMaxSize, RX_BUF_SIZE ); } static void rtl8169_set_magic_reg(void *ioaddr, unsigned mac_version) { struct { u32 mac_version; u32 clk; u32 val; } cfg2_info [] = { { RTL_GIGA_MAC_VER_05, PCI_Clock_33MHz, 0x000fff00 }, // 8110SCd { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff }, { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff } }, *p = cfg2_info; unsigned int i; u32 clk; DBGP ( "rtl8169_set_magic_reg\n" ); clk = RTL_R8(Config2) & PCI_Clock_66MHz; for (i = 0; i < ARRAY_SIZE(cfg2_info); i++, p++) { if ((p->mac_version == mac_version) && (p->clk == clk)) { RTL_W32(0x7c, p->val); break; } } } static void rtl_set_rx_mode ( struct net_device *netdev ) { struct rtl8169_private *tp = netdev_priv ( netdev ); void *ioaddr = tp->mmio_addr; u32 tmp; DBGP ( "rtl_set_rx_mode\n" ); /* Accept all Multicast Packets */ RTL_W32 ( MAR0 + 0, 0xffffffff ); RTL_W32 ( MAR0 + 4, 0xffffffff ); tmp = rtl8169_rx_config | AcceptBroadcast | AcceptMulticast | AcceptMyPhys | ( RTL_R32 ( RxConfig ) & rtl_chip_info[tp->chipset].RxConfigMask ); RTL_W32 ( RxConfig, tmp ); } static void rtl_hw_start_8169(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void *ioaddr = tp->mmio_addr; struct pci_device *pdev = tp->pci_dev; DBGP ( "rtl_hw_start_8169\n" ); if (tp->mac_version == RTL_GIGA_MAC_VER_05) { RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW); pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); } RTL_W8(Cfg9346, Cfg9346_Unlock); if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || (tp->mac_version == RTL_GIGA_MAC_VER_02) || (tp->mac_version == RTL_GIGA_MAC_VER_03) || (tp->mac_version == RTL_GIGA_MAC_VER_04)) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W8(EarlyTxThres, EarlyTxThld); rtl_set_rx_max_size(ioaddr); if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || (tp->mac_version == RTL_GIGA_MAC_VER_02) || (tp->mac_version == RTL_GIGA_MAC_VER_03) || (tp->mac_version == RTL_GIGA_MAC_VER_04)) rtl_set_rx_tx_config_registers(tp); tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || (tp->mac_version == RTL_GIGA_MAC_VER_03)) { DBG ( "Set MAC Reg C+CR Offset 0xE0. " "Bit-3 and bit-14 MUST be 1\n" ); tp->cp_cmd |= (1 << 14); } RTL_W16(CPlusCmd, tp->cp_cmd); rtl8169_set_magic_reg(ioaddr, tp->mac_version); /* * Undocumented corner. Supposedly: * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets */ RTL_W16(IntrMitigate, 0x0000); rtl_set_rx_tx_desc_registers(tp, ioaddr); if ((tp->mac_version != RTL_GIGA_MAC_VER_01) && (tp->mac_version != RTL_GIGA_MAC_VER_02) && (tp->mac_version != RTL_GIGA_MAC_VER_03) && (tp->mac_version != RTL_GIGA_MAC_VER_04)) { RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); rtl_set_rx_tx_config_registers(tp); } RTL_W8(Cfg9346, Cfg9346_Lock); /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ RTL_R8(IntrMask); RTL_W32(RxMissed, 0); rtl_set_rx_mode(dev); /* no early-rx interrupts */ RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); // RTL_W16(IntrMask, tp->intr_event); } static void rtl_tx_performance_tweak(struct pci_device *pdev, u16 force) { struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); int cap = tp->pcie_cap; DBGP ( "rtl_tx_performance_tweak\n" ); if (cap) { u16 ctl; pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force; pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); } } static void rtl_csi_access_enable(void *ioaddr) { u32 csi; DBGP ( "rtl_csi_access_enable\n" ); csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff; rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000); } struct ephy_info { unsigned int offset; u16 mask; u16 bits; }; static void rtl_ephy_init(void *ioaddr, struct ephy_info *e, int len) { u16 w; DBGP ( "rtl_ephy_init\n" ); while (len-- > 0) { w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits; rtl_ephy_write(ioaddr, e->offset, w); e++; } } static void rtl_disable_clock_request(struct pci_device *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); int cap = tp->pcie_cap; DBGP ( "rtl_disable_clock_request\n" ); if (cap) { u16 ctl; pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl); ctl &= ~PCI_EXP_LNKCTL_CLKREQ_EN; pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl); } } #define R8168_CPCMD_QUIRK_MASK (\ EnableBist | \ Mac_dbgo_oe | \ Force_half_dup | \ Force_rxflow_en | \ Force_txflow_en | \ Cxpl_dbg_sel | \ ASF | \ PktCntrDisable | \ Mac_dbgo_sel) static void rtl_hw_start_8168bb(void *ioaddr, struct pci_device *pdev) { DBGP ( "rtl_hw_start_8168bb\n" ); RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); rtl_tx_performance_tweak(pdev, (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); } static void rtl_hw_start_8168bef(void *ioaddr, struct pci_device *pdev) { DBGP ( "rtl_hw_start_8168bef\n" ); rtl_hw_start_8168bb(ioaddr, pdev); RTL_W8(EarlyTxThres, EarlyTxThld); RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0)); } static void __rtl_hw_start_8168cp(void *ioaddr, struct pci_device *pdev) { DBGP ( "__rtl_hw_start_8168cp\n" ); RTL_W8(Config1, RTL_R8(Config1) | Speed_down); RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); rtl_disable_clock_request(pdev); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } static void rtl_hw_start_8168cp_1(void *ioaddr, struct pci_device *pdev) { static struct ephy_info e_info_8168cp[] = { { 0x01, 0, 0x0001 }, { 0x02, 0x0800, 0x1000 }, { 0x03, 0, 0x0042 }, { 0x06, 0x0080, 0x0000 }, { 0x07, 0, 0x2000 } }; DBGP ( "rtl_hw_start_8168cp_1\n" ); rtl_csi_access_enable(ioaddr); rtl_ephy_init(ioaddr, e_info_8168cp, ARRAY_SIZE(e_info_8168cp)); __rtl_hw_start_8168cp(ioaddr, pdev); } static void rtl_hw_start_8168cp_2(void *ioaddr, struct pci_device *pdev) { DBGP ( "rtl_hw_start_8168cp_2\n" ); rtl_csi_access_enable(ioaddr); RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } static void rtl_hw_start_8168cp_3(void *ioaddr, struct pci_device *pdev) { DBGP ( "rtl_hw_start_8168cp_3\n" ); rtl_csi_access_enable(ioaddr); RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); /* Magic. */ RTL_W8(DBG_REG, 0x20); RTL_W8(EarlyTxThres, EarlyTxThld); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } static void rtl_hw_start_8168c_1(void *ioaddr, struct pci_device *pdev) { static struct ephy_info e_info_8168c_1[] = { { 0x02, 0x0800, 0x1000 }, { 0x03, 0, 0x0002 }, { 0x06, 0x0080, 0x0000 } }; DBGP ( "rtl_hw_start_8168c_1\n" ); rtl_csi_access_enable(ioaddr); RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2); rtl_ephy_init(ioaddr, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1)); __rtl_hw_start_8168cp(ioaddr, pdev); } static void rtl_hw_start_8168c_2(void *ioaddr, struct pci_device *pdev) { static struct ephy_info e_info_8168c_2[] = { { 0x01, 0, 0x0001 }, { 0x03, 0x0400, 0x0220 } }; DBGP ( "rtl_hw_start_8168c_2\n" ); rtl_csi_access_enable(ioaddr); rtl_ephy_init(ioaddr, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2)); __rtl_hw_start_8168cp(ioaddr, pdev); } static void rtl_hw_start_8168c_3(void *ioaddr, struct pci_device *pdev) { DBGP ( "rtl_hw_start_8168c_3\n" ); rtl_hw_start_8168c_2(ioaddr, pdev); } static void rtl_hw_start_8168c_4(void *ioaddr, struct pci_device *pdev) { DBGP ( "rtl_hw_start_8168c_4\n" ); rtl_csi_access_enable(ioaddr); __rtl_hw_start_8168cp(ioaddr, pdev); } static void rtl_hw_start_8168d(void *ioaddr, struct pci_device *pdev) { DBGP ( "rtl_hw_start_8168d\n" ); rtl_csi_access_enable(ioaddr); rtl_disable_clock_request(pdev); RTL_W8(EarlyTxThres, EarlyTxThld); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } static void rtl_hw_start_8168(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void *ioaddr = tp->mmio_addr; struct pci_device *pdev = tp->pci_dev; DBGP ( "rtl_hw_start_8168\n" ); RTL_W8(Cfg9346, Cfg9346_Unlock); RTL_W8(EarlyTxThres, EarlyTxThld); rtl_set_rx_max_size(ioaddr); tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1; RTL_W16(CPlusCmd, tp->cp_cmd); RTL_W16(IntrMitigate, 0x5151); /* Work around for RxFIFO overflow. */ if (tp->mac_version == RTL_GIGA_MAC_VER_11) { tp->intr_event |= RxFIFOOver | PCSTimeout; tp->intr_event &= ~RxOverflow; } rtl_set_rx_tx_desc_registers(tp, ioaddr); rtl_set_rx_mode(dev); RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | (InterFrameGap << TxInterFrameGapShift)); RTL_R8(IntrMask); switch (tp->mac_version) { case RTL_GIGA_MAC_VER_11: rtl_hw_start_8168bb(ioaddr, pdev); break; case RTL_GIGA_MAC_VER_12: case RTL_GIGA_MAC_VER_17: rtl_hw_start_8168bef(ioaddr, pdev); break; case RTL_GIGA_MAC_VER_18: rtl_hw_start_8168cp_1(ioaddr, pdev); break; case RTL_GIGA_MAC_VER_19: rtl_hw_start_8168c_1(ioaddr, pdev); break; case RTL_GIGA_MAC_VER_20: rtl_hw_start_8168c_2(ioaddr, pdev); break; case RTL_GIGA_MAC_VER_21: rtl_hw_start_8168c_3(ioaddr, pdev); break; case RTL_GIGA_MAC_VER_22: rtl_hw_start_8168c_4(ioaddr, pdev); break; case RTL_GIGA_MAC_VER_23: rtl_hw_start_8168cp_2(ioaddr, pdev); break; case RTL_GIGA_MAC_VER_24: rtl_hw_start_8168cp_3(ioaddr, pdev); break; case RTL_GIGA_MAC_VER_25: rtl_hw_start_8168d(ioaddr, pdev); break; default: DBG ( "Unknown chipset (mac_version = %d).\n", tp->mac_version ); break; } RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W8(Cfg9346, Cfg9346_Lock); RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); // RTL_W16(IntrMask, tp->intr_event); } #define R810X_CPCMD_QUIRK_MASK (\ EnableBist | \ Mac_dbgo_oe | \ Force_half_dup | \ Force_half_dup | \ Force_txflow_en | \ Cxpl_dbg_sel | \ ASF | \ PktCntrDisable | \ PCIDAC | \ PCIMulRW) static void rtl_hw_start_8102e_1(void *ioaddr, struct pci_device *pdev) { static struct ephy_info e_info_8102e_1[] = { { 0x01, 0, 0x6e65 }, { 0x02, 0, 0x091f }, { 0x03, 0, 0xc2f9 }, { 0x06, 0, 0xafb5 }, { 0x07, 0, 0x0e00 }, { 0x19, 0, 0xec80 }, { 0x01, 0, 0x2e65 }, { 0x01, 0, 0x6e65 } }; u8 cfg1; DBGP ( "rtl_hw_start_8102e_1\n" ); rtl_csi_access_enable(ioaddr); RTL_W8(DBG_REG, FIX_NAK_1); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W8(Config1, LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable); RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); cfg1 = RTL_R8(Config1); if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) RTL_W8(Config1, cfg1 & ~LEDS0); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK); rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1)); } static void rtl_hw_start_8102e_2(void *ioaddr, struct pci_device *pdev) { DBGP ( "rtl_hw_start_8102e_2\n" ); rtl_csi_access_enable(ioaddr); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable); RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK); } static void rtl_hw_start_8102e_3(void *ioaddr, struct pci_device *pdev) { DBGP ( "rtl_hw_start_8102e_3\n" ); rtl_hw_start_8102e_2(ioaddr, pdev); rtl_ephy_write(ioaddr, 0x03, 0xc2f9); } static void rtl_hw_start_8101(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void *ioaddr = tp->mmio_addr; struct pci_device *pdev = tp->pci_dev; DBGP ( "rtl_hw_start_8101\n" ); if ((tp->mac_version == RTL_GIGA_MAC_VER_13) || (tp->mac_version == RTL_GIGA_MAC_VER_16)) { int cap = tp->pcie_cap; if (cap) { pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_NOSNOOP_EN); } } switch (tp->mac_version) { case RTL_GIGA_MAC_VER_07: rtl_hw_start_8102e_1(ioaddr, pdev); break; case RTL_GIGA_MAC_VER_08: rtl_hw_start_8102e_3(ioaddr, pdev); break; case RTL_GIGA_MAC_VER_09: rtl_hw_start_8102e_2(ioaddr, pdev); break; } RTL_W8(Cfg9346, Cfg9346_Unlock); RTL_W8(EarlyTxThres, EarlyTxThld); rtl_set_rx_max_size(ioaddr); tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; RTL_W16(CPlusCmd, tp->cp_cmd); RTL_W16(IntrMitigate, 0x0000); rtl_set_rx_tx_desc_registers(tp, ioaddr); RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); rtl_set_rx_tx_config_registers(tp); RTL_W8(Cfg9346, Cfg9346_Lock); RTL_R8(IntrMask); rtl_set_rx_mode(dev); RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); // RTL_W16(IntrMask, tp->intr_event); } /*** gPXE API Support Routines ***/ /** * setup_tx_resources - allocate tx resources (descriptors) * * @v tp Driver private storage * * @ret rc Returns 0 on success, negative on failure **/ static int rtl8169_setup_tx_resources ( struct rtl8169_private *tp ) { DBGP ( "rtl8169_setup_tx_resources\n" ); tp->tx_base = malloc_dma ( R8169_TX_RING_BYTES, TX_RING_ALIGN ); if ( ! tp->tx_base ) { return -ENOMEM; } memset ( tp->tx_base, 0, R8169_TX_RING_BYTES ); DBG ( "tp->tx_base = %#08lx\n", virt_to_bus ( tp->tx_base ) ); tp->tx_fill_ctr = 0; tp->tx_curr = 0; tp->tx_tail = 0; return 0; } static void rtl8169_process_tx_packets ( struct net_device *netdev ) { struct rtl8169_private *tp = netdev_priv ( netdev ); uint32_t tx_status; struct TxDesc *tx_curr_desc; DBGP ( "rtl8169_process_tx_packets\n" ); while ( tp->tx_tail != tp->tx_curr ) { tx_curr_desc = tp->tx_base + tp->tx_tail; tx_status = tx_curr_desc->opts1; DBG2 ( "Before DescOwn check tx_status: %#08x\n", tx_status ); /* if the packet at tx_tail is not owned by hardware it is for us */ if ( tx_status & DescOwn ) break; DBG ( "Transmitted packet.\n" ); DBG ( "tp->tx_fill_ctr = %d\n", tp->tx_fill_ctr ); DBG ( "tp->tx_tail = %d\n", tp->tx_tail ); DBG ( "tp->tx_curr = %d\n", tp->tx_curr ); DBG ( "tx_status = %d\n", tx_status ); DBG ( "tx_curr_desc = %#08lx\n", virt_to_bus ( tx_curr_desc ) ); /* Pass packet to core for processing */ netdev_tx_complete ( netdev, tp->tx_iobuf[tp->tx_tail] ); memset ( tx_curr_desc, 0, sizeof ( *tx_curr_desc ) ); /* Decrement count of used descriptors */ tp->tx_fill_ctr--; /* Increment sent packets index */ tp->tx_tail = ( tp->tx_tail + 1 ) % NUM_TX_DESC; } } static void rtl8169_free_tx_resources ( struct rtl8169_private *tp ) { DBGP ( "rtl8169_free_tx_resources\n" ); free_dma ( tp->tx_base, R8169_TX_RING_BYTES ); } static void rtl8169_populate_rx_descriptor ( struct rtl8169_private *tp, struct RxDesc *rx_desc, uint32_t index ) { DBGP ( "rtl8169_populate_rx_descriptor\n" ); DBG ( "Populating rx descriptor %d\n", index ); memset ( rx_desc, 0, sizeof ( *rx_desc ) ); rx_desc->addr_hi = 0; rx_desc->addr_lo = virt_to_bus ( tp->rx_iobuf[index]->data ); rx_desc->opts2 = 0; rx_desc->opts1 = ( index == ( NUM_RX_DESC - 1 ) ? RingEnd : 0 ) | RX_BUF_SIZE; rx_desc->opts1 |= DescOwn; } /** * Refill descriptor ring * * @v netdev Net device */ static void rtl8169_refill_rx_ring ( struct rtl8169_private *tp ) { struct RxDesc *rx_curr_desc; int i; DBGP ( "rtl8169_refill_rx_ring\n" ); for ( i = 0; i < NUM_RX_DESC; i++ ) { rx_curr_desc = ( tp->rx_base ) + i; /* Don't touch descriptors owned by the NIC */ if ( rx_curr_desc->opts1 & DescOwn ) continue; /* Don't touch descriptors with iobufs, they still need to be processed by the poll routine */ if ( tp->rx_iobuf[tp->rx_curr] != NULL ) continue; /** If we can't get an iobuf for this descriptor try again later (next poll). */ if ( ! ( tp->rx_iobuf[i] = alloc_iob ( RX_BUF_SIZE ) ) ) { DBG ( "Refill rx ring failed!!\n" ); break; } rtl8169_populate_rx_descriptor ( tp, rx_curr_desc, i ); } } /** * setup_rx_resources - allocate Rx resources (Descriptors) * * @v tp: Driver private structure * * @ret rc Returns 0 on success, negative on failure * **/ static int rtl8169_setup_rx_resources ( struct rtl8169_private *tp ) { DBGP ( "rtl8169_setup_rx_resources\n" ); tp->rx_base = malloc_dma ( R8169_RX_RING_BYTES, RX_RING_ALIGN ); DBG ( "tp->rx_base = %#08lx\n", virt_to_bus ( tp->rx_base ) ); if ( ! tp->rx_base ) { return -ENOMEM; } memset ( tp->rx_base, 0, R8169_RX_RING_BYTES ); rtl8169_refill_rx_ring ( tp ); tp->rx_curr = 0; return 0; } static void rtl8169_process_rx_packets ( struct net_device *netdev ) { struct rtl8169_private *tp = netdev_priv ( netdev ); uint32_t rx_status; uint16_t rx_len; struct RxDesc *rx_curr_desc; int i; DBGP ( "rtl8169_process_rx_packets\n" ); for ( i = 0; i < NUM_RX_DESC; i++ ) { rx_curr_desc = tp->rx_base + tp->rx_curr; rx_status = rx_curr_desc->opts1; DBG2 ( "Before DescOwn check rx_status: %#08x\n", rx_status ); /* Hardware still owns the descriptor */ if ( rx_status & DescOwn ) break; /* We own the descriptor, but it has not been refilled yet */ if ( tp->rx_iobuf[tp->rx_curr] == NULL ) break; rx_len = rx_status & 0x3fff; DBG ( "Received packet.\n" ); DBG ( "tp->rx_curr = %d\n", tp->rx_curr ); DBG ( "rx_len = %d\n", rx_len ); DBG ( "rx_status = %#08x\n", rx_status ); DBG ( "rx_curr_desc = %#08lx\n", virt_to_bus ( rx_curr_desc ) ); if ( rx_status & RxRES ) { netdev_rx_err ( netdev, tp->rx_iobuf[tp->rx_curr], -EINVAL ); DBG ( "rtl8169_poll: Corrupted packet received!\n" " rx_status: %#08x\n", rx_status ); } else { /* Adjust size of the iobuf to reflect received data */ iob_put ( tp->rx_iobuf[tp->rx_curr], rx_len ); /* Add this packet to the receive queue. */ netdev_rx ( netdev, tp->rx_iobuf[tp->rx_curr] ); } /* Invalidate this iobuf and descriptor */ tp->rx_iobuf[tp->rx_curr] = NULL; memset ( rx_curr_desc, 0, sizeof ( *rx_curr_desc ) ); /* Update pointer to next available rx descriptor */ tp->rx_curr = ( tp->rx_curr + 1 ) % NUM_RX_DESC; } rtl8169_refill_rx_ring ( tp ); } static void rtl8169_free_rx_resources ( struct rtl8169_private *tp ) { int i; DBGP ( "rtl8169_free_rx_resources\n" ); free_dma ( tp->rx_base, R8169_RX_RING_BYTES ); for ( i = 0; i < NUM_RX_DESC; i++ ) { free_iob ( tp->rx_iobuf[i] ); tp->rx_iobuf[i] = NULL; } } /** FIXME: Because gPXE's pci_device_id structure does not contain a field to contain arbitrary data, we need the following table to associate PCI IDs with nic variants, because a lot of driver routines depend on knowing which kind of variant they are dealing with. --mdc **/ #define _R(VENDOR,DEVICE,INDEX) \ { .vendor = VENDOR, .device = DEVICE, .index = INDEX } static const struct { uint16_t vendor; uint16_t device; int index; } nic_variant_table[] = { _R(0x10ec, 0x8129, RTL_CFG_0), _R(0x10ec, 0x8136, RTL_CFG_2), _R(0x10ec, 0x8167, RTL_CFG_0), _R(0x10ec, 0x8168, RTL_CFG_1), _R(0x10ec, 0x8169, RTL_CFG_0), _R(0x1186, 0x4300, RTL_CFG_0), _R(0x1259, 0xc107, RTL_CFG_0), _R(0x16ec, 0x0116, RTL_CFG_0), _R(0x1737, 0x1032, RTL_CFG_0), _R(0x0001, 0x8168, RTL_CFG_2), }; #undef _R static int rtl8169_get_nic_variant ( uint16_t vendor, uint16_t device ) { u32 i; DBGP ( "rtl8169_get_nic_variant\n" ); for (i = 0; i < ARRAY_SIZE(nic_variant_table); i++) { if ( ( nic_variant_table[i].vendor == vendor ) && ( nic_variant_table[i].device == device ) ) { return ( nic_variant_table[i].index ); } } DBG ( "No matching NIC variant found!\n" ); return ( RTL_CFG_0 ); } static void rtl8169_irq_enable ( struct rtl8169_private *tp ) { void *ioaddr = tp->mmio_addr; DBGP ( "rtl8169_irq_enable\n" ); RTL_W16 ( IntrMask, tp->intr_event ); } static void rtl8169_irq_disable ( struct rtl8169_private *tp ) { void *ioaddr = tp->mmio_addr; DBGP ( "rtl8169_irq_disable\n" ); rtl8169_irq_mask_and_ack ( ioaddr ); } /*** gPXE Core API Routines ***/ /** * open - Called when a network interface is made active * * @v netdev network interface device structure * @ret rc Return status code, 0 on success, negative value on failure * **/ static int rtl8169_open ( struct net_device *netdev ) { struct rtl8169_private *tp = netdev_priv ( netdev ); void *ioaddr = tp->mmio_addr; int rc; DBGP ( "rtl8169_open\n" ); /* allocate transmit descriptors */ rc = rtl8169_setup_tx_resources ( tp ); if ( rc ) { DBG ( "Error setting up TX resources!\n" ); goto err_setup_tx; } /* allocate receive descriptors */ rc = rtl8169_setup_rx_resources ( tp ); if ( rc ) { DBG ( "Error setting up RX resources!\n" ); goto err_setup_rx; } rtl_hw_start ( netdev ); DBG ( "TxDescStartAddrHigh = %#08lx\n", RTL_R32 ( TxDescStartAddrHigh ) ); DBG ( "TxDescStartAddrLow = %#08lx\n", RTL_R32 ( TxDescStartAddrLow ) ); DBG ( "RxDescAddrHigh = %#08lx\n", RTL_R32 ( RxDescAddrHigh ) ); DBG ( "RxDescAddrLow = %#08lx\n", RTL_R32 ( RxDescAddrLow ) ); return 0; err_setup_rx: rtl8169_free_tx_resources ( tp ); err_setup_tx: rtl8169_hw_reset ( ioaddr ); return rc; } /** * transmit - Transmit a packet * * @v netdev Network device * @v iobuf I/O buffer * * @ret rc Returns 0 on success, negative on failure */ static int rtl8169_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { struct rtl8169_private *tp = netdev_priv ( netdev ); void *ioaddr = tp->mmio_addr; uint32_t tx_len = iob_len ( iobuf ); struct TxDesc *tx_curr_desc; DBGP ("rtl8169_transmit\n"); if ( tp->tx_fill_ctr == NUM_TX_DESC ) { DBG ("TX overflow\n"); return -ENOBUFS; } /** * The rtl8169 family automatically pads short packets to a * minimum size, but if it did not, like some older cards, * we could do: * iob_pad ( iobuf, ETH_ZLEN ); */ /* Save pointer to this iobuf we have been given to transmit so we can pass it to netdev_tx_complete() later */ tp->tx_iobuf[tp->tx_curr] = iobuf; tx_curr_desc = tp->tx_base + tp->tx_curr; DBG ( "tp->tx_fill_ctr = %d\n", tp->tx_fill_ctr ); DBG ( "tp->tx_curr = %d\n", tp->tx_curr ); DBG ( "tx_curr_desc = %#08lx\n", virt_to_bus ( tx_curr_desc ) ); DBG ( "iobuf->data = %#08lx\n", virt_to_bus ( iobuf->data ) ); DBG ( "tx_len = %d\n", tx_len ); /* Configure current descriptor to transmit supplied packet */ tx_curr_desc->addr_hi = 0; tx_curr_desc->addr_lo = virt_to_bus ( iobuf->data ); tx_curr_desc->opts2 = 0; tx_curr_desc->opts1 = FirstFrag | LastFrag | ( tp->tx_curr == ( NUM_TX_DESC - 1 ) ? RingEnd : 0 ) | tx_len; /* Mark descriptor as owned by NIC */ tx_curr_desc->opts1 |= DescOwn; DBG ( "tx_curr_desc->opts1 = %#08x\n", tx_curr_desc->opts1 ); DBG ( "tx_curr_desc->opts2 = %#08x\n", tx_curr_desc->opts2 ); DBG ( "tx_curr_desc->addr_hi = %#08x\n", tx_curr_desc->addr_hi ); DBG ( "tx_curr_desc->addr_lo = %#08x\n", tx_curr_desc->addr_lo ); RTL_W8 ( TxPoll, NPQ ); /* set polling bit */ /* Point to next free descriptor */ tp->tx_curr = ( tp->tx_curr + 1 ) % NUM_TX_DESC; /* Increment number of tx descriptors in use */ tp->tx_fill_ctr++; return 0; } /** * poll - Poll for received packets * * @v netdev Network device */ static void rtl8169_poll ( struct net_device *netdev ) { struct rtl8169_private *tp = netdev_priv ( netdev ); void *ioaddr = tp->mmio_addr; uint16_t intr_status; uint16_t intr_mask; DBGP ( "rtl8169_poll\n" ); intr_status = RTL_R16 ( IntrStatus ); intr_mask = RTL_R16 ( IntrMask ); DBG2 ( "rtl8169_poll (before): intr_mask = %#04x intr_status = %#04x\n", intr_mask, intr_status ); RTL_W16 ( IntrStatus, 0xffff ); /* hotplug / major error / no more work / shared irq */ if ( intr_status == 0xffff ) return; /* Process transmitted packets */ rtl8169_process_tx_packets ( netdev ); /* Process received packets */ rtl8169_process_rx_packets ( netdev ); } /** * close - Disable network interface * * @v netdev network interface device structure * **/ static void rtl8169_close ( struct net_device *netdev ) { struct rtl8169_private *tp = netdev_priv ( netdev ); void *ioaddr = tp->mmio_addr; DBGP ( "r8169_close\n" ); rtl8169_hw_reset ( ioaddr ); rtl8169_free_tx_resources ( tp ); rtl8169_free_rx_resources ( tp ); } /** * irq - enable or Disable interrupts * * @v netdev network adapter * @v action requested interrupt action * **/ static void rtl8169_irq ( struct net_device *netdev, int action ) { struct rtl8169_private *tp = netdev_priv ( netdev ); DBGP ( "rtl8169_irq\n" ); switch ( action ) { case 0 : rtl8169_irq_disable ( tp ); break; default : rtl8169_irq_enable ( tp ); break; } } static struct net_device_operations rtl8169_operations = { .open = rtl8169_open, .transmit = rtl8169_transmit, .poll = rtl8169_poll, .close = rtl8169_close, .irq = rtl8169_irq, }; /** * probe - Initial configuration of NIC * * @v pci PCI device * @v id PCI IDs * * @ret rc Return status code **/ static int rtl8169_probe ( struct pci_device *pdev, const struct pci_device_id *ent ) { int i, rc; struct net_device *netdev; struct rtl8169_private *tp; void *ioaddr; /** FIXME: This lookup is necessary because gPXE does not have a "data" element in the structure pci_device_id which can pass an arbitrary piece of data to the driver. It might be useful to add it. Then we could just use ent->data instead of having to look up cfg_index. **/ int cfg_index = rtl8169_get_nic_variant ( ent->vendor, ent->device ); const struct rtl_cfg_info *cfg = rtl_cfg_infos + cfg_index; DBGP ( "rtl8169_probe\n" ); DBG ( "ent->vendor = %#04x, ent->device = %#04x\n", ent->vendor, ent->device ); DBG ( "cfg_index = %d\n", cfg_index ); DBG ( "cfg->intr_event = %#04x\n", cfg->intr_event ); rc = -ENOMEM; /* Allocate net device ( also allocates memory for netdev->priv and makes netdev-priv point to it ) */ netdev = alloc_etherdev ( sizeof ( *tp ) ); if ( ! netdev ) goto err_alloc_etherdev; /* Associate driver-specific network operations with generic network device layer */ netdev_init ( netdev, &rtl8169_operations ); /* Associate this network device with the given PCI device */ pci_set_drvdata ( pdev, netdev ); netdev->dev = &pdev->dev; /* Initialize driver private storage */ tp = netdev_priv ( netdev ); memset ( tp, 0, ( sizeof ( *tp ) ) ); tp->pci_dev = pdev; tp->irqno = pdev->irq; tp->netdev = netdev; tp->cfg_index = cfg_index; tp->intr_event = cfg->intr_event; tp->cp_cmd = PCIMulRW; tp->hw_start = cfg->hw_start; rc = -EIO; adjust_pci_device ( pdev ); /* ioremap MMIO region */ ioaddr = ioremap ( pdev->membase, R8169_REGS_SIZE ); if ( ! ioaddr ) { DBG ( "cannot remap MMIO\n" ); rc = -EIO; goto err_ioremap; } tp->mmio_addr = ioaddr; tp->pcie_cap = pci_find_capability ( pdev, PCI_CAP_ID_EXP ); if ( tp->pcie_cap ) { DBG ( "PCI Express capability\n" ); } else { DBG ( "No PCI Express capability\n" ); } /* Mask interrupts just in case */ rtl8169_irq_mask_and_ack ( ioaddr ); /* Soft reset NIC */ rtl_soft_reset ( netdev ); /* Identify chip attached to board */ rtl8169_get_mac_version ( tp, ioaddr ); for ( i = 0; (u32) i < ARRAY_SIZE ( rtl_chip_info ); i++ ) { if ( tp->mac_version == rtl_chip_info[i].mac_version ) break; } if ( i == ARRAY_SIZE(rtl_chip_info ) ) { /* Unknown chip: assume array element #0, original RTL-8169 */ DBG ( "Unknown chip version, assuming %s\n", rtl_chip_info[0].name ); i = 0; } tp->chipset = i; if ((tp->mac_version <= RTL_GIGA_MAC_VER_06) && (RTL_R8(PHYstatus) & TBI_Enable)) { tp->set_speed = rtl8169_set_speed_tbi; tp->phy_reset_enable = rtl8169_tbi_reset_enable; tp->phy_reset_pending = rtl8169_tbi_reset_pending; tp->link_ok = rtl8169_tbi_link_ok; tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */ } else { tp->set_speed = rtl8169_set_speed_xmii; tp->phy_reset_enable = rtl8169_xmii_reset_enable; tp->phy_reset_pending = rtl8169_xmii_reset_pending; tp->link_ok = rtl8169_xmii_link_ok; } /* Get MAC address */ for ( i = 0; i < MAC_ADDR_LEN; i++ ) netdev->hw_addr[i] = RTL_R8 ( MAC0 + i ); DBG ( "%s\n", eth_ntoa ( netdev->hw_addr ) ); rtl8169_init_phy ( netdev, tp ); if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err_register; /* Mark as link up; we don't yet handle link state */ netdev_link_up ( netdev ); DBG ( "rtl8169_probe succeeded!\n" ); /* No errors, return success */ return 0; /* Error return paths */ err_register: err_ioremap: netdev_put ( netdev ); err_alloc_etherdev: return rc; } /** * remove - Device Removal Routine * * @v pdev PCI device information struct * **/ static void rtl8169_remove ( struct pci_device *pdev ) { struct net_device *netdev = pci_get_drvdata ( pdev ); struct rtl8169_private *tp = netdev_priv ( netdev ); void *ioaddr = tp->mmio_addr; DBGP ( "rtl8169_remove\n" ); rtl8169_hw_reset ( ioaddr ); unregister_netdev ( netdev ); netdev_nullify ( netdev ); netdev_put ( netdev ); } static struct pci_device_id rtl8169_nics[] = { PCI_ROM(0x10ec, 0x8129, "rtl8169-0x8129", "rtl8169-0x8129", 0), PCI_ROM(0x10ec, 0x8136, "rtl8169-0x8136", "rtl8169-0x8136", 0), PCI_ROM(0x10ec, 0x8167, "rtl8169-0x8167", "rtl8169-0x8167", 0), PCI_ROM(0x10ec, 0x8168, "rtl8169-0x8168", "rtl8169-0x8168", 0), PCI_ROM(0x10ec, 0x8169, "rtl8169-0x8169", "rtl8169-0x8169", 0), PCI_ROM(0x1186, 0x4300, "rtl8169-0x4300", "rtl8169-0x4300", 0), PCI_ROM(0x1259, 0xc107, "rtl8169-0xc107", "rtl8169-0xc107", 0), PCI_ROM(0x16ec, 0x0116, "rtl8169-0x0116", "rtl8169-0x0116", 0), PCI_ROM(0x1737, 0x1032, "rtl8169-0x1032", "rtl8169-0x1032", 0), PCI_ROM(0x0001, 0x8168, "rtl8169-0x8168", "rtl8169-0x8168", 0), }; struct pci_driver rtl8169_driver __pci_driver = { .ids = rtl8169_nics, .id_count = ( sizeof ( rtl8169_nics ) / sizeof ( rtl8169_nics[0] ) ), .probe = rtl8169_probe, .remove = rtl8169_remove, }; /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */ debian/grub-extras/disabled/gpxe/src/drivers/block/0000775000000000000000000000000012524676037017520 5ustar debian/grub-extras/disabled/gpxe/src/drivers/block/scsi.c0000664000000000000000000002475712524662415020637 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include /** @file * * SCSI block device * */ /** Maximum number of dummy "read capacity (10)" operations * * These are issued at connection setup to draw out various useless * power-on messages. */ #define SCSI_MAX_DUMMY_READ_CAP 10 static inline __attribute__ (( always_inline )) struct scsi_device * block_to_scsi ( struct block_device *blockdev ) { return container_of ( blockdev, struct scsi_device, blockdev ); } /** * Handle SCSI command with no backing device * * @v scsi SCSI device * @v command SCSI command * @ret rc Return status code */ int scsi_detached_command ( struct scsi_device *scsi __unused, struct scsi_command *command __unused ) { return -ENODEV; } /** * Issue SCSI command * * @v scsi SCSI device * @v command SCSI command * @ret rc Return status code */ static int scsi_command ( struct scsi_device *scsi, struct scsi_command *command ) { int rc; DBGC2 ( scsi, "SCSI %p " SCSI_CDB_FORMAT "\n", scsi, SCSI_CDB_DATA ( command->cdb ) ); /* Clear sense response code before issuing command */ command->sense_response = 0; /* Flag command as in-progress */ command->rc = -EINPROGRESS; /* Issue SCSI command */ if ( ( rc = scsi->command ( scsi, command ) ) != 0 ) { /* Something went wrong with the issuing mechanism */ DBGC ( scsi, "SCSI %p " SCSI_CDB_FORMAT " err %s\n", scsi, SCSI_CDB_DATA ( command->cdb ), strerror ( rc ) ); return rc; } /* Wait for command to complete */ while ( command->rc == -EINPROGRESS ) step(); if ( ( rc = command->rc ) != 0 ) { /* Something went wrong with the command execution */ DBGC ( scsi, "SCSI %p " SCSI_CDB_FORMAT " err %s\n", scsi, SCSI_CDB_DATA ( command->cdb ), strerror ( rc ) ); return rc; } /* Check for SCSI errors */ if ( command->status != 0 ) { DBGC ( scsi, "SCSI %p " SCSI_CDB_FORMAT " status %02x sense " "%02x\n", scsi, SCSI_CDB_DATA ( command->cdb ), command->status, command->sense_response ); return -EIO; } return 0; } /** * Read block from SCSI device using READ (10) * * @v blockdev Block device * @v block LBA block number * @v count Block count * @v buffer Data buffer * @ret rc Return status code */ static int scsi_read_10 ( struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer ) { struct scsi_device *scsi = block_to_scsi ( blockdev ); struct scsi_command command; struct scsi_cdb_read_10 *cdb = &command.cdb.read10; /* Issue READ (10) */ memset ( &command, 0, sizeof ( command ) ); cdb->opcode = SCSI_OPCODE_READ_10; cdb->lba = cpu_to_be32 ( block ); cdb->len = cpu_to_be16 ( count ); command.data_in = buffer; command.data_in_len = ( count * blockdev->blksize ); return scsi_command ( scsi, &command ); } /** * Read block from SCSI device using READ (16) * * @v blockdev Block device * @v block LBA block number * @v count Block count * @v buffer Data buffer * @ret rc Return status code */ static int scsi_read_16 ( struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer ) { struct scsi_device *scsi = block_to_scsi ( blockdev ); struct scsi_command command; struct scsi_cdb_read_16 *cdb = &command.cdb.read16; /* Issue READ (16) */ memset ( &command, 0, sizeof ( command ) ); cdb->opcode = SCSI_OPCODE_READ_16; cdb->lba = cpu_to_be64 ( block ); cdb->len = cpu_to_be32 ( count ); command.data_in = buffer; command.data_in_len = ( count * blockdev->blksize ); return scsi_command ( scsi, &command ); } /** * Write block to SCSI device using WRITE (10) * * @v blockdev Block device * @v block LBA block number * @v count Block count * @v buffer Data buffer * @ret rc Return status code */ static int scsi_write_10 ( struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer ) { struct scsi_device *scsi = block_to_scsi ( blockdev ); struct scsi_command command; struct scsi_cdb_write_10 *cdb = &command.cdb.write10; /* Issue WRITE (10) */ memset ( &command, 0, sizeof ( command ) ); cdb->opcode = SCSI_OPCODE_WRITE_10; cdb->lba = cpu_to_be32 ( block ); cdb->len = cpu_to_be16 ( count ); command.data_out = buffer; command.data_out_len = ( count * blockdev->blksize ); return scsi_command ( scsi, &command ); } /** * Write block to SCSI device using WRITE (16) * * @v blockdev Block device * @v block LBA block number * @v count Block count * @v buffer Data buffer * @ret rc Return status code */ static int scsi_write_16 ( struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer ) { struct scsi_device *scsi = block_to_scsi ( blockdev ); struct scsi_command command; struct scsi_cdb_write_16 *cdb = &command.cdb.write16; /* Issue WRITE (16) */ memset ( &command, 0, sizeof ( command ) ); cdb->opcode = SCSI_OPCODE_WRITE_16; cdb->lba = cpu_to_be64 ( block ); cdb->len = cpu_to_be32 ( count ); command.data_out = buffer; command.data_out_len = ( count * blockdev->blksize ); return scsi_command ( scsi, &command ); } /** * Read capacity of SCSI device via READ CAPACITY (10) * * @v blockdev Block device * @ret rc Return status code */ static int scsi_read_capacity_10 ( struct block_device *blockdev ) { struct scsi_device *scsi = block_to_scsi ( blockdev ); struct scsi_command command; struct scsi_cdb_read_capacity_10 *cdb = &command.cdb.readcap10; struct scsi_capacity_10 capacity; int rc; /* Issue READ CAPACITY (10) */ memset ( &command, 0, sizeof ( command ) ); cdb->opcode = SCSI_OPCODE_READ_CAPACITY_10; command.data_in = virt_to_user ( &capacity ); command.data_in_len = sizeof ( capacity ); if ( ( rc = scsi_command ( scsi, &command ) ) != 0 ) return rc; /* Fill in block device fields */ blockdev->blksize = be32_to_cpu ( capacity.blksize ); blockdev->blocks = ( be32_to_cpu ( capacity.lba ) + 1 ); return 0; } /** * Read capacity of SCSI device via READ CAPACITY (16) * * @v blockdev Block device * @ret rc Return status code */ static int scsi_read_capacity_16 ( struct block_device *blockdev ) { struct scsi_device *scsi = block_to_scsi ( blockdev ); struct scsi_command command; struct scsi_cdb_read_capacity_16 *cdb = &command.cdb.readcap16; struct scsi_capacity_16 capacity; int rc; /* Issue READ CAPACITY (16) */ memset ( &command, 0, sizeof ( command ) ); cdb->opcode = SCSI_OPCODE_SERVICE_ACTION_IN; cdb->service_action = SCSI_SERVICE_ACTION_READ_CAPACITY_16; cdb->len = cpu_to_be32 ( sizeof ( capacity ) ); command.data_in = virt_to_user ( &capacity ); command.data_in_len = sizeof ( capacity ); if ( ( rc = scsi_command ( scsi, &command ) ) != 0 ) return rc; /* Fill in block device fields */ blockdev->blksize = be32_to_cpu ( capacity.blksize ); blockdev->blocks = ( be64_to_cpu ( capacity.lba ) + 1 ); return 0; } static struct block_device_operations scsi_operations_16 = { .read = scsi_read_16, .write = scsi_write_16, }; static struct block_device_operations scsi_operations_10 = { .read = scsi_read_10, .write = scsi_write_10, }; /** * Initialise SCSI device * * @v scsi SCSI device * @ret rc Return status code * * Initialises a SCSI device. The scsi_device::command and * scsi_device::lun fields must already be filled in. This function * will configure scsi_device::blockdev, including issuing a READ * CAPACITY call to determine the block size and total device size. */ int init_scsidev ( struct scsi_device *scsi ) { unsigned int i; int rc; /* Issue some theoretically extraneous READ CAPACITY (10) * commands, solely in order to draw out the "CHECK CONDITION * (power-on occurred)", "CHECK CONDITION (reported LUNs data * has changed)" etc. that some dumb targets insist on sending * as an error at start of day. The precise command that we * use is unimportant; we just need to provide the target with * an opportunity to send its responses. */ for ( i = 0 ; i < SCSI_MAX_DUMMY_READ_CAP ; i++ ) { if ( ( rc = scsi_read_capacity_10 ( &scsi->blockdev ) ) == 0 ) break; DBGC ( scsi, "SCSI %p ignoring start-of-day error (#%d)\n", scsi, ( i + 1 ) ); } /* Try READ CAPACITY (10), which is a mandatory command, first. */ scsi->blockdev.op = &scsi_operations_10; if ( ( rc = scsi_read_capacity_10 ( &scsi->blockdev ) ) != 0 ) { DBGC ( scsi, "SCSI %p could not READ CAPACITY (10): %s\n", scsi, strerror ( rc ) ); return rc; } /* If capacity range was exceeded (i.e. capacity.lba was * 0xffffffff, meaning that blockdev->blocks is now zero), use * READ CAPACITY (16) instead. READ CAPACITY (16) is not * mandatory, so we can't just use it straight off. */ if ( scsi->blockdev.blocks == 0 ) { scsi->blockdev.op = &scsi_operations_16; if ( ( rc = scsi_read_capacity_16 ( &scsi->blockdev ) ) != 0 ){ DBGC ( scsi, "SCSI %p could not READ CAPACITY (16): " "%s\n", scsi, strerror ( rc ) ); return rc; } } DBGC ( scsi, "SCSI %p using READ/WRITE (%d) commands\n", scsi, ( ( scsi->blockdev.op == &scsi_operations_10 ) ? 10 : 16 ) ); DBGC ( scsi, "SCSI %p capacity is %ld MB (%#llx blocks)\n", scsi, ( ( unsigned long ) ( scsi->blockdev.blocks >> 11 ) ), scsi->blockdev.blocks ); return 0; } /** * Parse SCSI LUN * * @v lun_string LUN string representation * @v lun LUN to fill in * @ret rc Return status code */ int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun ) { char *p; int i; memset ( lun, 0, sizeof ( *lun ) ); if ( lun_string ) { p = ( char * ) lun_string; for ( i = 0 ; i < 4 ; i++ ) { lun->u16[i] = htons ( strtoul ( p, &p, 16 ) ); if ( *p == '\0' ) break; if ( *p != '-' ) return -EINVAL; p++; } if ( *p ) return -EINVAL; } return 0; } debian/grub-extras/disabled/gpxe/src/include/0000775000000000000000000000000012524676037016373 5ustar debian/grub-extras/disabled/gpxe/src/include/nic.h0000664000000000000000000002176512524662415017323 0ustar /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. */ FILE_LICENCE ( GPL2_OR_LATER ); #ifndef NIC_H #define NIC_H #include #include #include #include #include #include #include #include #include #include typedef enum { DISABLE = 0, ENABLE, FORCE } irq_action_t; typedef enum duplex { HALF_DUPLEX = 1, FULL_DUPLEX } duplex_t; /* * Structure returned from eth_probe and passed to other driver * functions. */ struct nic { struct nic_operations *nic_op; int flags; /* driver specific flags */ unsigned char *node_addr; unsigned char *packet; unsigned int packetlen; unsigned int ioaddr; unsigned char irqno; unsigned int mbps; duplex_t duplex; void *priv_data; /* driver private data */ }; struct nic_operations { int ( *connect ) ( struct nic * ); int ( *poll ) ( struct nic *, int retrieve ); void ( *transmit ) ( struct nic *, const char *, unsigned int, unsigned int, const char * ); void ( *irq ) ( struct nic *, irq_action_t ); }; extern struct nic nic; static inline int eth_poll ( int retrieve ) { return nic.nic_op->poll ( &nic, retrieve ); } static inline void eth_transmit ( const char *dest, unsigned int type, unsigned int size, const void *packet ) { nic.nic_op->transmit ( &nic, dest, type, size, packet ); } /* * Function prototypes * */ extern int dummy_connect ( struct nic *nic ); extern void dummy_irq ( struct nic *nic, irq_action_t irq_action ); extern int legacy_probe ( void *hwdev, void ( * set_drvdata ) ( void *hwdev, void *priv ), struct device *dev, int ( * probe ) ( struct nic *nic, void *hwdev ), void ( * disable ) ( struct nic *nic, void *hwdev )); void legacy_remove ( void *hwdev, void * ( * get_drvdata ) ( void *hwdev ), void ( * disable ) ( struct nic *nic, void *hwdev ) ); #define PCI_DRIVER(_name,_ids,_class) \ static inline int \ _name ## _pci_legacy_probe ( struct pci_device *pci, \ const struct pci_device_id *id ); \ static inline void \ _name ## _pci_legacy_remove ( struct pci_device *pci ); \ struct pci_driver _name __pci_driver = { \ .ids = _ids, \ .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ), \ .probe = _name ## _pci_legacy_probe, \ .remove = _name ## _pci_legacy_remove, \ }; \ REQUIRE_OBJECT ( pci ); static inline void legacy_pci_set_drvdata ( void *hwdev, void *priv ) { pci_set_drvdata ( hwdev, priv ); } static inline void * legacy_pci_get_drvdata ( void *hwdev ) { return pci_get_drvdata ( hwdev ); } #define ISAPNP_DRIVER(_name,_ids) \ static inline int \ _name ## _isapnp_legacy_probe ( struct isapnp_device *isapnp, \ const struct isapnp_device_id *id ); \ static inline void \ _name ## _isapnp_legacy_remove ( struct isapnp_device *isapnp ); \ struct isapnp_driver _name __isapnp_driver = { \ .ids = _ids, \ .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ), \ .probe = _name ## _isapnp_legacy_probe, \ .remove = _name ## _isapnp_legacy_remove, \ }; \ REQUIRE_OBJECT ( isapnp ); static inline void legacy_isapnp_set_drvdata ( void *hwdev, void *priv ) { isapnp_set_drvdata ( hwdev, priv ); } static inline void * legacy_isapnp_get_drvdata ( void *hwdev ) { return isapnp_get_drvdata ( hwdev ); } #define EISA_DRIVER(_name,_ids) \ static inline int \ _name ## _eisa_legacy_probe ( struct eisa_device *eisa, \ const struct eisa_device_id *id ); \ static inline void \ _name ## _eisa_legacy_remove ( struct eisa_device *eisa ); \ struct eisa_driver _name __eisa_driver = { \ .ids = _ids, \ .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ), \ .probe = _name ## _eisa_legacy_probe, \ .remove = _name ## _eisa_legacy_remove, \ }; \ REQUIRE_OBJECT ( eisa ); static inline void legacy_eisa_set_drvdata ( void *hwdev, void *priv ) { eisa_set_drvdata ( hwdev, priv ); } static inline void * legacy_eisa_get_drvdata ( void *hwdev ) { return eisa_get_drvdata ( hwdev ); } #define MCA_DRIVER(_name,_ids) \ static inline int \ _name ## _mca_legacy_probe ( struct mca_device *mca, \ const struct mca_device_id *id ); \ static inline void \ _name ## _mca_legacy_remove ( struct mca_device *mca ); \ struct mca_driver _name __mca_driver = { \ .ids = _ids, \ .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ), \ .probe = _name ## _mca_legacy_probe, \ .remove = _name ## _mca_legacy_remove, \ }; \ REQUIRE_OBJECT ( mca ); static inline void legacy_mca_set_drvdata ( void *hwdev, void *priv ) { mca_set_drvdata ( hwdev, priv ); } static inline void * legacy_mca_get_drvdata ( void *hwdev ) { return mca_get_drvdata ( hwdev ); } #define ISA_DRIVER(_name,_probe_addrs,_probe_addr,_vendor_id,_prod_id) \ static inline int \ _name ## _isa_legacy_probe ( struct isa_device *isa ); \ static inline int \ _name ## _isa_legacy_probe_at_addr ( struct isa_device *isa ) { \ if ( ! _probe_addr ( isa->ioaddr ) ) \ return -ENODEV; \ return _name ## _isa_legacy_probe ( isa ); \ } \ static inline void \ _name ## _isa_legacy_remove ( struct isa_device *isa ); \ static const char _name ## _text[]; \ struct isa_driver _name __isa_driver = { \ .name = _name ## _text, \ .probe_addrs = _probe_addrs, \ .addr_count = ( sizeof ( _probe_addrs ) / \ sizeof ( _probe_addrs[0] ) ), \ .vendor_id = _vendor_id, \ .prod_id = _prod_id, \ .probe = _name ## _isa_legacy_probe_at_addr, \ .remove = _name ## _isa_legacy_remove, \ }; \ REQUIRE_OBJECT ( isa ); static inline void legacy_isa_set_drvdata ( void *hwdev, void *priv ) { isa_set_drvdata ( hwdev, priv ); } static inline void * legacy_isa_get_drvdata ( void *hwdev ) { return isa_get_drvdata ( hwdev ); } #undef DRIVER #define DRIVER(_name_text,_unused2,_unused3,_name,_probe,_disable) \ static const char _name ## _text[] = _name_text; \ static inline int \ _name ## _probe ( struct nic *nic, void *hwdev ) { \ return _probe ( nic, hwdev ); \ } \ static inline void \ _name ## _disable ( struct nic *nic, void *hwdev ) { \ void ( * _unsafe_disable ) () = _disable; \ _unsafe_disable ( nic, hwdev ); \ } \ static inline int \ _name ## _pci_legacy_probe ( struct pci_device *pci, \ const struct pci_device_id *id __unused ) { \ return legacy_probe ( pci, legacy_pci_set_drvdata, \ (void *) &pci->dev, _name ## _probe, \ _name ## _disable ); \ } \ static inline void \ _name ## _pci_legacy_remove ( struct pci_device *pci ) { \ return legacy_remove ( pci, legacy_pci_get_drvdata, \ _name ## _disable ); \ } \ static inline int \ _name ## _isapnp_legacy_probe ( struct isapnp_device *isapnp, \ const struct isapnp_device_id *id __unused ) { \ return legacy_probe ( isapnp, legacy_isapnp_set_drvdata, \ &isapnp->dev, _name ## _probe, \ _name ## _disable ); \ } \ static inline void \ _name ## _isapnp_legacy_remove ( struct isapnp_device *isapnp ) { \ return legacy_remove ( isapnp, legacy_isapnp_get_drvdata, \ _name ## _disable ); \ } \ static inline int \ _name ## _eisa_legacy_probe ( struct eisa_device *eisa, \ const struct eisa_device_id *id __unused ) { \ return legacy_probe ( eisa, legacy_eisa_set_drvdata, \ &eisa->dev, _name ## _probe, \ _name ## _disable ); \ } \ static inline void \ _name ## _eisa_legacy_remove ( struct eisa_device *eisa ) { \ return legacy_remove ( eisa, legacy_eisa_get_drvdata, \ _name ## _disable ); \ } \ static inline int \ _name ## _mca_legacy_probe ( struct mca_device *mca, \ const struct mca_device_id *id __unused ) { \ return legacy_probe ( mca, legacy_mca_set_drvdata, \ &mca->dev, _name ## _probe, \ _name ## _disable ); \ } \ static inline void \ _name ## _mca_legacy_remove ( struct mca_device *mca ) { \ return legacy_remove ( mca, legacy_mca_get_drvdata, \ _name ## _disable ); \ } \ static inline int \ _name ## _isa_legacy_probe ( struct isa_device *isa ) { \ return legacy_probe ( isa, legacy_isa_set_drvdata, \ &isa->dev, _name ## _probe, \ _name ## _disable ); \ } \ static inline void \ _name ## _isa_legacy_remove ( struct isa_device *isa ) { \ return legacy_remove ( isa, legacy_isa_get_drvdata, \ _name ## _disable ); \ } #endif /* NIC_H */ debian/grub-extras/disabled/gpxe/src/include/etherboot.h0000664000000000000000000000147612524662415020542 0ustar #ifndef ETHERBOOT_H #define ETHERBOOT_H /* * Standard includes that we always want * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include typedef unsigned long Address; /* * IMPORTANT!!!!!!!!!!!!!! * * Everything below this point is cruft left over from older versions * of Etherboot. Do not add *anything* below this point. Things are * gradually being moved to individual header files. * */ /* Link configuration time in tenths of a second */ #ifndef VALID_LINK_TIMEOUT #define VALID_LINK_TIMEOUT 100 /* 10.0 seconds */ #endif /* * Local variables: * c-basic-offset: 8 * End: */ #endif /* ETHERBOOT_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/0000775000000000000000000000000012524676037017336 5ustar debian/grub-extras/disabled/gpxe/src/include/gpxe/interface.h0000664000000000000000000000240012524662415021436 0ustar #ifndef _GPXE_INTERFACE_H #define _GPXE_INTERFACE_H /** @file * * Object communication interfaces * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** An object communication interface */ struct interface { /** Destination interface * * When messages are sent via this interface, they will be * delivered to the destination interface. * * This pointer may never be NULL. When the interface is * unplugged, it should point to a null interface. */ struct interface *dest; /** Reference counter * * If this interface is not part of a reference-counted * object, this field may be NULL. */ struct refcnt *refcnt; }; /** * Increment reference count on an interface * * @v intf Interface * @ret intf Interface */ static inline __attribute__ (( always_inline )) struct interface * intf_get ( struct interface *intf ) { ref_get ( intf->refcnt ); return intf; } /** * Decrement reference count on an interface * * @v intf Interface */ static inline __attribute__ (( always_inline )) void intf_put ( struct interface *intf ) { ref_put ( intf->refcnt ); } extern void plug ( struct interface *intf, struct interface *dest ); extern void plug_plug ( struct interface *a, struct interface *b ); #endif /* _GPXE_INTERFACE_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/uaccess.h0000664000000000000000000002067312524662415021140 0ustar #ifndef _GPXE_UACCESS_H #define _GPXE_UACCESS_H /** * @file * * Access to external ("user") memory * * gPXE often needs to transfer data between internal and external * buffers. On i386, the external buffers may require access via a * different segment, and the buffer address cannot be encoded into a * simple void * pointer. The @c userptr_t type encapsulates the * information needed to identify an external buffer, and the * copy_to_user() and copy_from_user() functions provide methods for * transferring data between internal and external buffers. * * Note that userptr_t is an opaque type; in particular, performing * arithmetic upon a userptr_t is not allowed. * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include /** * A pointer to a user buffer * */ typedef unsigned long userptr_t; /** Equivalent of NULL for user pointers */ #define UNULL ( ( userptr_t ) 0 ) /** * @defgroup uaccess_trivial Trivial user access API implementations * * User access API implementations that can be used by environments in * which virtual addresses allow access to all of memory. * * @{ * */ /** * Convert virtual address to user pointer * * @v addr Virtual address * @ret userptr User pointer */ static inline __always_inline userptr_t trivial_virt_to_user ( volatile const void *addr ) { return ( ( userptr_t ) addr ); } /** * Convert user pointer to virtual address * * @v userptr User pointer * @v offset Offset from user pointer * @ret addr Virtual address * * This operation is not available under all memory models. */ static inline __always_inline void * trivial_user_to_virt ( userptr_t userptr, off_t offset ) { return ( ( void * ) userptr + offset ); } /** * Add offset to user pointer * * @v userptr User pointer * @v offset Offset * @ret userptr New pointer value */ static inline __always_inline userptr_t trivial_userptr_add ( userptr_t userptr, off_t offset ) { return ( userptr + offset ); } /** * Copy data between user buffers * * @v dest Destination * @v dest_off Destination offset * @v src Source * @v src_off Source offset * @v len Length */ static inline __always_inline void trivial_memcpy_user ( userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len ) { memcpy ( ( ( void * ) dest + dest_off ), ( ( void * ) src + src_off ), len ); } /** * Copy data between user buffers, allowing for overlap * * @v dest Destination * @v dest_off Destination offset * @v src Source * @v src_off Source offset * @v len Length */ static inline __always_inline void trivial_memmove_user ( userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len ) { memmove ( ( ( void * ) dest + dest_off ), ( ( void * ) src + src_off ), len ); } /** * Fill user buffer with a constant byte * * @v buffer User buffer * @v offset Offset within buffer * @v c Constant byte with which to fill * @v len Length */ static inline __always_inline void trivial_memset_user ( userptr_t buffer, off_t offset, int c, size_t len ) { memset ( ( ( void * ) buffer + offset ), c, len ); } /** * Find length of NUL-terminated string in user buffer * * @v buffer User buffer * @v offset Offset within buffer * @ret len Length of string (excluding NUL) */ static inline __always_inline size_t trivial_strlen_user ( userptr_t buffer, off_t offset ) { return strlen ( ( void * ) buffer + offset ); } /** * Find character in user buffer * * @v buffer User buffer * @v offset Starting offset within buffer * @v c Character to search for * @v len Length of user buffer * @ret offset Offset of character, or <0 if not found */ static inline __always_inline off_t trivial_memchr_user ( userptr_t buffer, off_t offset, int c, size_t len ) { void *found; found = memchr ( ( ( void * ) buffer + offset ), c, len ); return ( found ? ( found - ( void * ) buffer ) : -1 ); } /** @} */ /** * Calculate static inline user access API function name * * @v _prefix Subsystem prefix * @v _api_func API function * @ret _subsys_func Subsystem API function */ #define UACCESS_INLINE( _subsys, _api_func ) \ SINGLE_API_INLINE ( UACCESS_PREFIX_ ## _subsys, _api_func ) /** * Provide an user access API implementation * * @v _prefix Subsystem prefix * @v _api_func API function * @v _func Implementing function */ #define PROVIDE_UACCESS( _subsys, _api_func, _func ) \ PROVIDE_SINGLE_API ( UACCESS_PREFIX_ ## _subsys, _api_func, _func ) /** * Provide a static inline user access API implementation * * @v _prefix Subsystem prefix * @v _api_func API function */ #define PROVIDE_UACCESS_INLINE( _subsys, _api_func ) \ PROVIDE_SINGLE_API_INLINE ( UACCESS_PREFIX_ ## _subsys, _api_func ) /* Include all architecture-independent user access API headers */ #include /* Include all architecture-dependent user access API headers */ #include /** * Convert physical address to user pointer * * @v phys_addr Physical address * @ret userptr User pointer */ userptr_t phys_to_user ( unsigned long phys_addr ); /** * Convert user pointer to physical address * * @v userptr User pointer * @v offset Offset from user pointer * @ret phys_addr Physical address */ unsigned long user_to_phys ( userptr_t userptr, off_t offset ); /** * Convert virtual address to user pointer * * @v addr Virtual address * @ret userptr User pointer */ userptr_t virt_to_user ( volatile const void *addr ); /** * Convert user pointer to virtual address * * @v userptr User pointer * @v offset Offset from user pointer * @ret addr Virtual address * * This operation is not available under all memory models. */ void * user_to_virt ( userptr_t userptr, off_t offset ); /** * Add offset to user pointer * * @v userptr User pointer * @v offset Offset * @ret userptr New pointer value */ userptr_t userptr_add ( userptr_t userptr, off_t offset ); /** * Convert virtual address to a physical address * * @v addr Virtual address * @ret phys_addr Physical address */ static inline __always_inline unsigned long virt_to_phys ( volatile const void *addr ) { return user_to_phys ( virt_to_user ( addr ), 0 ); } /** * Convert physical address to a virtual address * * @v addr Virtual address * @ret phys_addr Physical address * * This operation is not available under all memory models. */ static inline __always_inline void * phys_to_virt ( unsigned long phys_addr ) { return user_to_virt ( phys_to_user ( phys_addr ), 0 ); } /** * Copy data between user buffers * * @v dest Destination * @v dest_off Destination offset * @v src Source * @v src_off Source offset * @v len Length */ void memcpy_user ( userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len ); /** * Copy data to user buffer * * @v dest Destination * @v dest_off Destination offset * @v src Source * @v len Length */ static inline __always_inline void copy_to_user ( userptr_t dest, off_t dest_off, const void *src, size_t len ) { memcpy_user ( dest, dest_off, virt_to_user ( src ), 0, len ); } /** * Copy data from user buffer * * @v dest Destination * @v src Source * @v src_off Source offset * @v len Length */ static inline __always_inline void copy_from_user ( void *dest, userptr_t src, off_t src_off, size_t len ) { memcpy_user ( virt_to_user ( dest ), 0, src, src_off, len ); } /** * Copy data between user buffers, allowing for overlap * * @v dest Destination * @v dest_off Destination offset * @v src Source * @v src_off Source offset * @v len Length */ void memmove_user ( userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len ); /** * Fill user buffer with a constant byte * * @v userptr User buffer * @v offset Offset within buffer * @v c Constant byte with which to fill * @v len Length */ void memset_user ( userptr_t userptr, off_t offset, int c, size_t len ); /** * Find length of NUL-terminated string in user buffer * * @v userptr User buffer * @v offset Offset within buffer * @ret len Length of string (excluding NUL) */ size_t strlen_user ( userptr_t userptr, off_t offset ); /** * Find character in user buffer * * @v userptr User buffer * @v offset Starting offset within buffer * @v c Character to search for * @v len Length of user buffer * @ret offset Offset of character, or <0 if not found */ off_t memchr_user ( userptr_t userptr, off_t offset, int c, size_t len ); #endif /* _GPXE_UACCESS_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/profile.h0000664000000000000000000000354512524662415021151 0ustar #ifndef _GPXE_PROFILE_H #define _GPXE_PROFILE_H /** @file * * Profiling * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** * A data structure for storing profiling information */ union profiler { /** Timestamp (in CPU-specific "ticks") */ uint64_t timestamp; /** Registers returned by rdtsc. * * This part should really be architecture-specific code. */ struct { uint32_t eax; uint32_t edx; } rdtsc; }; /** * Static per-object profiler, for use with simple_profile() */ static union profiler simple_profiler; /** * Perform profiling * * @v profiler Profiler data structure * @ret delta Elapsed ticks since last call to profile(). * * Call profile() both before and after the code you wish to measure. * The "after" call will return the measurement. For example: * * @code * * profile ( &profiler ); * ... do something here ... * printf ( "It took %ld ticks to execute\n", profile ( &profiler ) ); * * @endcode */ static inline __attribute__ (( always_inline )) unsigned long profile ( union profiler *profiler ) { uint64_t last_timestamp = profiler->timestamp; __asm__ __volatile__ ( "rdtsc" : "=a" ( profiler->rdtsc.eax ), "=d" ( profiler->rdtsc.edx ) ); return ( profiler->timestamp - last_timestamp ); } /** * Perform profiling * * @ret delta Elapsed ticks since last call to profile(). * * When you only need one profiler, you can avoid the hassle of * creating your own @c profiler data structure by using * simple_profile() instead. * * simple_profile() is equivalent to profile(&simple_profiler), where * @c simple_profiler is a @c profiler data structure that is static * to each object which includes @c profile.h. */ static inline __attribute__ (( always_inline )) unsigned long simple_profile ( void ) { return profile ( &simple_profiler ); } #endif /* _GPXE_PROFILE_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/retry.h0000664000000000000000000000364312524662415020655 0ustar #ifndef _GPXE_RETRY_H #define _GPXE_RETRY_H /** @file * * Retry timers * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** Default timeout value */ #define DEFAULT_MIN_TIMEOUT ( TICKS_PER_SEC / 4 ) /** Limit after which the timeout will be deemed permanent */ #define DEFAULT_MAX_TIMEOUT ( 10 * TICKS_PER_SEC ) /** A retry timer */ struct retry_timer { /** List of active timers */ struct list_head list; /** Timer is currently running */ unsigned int running; /** Timeout value (in ticks) */ unsigned long timeout; /** Minimum timeout value (in ticks) * * A value of zero means "use default timeout." */ unsigned long min_timeout; /** Maximum timeout value before failure (in ticks) * * A value of zero means "use default timeout." */ unsigned long max_timeout; /** Start time (in ticks) */ unsigned long start; /** Retry count */ unsigned int count; /** Timer expired callback * * @v timer Retry timer * @v fail Failure indicator * * The timer will already be stopped when this method is * called. The failure indicator will be True if the retry * timeout has already exceeded @c MAX_TIMEOUT. */ void ( * expired ) ( struct retry_timer *timer, int over ); }; extern void start_timer ( struct retry_timer *timer ); extern void start_timer_fixed ( struct retry_timer *timer, unsigned long timeout ); extern void stop_timer ( struct retry_timer *timer ); /** * Start timer with no delay * * @v timer Retry timer * * This starts the timer running with a zero timeout value. */ static inline void start_timer_nodelay ( struct retry_timer *timer ) { start_timer_fixed ( timer, 0 ); } /** * Test to see if timer is currently running * * @v timer Retry timer * @ret running Non-zero if timer is running */ static inline __attribute__ (( always_inline )) unsigned long timer_running ( struct retry_timer *timer ) { return ( timer->running ); } #endif /* _GPXE_RETRY_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/errortab.h0000664000000000000000000000053312524662415021323 0ustar #ifndef _GPXE_ERRORTAB_H #define _GPXE_ERRORTAB_H /** @file * * Error message tables * */ FILE_LICENCE ( GPL2_OR_LATER ); #include struct errortab { int errno; const char *text; }; #define ERRORTAB __table ( struct errortab, "errortab" ) #define __errortab __table_entry ( ERRORTAB, 01 ) #endif /* _GPXE_ERRORTAB_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/srp.h0000664000000000000000000005267512524662415020325 0ustar #ifndef _GPXE_SRP_H #define _GPXE_SRP_H /** @file * * SCSI RDMA Protocol * */ FILE_LICENCE ( BSD2 ); #include #include #include #include #include /***************************************************************************** * * Common fields * ***************************************************************************** */ /** An SRP information unit tag */ struct srp_tag { uint32_t dwords[2]; } __attribute__ (( packed )); /** An SRP port ID */ struct srp_port_id { uint8_t bytes[16]; } __attribute__ (( packed )); /** An SRP port ID pair */ struct srp_port_ids { /** Initiator port ID */ struct srp_port_id initiator; /** Target port ID */ struct srp_port_id target; } __attribute__ (( packed )); /** SRP information unit common fields */ struct srp_common { /** Information unit type */ uint8_t type; /** Reserved */ uint8_t reserved0[7]; /** Tag */ struct srp_tag tag; } __attribute__ (( packed )); /***************************************************************************** * * Login request * ***************************************************************************** */ /** An SRP login request information unit */ struct srp_login_req { /** Information unit type * * This must be @c SRP_LOGIN_REQ */ uint8_t type; /** Reserved */ uint8_t reserved0[7]; /** Tag */ struct srp_tag tag; /** Requested maximum initiator to target IU length */ uint32_t max_i_t_iu_len; /** Reserved */ uint8_t reserved1[4]; /** Required buffer formats * * This is the bitwise OR of one or more @c * SRP_LOGIN_REQ_FMT_XXX constants. */ uint16_t required_buffer_formats; /** Flags * * This is the bitwise OR of zero or more @c * SRP_LOGIN_REQ_FLAG_XXX and @c SRP_LOGIN_REQ_MCA_XXX * constants. */ uint8_t flags; /** Reserved */ uint8_t reserved2[5]; /** Initiator and target port identifiers */ struct srp_port_ids port_ids; } __attribute__ (( packed )); /** Type of an SRP login request */ #define SRP_LOGIN_REQ 0x00 /** Require indirect data buffer descriptor format */ #define SRP_LOGIN_REQ_FMT_IDBD 0x04 /** Require direct data buffer descriptor format */ #define SRP_LOGIN_REQ_FMT_DDBD 0x02 /** Use solicited notification for asynchronous events */ #define SRP_LOGIN_REQ_FLAG_AESOLNT 0x40 /** Use solicited notification for credit request */ #define SRP_LOGIN_REQ_FLAG_CRSOLNT 0x20 /** Use solicited notification for logouts */ #define SRP_LOGIN_REQ_FLAG_LOSOLNT 0x10 /** Multi-channel action mask */ #define SRP_LOGIN_REQ_MCA_MASK 0x03 /** Single RDMA channel operation */ #define SRP_LOGIN_REQ_MCA_SINGLE_CHANNEL 0x00 /** Multiple independent RDMA channel operation */ #define SRP_LOGIN_REQ_MCA_MULTIPLE_CHANNELS 0x01 /***************************************************************************** * * Login response * ***************************************************************************** */ /** An SRP login response */ struct srp_login_rsp { /** Information unit type * * This must be @c SRP_LOGIN_RSP */ uint8_t type; /** Reserved */ uint8_t reserved0[3]; /** Request limit delta */ uint32_t request_limit_delta; /** Tag */ struct srp_tag tag; /** Maximum initiator to target IU length */ uint32_t max_i_t_iu_len; /** Maximum target to initiator IU length */ uint32_t max_t_i_iu_len; /** Supported buffer formats * * This is the bitwise OR of one or more @c * SRP_LOGIN_RSP_FMT_XXX constants. */ uint16_t supported_buffer_formats; /** Flags * * This is the bitwise OR of zero or more @c * SRP_LOGIN_RSP_FLAG_XXX and @c SRP_LOGIN_RSP_MCR_XXX * constants. */ uint8_t flags; /** Reserved */ uint8_t reserved1[25]; } __attribute__ (( packed )); /** Type of an SRP login response */ #define SRP_LOGIN_RSP 0xc0 /** Indirect data buffer descriptor format supported */ #define SRP_LOGIN_RSP_FMT_IDBD 0x04 /** Direct data buffer descriptor format supported */ #define SRP_LOGIN_RSP_FMT_DDBD 0x02 /** Solicited notification is supported */ #define SRP_LOGIN_RSP_FLAG_SOLNTSUP 0x10 /** Multi-channel result mask */ #define SRP_LOGIN_RSP_MCR_MASK 0x03 /** No existing RDMA channels were associated with the same I_T nexus */ #define SRP_LOGIN_RSP_MCR_NO_EXISTING_CHANNELS 0x00 /** One or more existing RDMA channels were terminated */ #define SRP_LOGIN_RSP_MCR_EXISTING_CHANNELS_TERMINATED 0x01 /** One or more existing RDMA channels continue to operate independently */ #define SRP_LOGIN_RSP_MCR_EXISTING_CHANNELS_CONTINUE 0x02 /***************************************************************************** * * Login rejection * ***************************************************************************** */ /** An SRP login rejection */ struct srp_login_rej { /** Information unit type * * This must be @c SRP_LOGIN_REJ */ uint8_t type; /** Reserved */ uint8_t reserved0[3]; /** Reason * * This is a @c SRP_LOGIN_REJ_REASON_XXX constant. */ uint32_t reason; /** Tag */ struct srp_tag tag; /** Reserved */ uint8_t reserved1[8]; /** Supported buffer formats * * This is the bitwise OR of one or more @c * SRP_LOGIN_REJ_FMT_XXX constants. */ uint16_t supported_buffer_formats; /** Reserved */ uint8_t reserved2[6]; } __attribute__ (( packed )); /** Type of an SRP login rejection */ #define SRP_LOGIN_REJ 0xc2 /** Unable to establish RDMA channel, no reason specified */ #define SRP_LOGIN_REJ_REASON_UNKNOWN 0x00010000UL /** Insufficient RDMA channel resources */ #define SRP_LOGIN_REJ_REASON_INSUFFICIENT_RESOURCES 0x00010001UL /** Requested maximum initiator to target IU length value too large */ #define SRP_LOGIN_REJ_REASON_BAD_MAX_I_T_IU_LEN 0x00010002UL /** Unable to associate RDMA channel with specified I_T nexus */ #define SRP_LOGIN_REJ_REASON_CANNOT_ASSOCIATE 0x00010003UL /** One or more requested data buffer descriptor formats are not supported */ #define SRP_LOGIN_REJ_REASON_UNSUPPORTED_BUFFER_FORMAT 0x00010004UL /** SRP target port does not support multiple RDMA channels per I_T nexus */ #define SRP_LOGIN_REJ_REASON_NO_MULTIPLE_CHANNELS 0x00010005UL /** RDMA channel limit reached for this initiator */ #define SRP_LOGIN_REJ_REASON_NO_MORE_CHANNELS 0x00010006UL /** Indirect data buffer descriptor format supported */ #define SRP_LOGIN_REJ_FMT_IDBD 0x04 /** Direct data buffer descriptor format supported */ #define SRP_LOGIN_REJ_FMT_DDBD 0x02 /***************************************************************************** * * Initiator logout * ***************************************************************************** */ /** An SRP initiator logout request */ struct srp_i_logout { /** Information unit type * * This must be @c SRP_I_LOGOUT */ uint8_t type; /** Reserved */ uint8_t reserved0[7]; /** Tag */ struct srp_tag tag; } __attribute__ (( packed )); /** Type of an SRP initiator logout request */ #define SRP_I_LOGOUT 0x03 /***************************************************************************** * * Target logout * ***************************************************************************** */ /** An SRP target logout request */ struct srp_t_logout { /** Information unit type * * This must be @c SRP_T_LOGOUT */ uint8_t type; /** Flags * * This is the bitwise OR of zero or more @c * SRP_T_LOGOUT_FLAG_XXX constants. */ uint8_t flags; /** Reserved */ uint8_t reserved0[2]; /** Reason * * This is a @c SRP_T_LOGOUT_REASON_XXX constant. */ uint32_t reason; /** Tag */ struct srp_tag tag; } __attribute__ (( packed )); /** Type of an SRP target logout request */ #define SRP_T_LOGOUT 0x80 /** The initiator specified solicited notification of logouts */ #define SRP_T_LOGOUT_FLAG_SOLNT 0x01 /** No reason specified */ #define SRP_T_LOGOUT_REASON_UNKNOWN 0x00000000UL /** Inactive RDMA channel (reclaiming resources) */ #define SRP_T_LOGOUT_REASON_INACTIVE 0x00000001UL /** Invalid information unit type code received by SRP target port */ #define SRP_T_LOGOUT_REASON_INVALID_TYPE 0x00000002UL /** SRP initiator port sent response with no corresponding request */ #define SRP_T_LOGOUT_REASON_SPURIOUS_RESPONSE 0x00000003UL /** RDMA channel disconnected due to multi-channel action code in new login */ #define SRP_T_LOGOUT_REASON_MCA 0x00000004UL /** Unsuppported format code value specified in data-out buffer descriptor */ #define SRP_T_LOGOUT_UNSUPPORTED_DATA_OUT_FORMAT 0x00000005UL /** Unsuppported format code value specified in data-in buffer descriptor */ #define SRP_T_LOGOUT_UNSUPPORTED_DATA_IN_FORMAT 0x00000006UL /** Invalid length for IU type */ #define SRP_T_LOGOUT_INVALID_IU_LEN 0x00000008UL /***************************************************************************** * * Task management * ***************************************************************************** */ /** An SRP task management request */ struct srp_tsk_mgmt { /** Information unit type * * This must be @c SRP_TSK_MGMT */ uint8_t type; /** Flags * * This is the bitwise OR of zero or more * @c SRP_TSK_MGMT_FLAG_XXX constants. */ uint8_t flags; /** Reserved */ uint8_t reserved0[6]; /** Tag */ struct srp_tag tag; /** Reserved */ uint8_t reserved1[4]; /** Logical unit number */ struct scsi_lun lun; /** Reserved */ uint8_t reserved2[2]; /** Task management function * * This is a @c SRP_TASK_MGMT_FUNC_XXX constant */ uint8_t function; /** Reserved */ uint8_t reserved3[1]; /** Tag of task to be managed */ struct srp_tag managed_tag; /** Reserved */ uint8_t reserved4[8]; } __attribute__ (( packed )); /** Type of an SRP task management request */ #define SRP_TSK_MGMT 0x01 /** Use solicited notification for unsuccessful completions */ #define SRP_TSK_MGMT_FLAG_UCSOLNT 0x04 /** Use solicited notification for successful completions */ #define SRP_TSK_MGMT_FLAG_SCSOLNT 0x02 /** The task manager shall perform an ABORT TASK function */ #define SRP_TSK_MGMT_FUNC_ABORT_TASK 0x01 /** The task manager shall perform an ABORT TASK SET function */ #define SRP_TSK_MGMT_FUNC_ABORT_TASK_SET 0x02 /** The task manager shall perform a CLEAR TASK SET function */ #define SRP_TSK_MGMT_FUNC_CLEAR_TASK_SET 0x04 /** The task manager shall perform a LOGICAL UNIT RESET function */ #define SRP_TSK_MGMT_FUNC_LOGICAL_UNIT_RESET 0x08 /** The task manager shall perform a CLEAR ACA function */ #define SRP_TSK_MGMT_FUNC_CLEAR_ACA 0x40 /***************************************************************************** * * SCSI command * ***************************************************************************** */ /** An SRP SCSI command */ struct srp_cmd { /** Information unit type * * This must be @c SRP_CMD */ uint8_t type; /** Flags * * This is the bitwise OR of zero or more @c SRP_CMD_FLAG_XXX * constants. */ uint8_t flags; /** Reserved */ uint8_t reserved0[3]; /** Data buffer descriptor formats * * This is the bitwise OR of one @c SRP_CMD_DO_FMT_XXX and one @c * SRP_CMD_DI_FMT_XXX constant. */ uint8_t data_buffer_formats; /** Data-out buffer descriptor count */ uint8_t data_out_buffer_count; /** Data-in buffer descriptor count */ uint8_t data_in_buffer_count; /** Tag */ struct srp_tag tag; /** Reserved */ uint8_t reserved1[4]; /** Logical unit number */ struct scsi_lun lun; /** Reserved */ uint8_t reserved2[1]; /** Task attribute * * This is a @c SRP_CMD_TASK_ATTR_XXX constant. */ uint8_t task_attr; /** Reserved */ uint8_t reserved3[1]; /** Additional CDB length */ uint8_t additional_cdb_len; /** Command data block */ union scsi_cdb cdb; } __attribute__ (( packed )); /** Type of an SRP SCSI command */ #define SRP_CMD 0x02 /** Use solicited notification for unsuccessful completions */ #define SRP_CMD_FLAG_UCSOLNT 0x04 /** Use solicited notification for successful completions */ #define SRP_CMD_FLAG_SCSOLNT 0x02 /** Data-out buffer format mask */ #define SRP_CMD_DO_FMT_MASK 0xf0 /** Direct data-out buffer format */ #define SRP_CMD_DO_FMT_DIRECT 0x10 /** Indirect data-out buffer format */ #define SRP_CMD_DO_FMT_INDIRECT 0x20 /** Data-in buffer format mask */ #define SRP_CMD_DI_FMT_MASK 0x0f /** Direct data-in buffer format */ #define SRP_CMD_DI_FMT_DIRECT 0x01 /** Indirect data-in buffer format */ #define SRP_CMD_DI_FMT_INDIRECT 0x02 /** Use the rules for a simple task attribute */ #define SRP_CMD_TASK_ATTR_SIMPLE 0x00 /** Use the rules for a head of queue task attribute */ #define SRP_CMD_TASK_ATTR_QUEUE_HEAD 0x01 /** Use the rules for an ordered task attribute */ #define SRP_CMD_TASK_ATTR_ORDERED 0x02 /** Use the rules for an automatic contingent allegiance task attribute */ #define SRP_CMD_TASK_ATTR_AUTOMATIC_CONTINGENT_ALLEGIANCE 0x08 /** An SRP memory descriptor */ struct srp_memory_descriptor { /** Virtual address */ uint64_t address; /** Memory handle */ uint32_t handle; /** Data length */ uint32_t len; } __attribute__ (( packed )); /***************************************************************************** * * SCSI response * ***************************************************************************** */ /** An SRP SCSI response */ struct srp_rsp { /** Information unit type * * This must be @c SRP_RSP */ uint8_t type; /** Flags * * This is the bitwise OR of zero or more @c SRP_RSP_FLAG_XXX * constants. */ uint8_t flags; /** Reserved */ uint8_t reserved0[2]; /** Request limit delta */ uint32_t request_limit_delta; /** Tag */ struct srp_tag tag; /** Reserved */ uint8_t reserved1[2]; /** Valid fields * * This is the bitwise OR of zero or more @c SRP_RSP_VALID_XXX * constants. */ uint8_t valid; /** Status * * This is the SCSI status code. */ uint8_t status; /** Data-out residual count */ uint32_t data_out_residual_count; /** Data-in residual count */ uint32_t data_in_residual_count; /** Sense data list length */ uint32_t sense_data_len; /** Response data list length */ uint32_t response_data_len; } __attribute__ (( packed )); /** Type of an SRP SCSI response */ #define SRP_RSP 0xc1 /** The initiator specified solicited notification of this response */ #define SRP_RSP_FLAG_SOLNT 0x01 /** Data-in residual count field is valid and represents an underflow */ #define SRP_RSP_VALID_DIUNDER 0x20 /** Data-in residual count field is valid and represents an overflow */ #define SRP_RSP_VALID_DIOVER 0x10 /** Data-out residual count field is valid and represents an underflow */ #define SRP_RSP_VALID_DOUNDER 0x08 /** Data-out residual count field is valid and represents an overflow */ #define SRP_RSP_VALID_DOOVER 0x04 /** Sense data list length field is valid */ #define SRP_RSP_VALID_SNSVALID 0x02 /** Response data list length field is valid */ #define SRP_RSP_VALID_RSPVALID 0x01 /** * Get response data portion of SCSI response * * @v rsp SCSI response * @ret response_data Response data, or NULL if not present */ static inline void * srp_rsp_response_data ( struct srp_rsp *rsp ) { return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ? ( ( ( void * ) rsp ) + sizeof ( *rsp ) ) : NULL ); } /** * Get length of response data portion of SCSI response * * @v rsp SCSI response * @ret response_data_len Response data length */ static inline size_t srp_rsp_response_data_len ( struct srp_rsp *rsp ) { return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ? ntohl ( rsp->response_data_len ) : 0 ); } /** * Get sense data portion of SCSI response * * @v rsp SCSI response * @ret sense_data Sense data, or NULL if not present */ static inline void * srp_rsp_sense_data ( struct srp_rsp *rsp ) { return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ? ( ( ( void * ) rsp ) + sizeof ( *rsp ) + srp_rsp_response_data_len ( rsp ) ) : NULL ); } /** * Get length of sense data portion of SCSI response * * @v rsp SCSI response * @ret sense_data_len Sense data length */ static inline size_t srp_rsp_sense_data_len ( struct srp_rsp *rsp ) { return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ? ntohl ( rsp->sense_data_len ) : 0 ); } /***************************************************************************** * * Credit request * ***************************************************************************** */ /** An SRP credit request */ struct srp_cred_req { /** Information unit type * * This must be @c SRP_CRED_REQ */ uint8_t type; /** Flags * * This is the bitwise OR of zero or more * @c SRP_CRED_REQ_FLAG_XXX constants. */ uint8_t flags; /** Reserved */ uint8_t reserved0[2]; /** Request limit delta */ uint32_t request_limit_delta; /** Tag */ struct srp_tag tag; } __attribute__ (( packed )); /** Type of an SRP credit request */ #define SRP_CRED_REQ 0x81 /** The initiator specified solicited notification of credit requests */ #define SRP_CRED_REQ_FLAG_SOLNT 0x01 /***************************************************************************** * * Credit response * ***************************************************************************** */ /** An SRP credit response */ struct srp_cred_rsp { /** Information unit type * * This must be @c SRP_CRED_RSP */ uint8_t type; /** Reserved */ uint8_t reserved0[7]; /** Tag */ struct srp_tag tag; } __attribute__ (( packed )); /** Type of an SRP credit response */ #define SRP_CRED_RSP 0x41 /***************************************************************************** * * Asynchronous event request * ***************************************************************************** */ /** An SRP asynchronous event request */ struct srp_aer_req { /** Information unit type * * This must be @c SRP_AER_REQ */ uint8_t type; /** Flags * * This is the bitwise OR of zero or more @c * SRP_AER_REQ_FLAG_XXX constants. */ uint8_t flags; /** Reserved */ uint8_t reserved0[2]; /** Request limit delta */ uint32_t request_limit_delta; /** Tag */ struct srp_tag tag; /** Reserved */ uint8_t reserved1[4]; /** Logical unit number */ struct scsi_lun lun; /** Sense data list length */ uint32_t sense_data_len; /** Reserved */ uint8_t reserved2[4]; } __attribute__ (( packed )); /** Type of an SRP asynchronous event request */ #define SRP_AER_REQ 0x82 /** The initiator specified solicited notification of asynchronous events */ #define SRP_AER_REQ_FLAG_SOLNT 0x01 /** * Get sense data portion of asynchronous event request * * @v aer_req SRP asynchronous event request * @ret sense_data Sense data */ static inline __always_inline void * srp_aer_req_sense_data ( struct srp_aer_req *aer_req ) { return ( ( ( void * ) aer_req ) + sizeof ( *aer_req ) ); } /** * Get length of sense data portion of asynchronous event request * * @v aer_req SRP asynchronous event request * @ret sense_data_len Sense data length */ static inline __always_inline size_t srp_aer_req_sense_data_len ( struct srp_aer_req *aer_req ) { return ( ntohl ( aer_req->sense_data_len ) ); } /***************************************************************************** * * Asynchronous event response * ***************************************************************************** */ /** An SRP asynchronous event response */ struct srp_aer_rsp { /** Information unit type * * This must be @c SRP_AER_RSP */ uint8_t type; /** Reserved */ uint8_t reserved0[7]; /** Tag */ struct srp_tag tag; } __attribute__ (( packed )); /** Type of an SRP asynchronous event response */ #define SRP_AER_RSP 0x42 /***************************************************************************** * * Information units * ***************************************************************************** */ /** Maximum length of any initiator-to-target IU that we will send * * The longest IU is a SRP_CMD with no additional CDB and two direct * data buffer descriptors, which comes to 80 bytes. */ #define SRP_MAX_I_T_IU_LEN 80 /***************************************************************************** * * SRP device * ***************************************************************************** */ struct srp_device; /** An SRP transport type */ struct srp_transport_type { /** Length of transport private data */ size_t priv_len; /** Parse root path * * @v srp SRP device * @v root_path Root path * @ret Return status code */ int ( * parse_root_path ) ( struct srp_device *srp, const char *root_path ); /** Connect SRP session * * @v srp SRP device * @ret rc Return status code * * This method should open the underlying socket. */ int ( * connect ) ( struct srp_device *srp ); }; /** An SRP device */ struct srp_device { /** Reference count */ struct refcnt refcnt; /** Initiator and target port IDs */ struct srp_port_ids port_ids; /** Logical unit number */ struct scsi_lun lun; /** Memory handle */ uint32_t memory_handle; /** Current state * * This is the bitwise-OR of zero or more @c SRP_STATE_XXX * flags. */ unsigned int state; /** Retry counter */ unsigned int retry_count; /** Current SCSI command */ struct scsi_command *command; /** Underlying data transfer interface */ struct xfer_interface socket; /** Transport type */ struct srp_transport_type *transport; /** Transport private data */ char transport_priv[0]; }; /** * Get SRP transport private data * * @v srp SRP device * @ret priv SRP transport private data */ static inline __always_inline void * srp_transport_priv ( struct srp_device *srp ) { return ( ( void * ) srp->transport_priv ); } /** SRP state flags */ enum srp_state { /** Underlying socket is open */ SRP_STATE_SOCKET_OPEN = 0x0001, /** Session is logged in */ SRP_STATE_LOGGED_IN = 0x0002, }; /** Maximum number of SRP retry attempts */ #define SRP_MAX_RETRIES 3 extern int srp_attach ( struct scsi_device *scsi, const char *root_path ); extern void srp_detach ( struct scsi_device *scsi ); #endif /* _GPXE_SRP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ib_smc.h0000664000000000000000000000056612524662415020745 0ustar #ifndef _GPXE_IB_SMC_H #define _GPXE_IB_SMC_H /** @file * * Infiniband Subnet Management Client * */ FILE_LICENCE ( GPL2_OR_LATER ); #include typedef int ( * ib_local_mad_t ) ( struct ib_device *ibdev, union ib_mad *mad ); extern int ib_smc_update ( struct ib_device *ibdev, ib_local_mad_t local_mad ); #endif /* _GPXE_IB_SMC_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/settings_ui.h0000664000000000000000000000040312524662415022034 0ustar #ifndef _GPXE_SETTINGS_UI_H #define _GPXE_SETTINGS_UI_H /** @file * * Option configuration console * */ FILE_LICENCE ( GPL2_OR_LATER ); struct settings; extern int settings_ui ( struct settings *settings ) __nonnull; #endif /* _GPXE_SETTINGS_UI_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/uuid.h0000664000000000000000000000114112524662415020445 0ustar #ifndef _GPXE_UUID_H #define _GPXE_UUID_H /** @file * * Universally unique IDs */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** A universally unique ID */ union uuid { /** Canonical form (00000000-0000-0000-0000-000000000000) */ struct { /** 8 hex digits, big-endian */ uint32_t a; /** 2 hex digits, big-endian */ uint16_t b; /** 2 hex digits, big-endian */ uint16_t c; /** 2 hex digits, big-endian */ uint16_t d; /** 12 hex digits, big-endian */ uint8_t e[6]; } canonical; uint8_t raw[16]; }; extern char * uuid_ntoa ( union uuid *uuid ); #endif /* _GPXE_UUID_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/rarp.h0000664000000000000000000000034312524662415020446 0ustar #ifndef _GPXE_RARP_H #define _GPXE_RARP_H /** @file * * Reverse Address Resolution Protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); struct net_protocol; extern struct net_protocol rarp_protocol; #endif /* _GPXE_RARP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/udp.h0000664000000000000000000000140612524662415020273 0ustar #ifndef _GPXE_UDP_H #define _GPXE_UDP_H /** @file * * UDP protocol * * This file defines the gPXE UDP API. * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include struct xfer_interface; /** * UDP constants */ #define UDP_MAX_HLEN 72 #define UDP_MAX_TXIOB ETH_MAX_MTU #define UDP_MIN_TXIOB ETH_ZLEN /** * A UDP header */ struct udp_header { /** Source port */ uint16_t src; /** Destination port */ uint16_t dest; /** Length */ uint16_t len; /** Checksum */ uint16_t chksum; }; extern int udp_open_promisc ( struct xfer_interface *xfer ); extern int udp_open ( struct xfer_interface *xfer, struct sockaddr *peer, struct sockaddr *local ); #endif /* _GPXE_UDP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/dhcppkt.h0000664000000000000000000000262112524662415021140 0ustar #ifndef _GPXE_DHCPPKT_H #define _GPXE_DHCPPKT_H /** @file * * DHCP packets * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include /** * A DHCP packet * */ struct dhcp_packet { /** Reference counter */ struct refcnt refcnt; /** The DHCP packet contents */ struct dhcphdr *dhcphdr; /** Maximum length of the DHCP packet buffer */ size_t max_len; /** Used length of the DHCP packet buffer */ size_t len; /** DHCP options */ struct dhcp_options options; /** Settings interface */ struct settings settings; }; /** * Increment reference count on DHCP packet * * @v dhcppkt DHCP packet * @ret dhcppkt DHCP packet */ static inline __attribute__ (( always_inline )) struct dhcp_packet * dhcppkt_get ( struct dhcp_packet *dhcppkt ) { ref_get ( &dhcppkt->refcnt ); return dhcppkt; } /** * Decrement reference count on DHCP packet * * @v dhcppkt DHCP packet */ static inline __attribute__ (( always_inline )) void dhcppkt_put ( struct dhcp_packet *dhcppkt ) { ref_put ( &dhcppkt->refcnt ); } extern int dhcppkt_store ( struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len ); extern int dhcppkt_fetch ( struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len ); extern void dhcppkt_init ( struct dhcp_packet *dhcppkt, struct dhcphdr *data, size_t len ); #endif /* _GPXE_DHCPPKT_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/nvo.h0000664000000000000000000000236212524662415020307 0ustar #ifndef _GPXE_NVO_H #define _GPXE_NVO_H /** @file * * Non-volatile stored options * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include struct nvs_device; struct refcnt; /** * A fragment of a non-volatile storage device used for stored options */ struct nvo_fragment { /** Starting address of fragment within NVS device */ unsigned int address; /** Length of fragment */ size_t len; }; /** * A block of non-volatile stored options */ struct nvo_block { /** Settings block */ struct settings settings; /** Underlying non-volatile storage device */ struct nvs_device *nvs; /** List of option-containing fragments * * The list is terminated by a fragment with a length of zero. */ struct nvo_fragment *fragments; /** Total length of option-containing fragments */ size_t total_len; /** Option-containing data */ void *data; /** DHCP options block */ struct dhcp_options dhcpopts; }; extern void nvo_init ( struct nvo_block *nvo, struct nvs_device *nvs, struct nvo_fragment *fragments, struct refcnt *refcnt ); extern int register_nvo ( struct nvo_block *nvo, struct settings *parent ); extern void unregister_nvo ( struct nvo_block *nvo ); #endif /* _GPXE_NVO_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/md5.h0000664000000000000000000000064212524662415020171 0ustar #ifndef _GPXE_MD5_H #define _GPXE_MD5_H FILE_LICENCE ( GPL2_OR_LATER ); struct digest_algorithm; #include #define MD5_DIGEST_SIZE 16 #define MD5_BLOCK_WORDS 16 #define MD5_HASH_WORDS 4 struct md5_ctx { u32 hash[MD5_HASH_WORDS]; u32 block[MD5_BLOCK_WORDS]; u64 byte_count; }; #define MD5_CTX_SIZE sizeof ( struct md5_ctx ) extern struct digest_algorithm md5_algorithm; #endif /* _GPXE_MD5_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/umalloc.h0000664000000000000000000000277212524662415021146 0ustar #ifndef _GPXE_UMALLOC_H #define _GPXE_UMALLOC_H /** * @file * * User memory allocation * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include /** * Provide a user memory allocation API implementation * * @v _prefix Subsystem prefix * @v _api_func API function * @v _func Implementing function */ #define PROVIDE_UMALLOC( _subsys, _api_func, _func ) \ PROVIDE_SINGLE_API ( UMALLOC_PREFIX_ ## _subsys, _api_func, _func ) /* Include all architecture-independent I/O API headers */ #include /* Include all architecture-dependent I/O API headers */ #include /** * Reallocate external memory * * @v userptr Memory previously allocated by umalloc(), or UNULL * @v new_size Requested size * @ret userptr Allocated memory, or UNULL * * Calling realloc() with a new size of zero is a valid way to free a * memory block. */ userptr_t urealloc ( userptr_t userptr, size_t new_size ); /** * Allocate external memory * * @v size Requested size * @ret userptr Memory, or UNULL * * Memory is guaranteed to be aligned to a page boundary. */ static inline __always_inline userptr_t umalloc ( size_t size ) { return urealloc ( UNULL, size ); } /** * Free external memory * * @v userptr Memory allocated by umalloc(), or UNULL * * If @c ptr is UNULL, no action is taken. */ static inline __always_inline void ufree ( userptr_t userptr ) { urealloc ( userptr, 0 ); } #endif /* _GPXE_UMALLOC_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/arp.h0000664000000000000000000000177212524662415020273 0ustar #ifndef _GPXE_ARP_H #define _GPXE_ARP_H /** @file * * Address Resolution Protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include struct net_device; struct net_protocol; /** A network-layer protocol that relies upon ARP */ struct arp_net_protocol { /** Network-layer protocol */ struct net_protocol *net_protocol; /** Check existence of address * * @v netdev Network device * @v net_addr Network-layer address * @ret rc Return status code */ int ( * check ) ( struct net_device *netdev, const void *net_addr ); }; /** ARP protocol table */ #define ARP_NET_PROTOCOLS \ __table ( struct arp_net_protocol, "arp_net_protocols" ) /** Declare an ARP protocol */ #define __arp_net_protocol __table_entry ( ARP_NET_PROTOCOLS, 01 ) extern struct net_protocol arp_protocol; extern int arp_resolve ( struct net_device *netdev, struct net_protocol *net_protocol, const void *dest_net_addr, const void *source_net_addr, void *dest_ll_addr ); #endif /* _GPXE_ARP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/shell.h0000664000000000000000000000026412524662415020613 0ustar #ifndef _GPXE_SHELL_H #define _GPXE_SHELL_H /** @file * * Minimal command shell * */ FILE_LICENCE ( GPL2_OR_LATER ); extern void shell ( void ); #endif /* _GPXE_SHELL_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/serial.h0000664000000000000000000000040512524662415020760 0ustar #ifndef _GPXE_SERIAL_H #define _GPXE_SERIAL_H /** @file * * Serial driver functions * */ FILE_LICENCE ( GPL2_OR_LATER ); extern void serial_putc ( int ch ); extern int serial_getc ( void ); extern int serial_ischar ( void ); #endif /* _GPXE_SERIAL_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/monojob.h0000664000000000000000000000041212524662415021142 0ustar #ifndef _GPXE_MONOJOB_H #define _GPXE_MONOJOB_H /** @file * * Single foreground job * */ FILE_LICENCE ( GPL2_OR_LATER ); struct job_interface; extern struct job_interface monojob; extern int monojob_wait ( const char *string ); #endif /* _GPXE_MONOJOB_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/linux_compat.h0000664000000000000000000000105612524662415022206 0ustar #ifndef _GPXE_LINUX_COMPAT_H #define _GPXE_LINUX_COMPAT_H /** @file * * Linux code compatibility * * This file exists to ease the building of Linux source code within * gPXE. This is intended to facilitate quick testing; it is not * intended to be a substitute for proper porting. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #define __init #define __exit #define __initdata #define __exitdata #define printk printf #endif /* _GPXE_LINUX_COMPAT_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ib_pathrec.h0000664000000000000000000000320512524662415021602 0ustar #ifndef _GPXE_IB_PATHREC_H #define _GPXE_IB_PATHREC_H /** @file * * Infiniband path records * */ FILE_LICENCE ( GPL2_OR_LATER ); #include struct ib_mad_transaction; struct ib_path; /** Infiniband path operations */ struct ib_path_operations { /** Handle path transaction completion * * @v ibdev Infiniband device * @v path Path * @v rc Status code * @v av Address vector, or NULL on error */ void ( * complete ) ( struct ib_device *ibdev, struct ib_path *path, int rc, struct ib_address_vector *av ); }; /** An Infiniband path */ struct ib_path { /** Infiniband device */ struct ib_device *ibdev; /** Address vector */ struct ib_address_vector av; /** Management transaction */ struct ib_mad_transaction *madx; /** Path operations */ struct ib_path_operations *op; /** Owner private data */ void *owner_priv; }; /** * Set Infiniband path owner-private data * * @v path Path * @v priv Private data */ static inline __always_inline void ib_path_set_ownerdata ( struct ib_path *path, void *priv ) { path->owner_priv = priv; } /** * Get Infiniband path owner-private data * * @v path Path * @ret priv Private data */ static inline __always_inline void * ib_path_get_ownerdata ( struct ib_path *path ) { return path->owner_priv; } extern struct ib_path * ib_create_path ( struct ib_device *ibdev, struct ib_address_vector *av, struct ib_path_operations *op ); extern void ib_destroy_path ( struct ib_device *ibdev, struct ib_path *path ); extern int ib_resolve_path ( struct ib_device *ibdev, struct ib_address_vector *av ); #endif /* _GPXE_IB_PATHREC_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ethernet.h0000664000000000000000000000067712524662415021332 0ustar #ifndef _GPXE_ETHERNET_H #define _GPXE_ETHERNET_H /** @file * * Ethernet protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include extern void eth_init_addr ( const void *hw_addr, void *ll_addr ); extern const char * eth_ntoa ( const void *ll_addr ); extern int eth_mc_hash ( unsigned int af, const void *net_addr, void *ll_addr ); extern struct net_device * alloc_etherdev ( size_t priv_size ); #endif /* _GPXE_ETHERNET_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/if_arp.h0000664000000000000000000000541512524662415020747 0ustar #ifndef _GPXE_IF_ARP_H #define _GPXE_IF_ARP_H /** @file * * Address Resolution Protocol constants and types * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /* ARP protocol HARDWARE identifiers. */ #define ARPHRD_NETROM 0 /**< from KA9Q: NET/ROM pseudo */ #define ARPHRD_ETHER 1 /**< Ethernet 10Mbps */ #define ARPHRD_EETHER 2 /**< Experimental Ethernet */ #define ARPHRD_AX25 3 /**< AX.25 Level 2 */ #define ARPHRD_PRONET 4 /**< PROnet token ring */ #define ARPHRD_CHAOS 5 /**< Chaosnet */ #define ARPHRD_IEEE802 6 /**< IEEE 802.2 Ethernet/TR/TB */ #define ARPHRD_ARCNET 7 /**< ARCnet */ #define ARPHRD_APPLETLK 8 /**< APPLEtalk */ #define ARPHRD_DLCI 15 /**< Frame Relay DLCI */ #define ARPHRD_ATM 19 /**< ATM */ #define ARPHRD_METRICOM 23 /**< Metricom STRIP (new IANA id) */ #define ARPHRD_IEEE1394 24 /**< IEEE 1394 IPv4 - RFC 2734 */ #define ARPHRD_EUI64 27 /**< EUI-64 */ #define ARPHRD_INFINIBAND 32 /**< InfiniBand */ /* ARP protocol opcodes. */ #define ARPOP_REQUEST 1 /**< ARP request */ #define ARPOP_REPLY 2 /**< ARP reply */ #define ARPOP_RREQUEST 3 /**< RARP request */ #define ARPOP_RREPLY 4 /**< RARP reply */ #define ARPOP_InREQUEST 8 /**< InARP request */ #define ARPOP_InREPLY 9 /**< InARP reply */ #define ARPOP_NAK 10 /**< (ATM)ARP NAK */ /** * An ARP header * * This contains only the fixed-size portions of an ARP header; for * other fields use the arp_{sender,target}_{ha,pa} family of * functions. */ struct arphdr { /** Link-layer protocol * * This is an ARPHRD_XXX constant */ uint16_t ar_hrd; /** Network-layer protocol * * This is, for Ethernet, an ETH_P_XXX constant. */ uint16_t ar_pro; /** Link-layer address length */ uint8_t ar_hln; /** Network-layer address length */ uint8_t ar_pln; /** ARP opcode */ uint16_t ar_op; } __attribute__ (( packed )); /** ARP packet sender hardware address * * @v arphdr ARP header * @ret ar_sha Sender hardware address */ static inline void * arp_sender_ha ( struct arphdr *arphdr ) { return ( ( ( void * ) arphdr ) + sizeof ( *arphdr ) ); } /** ARP packet sender protocol address * * @v arphdr ARP header * @ret ar_spa Sender protocol address */ static inline void * arp_sender_pa ( struct arphdr *arphdr ) { return ( arp_sender_ha ( arphdr ) + arphdr->ar_hln ); } /** ARP packet target hardware address * * @v arphdr ARP header * @ret ar_tha Target hardware address */ static inline void * arp_target_ha ( struct arphdr *arphdr ) { return ( arp_sender_pa ( arphdr ) + arphdr->ar_pln ); } /** ARP packet target protocol address * * @v arphdr ARP header * @ret ar_tpa Target protocol address */ static inline void * arp_target_pa ( struct arphdr *arphdr ) { return ( arp_target_ha ( arphdr ) + arphdr->ar_hln ); } #endif /* _GPXE_IF_ARP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/icmp6.h0000664000000000000000000000202712524662415020521 0ustar #ifndef _GPXE_ICMP6_H #define _GPXE_ICMP6_H /** @file * * ICMP6 protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #define ICMP6_NSOLICIT 135 #define ICMP6_NADVERT 136 extern struct tcpip_protocol icmp6_protocol; struct icmp6_header { uint8_t type; uint8_t code; uint16_t csum; /* Message body */ }; struct neighbour_solicit { uint8_t type; uint8_t code; uint16_t csum; uint32_t reserved; struct in6_addr target; /* "Compulsory" options */ uint8_t opt_type; uint8_t opt_len; /* FIXME: hack alert */ uint8_t opt_ll_addr[6]; }; struct neighbour_advert { uint8_t type; uint8_t code; uint16_t csum; uint8_t flags; uint8_t reserved; struct in6_addr target; uint8_t opt_type; uint8_t opt_len; /* FIXME: hack alert */ uint8_t opt_ll_addr[6]; }; #define ICMP6_FLAGS_ROUTER 0x80 #define ICMP6_FLAGS_SOLICITED 0x40 #define ICMP6_FLAGS_OVERRIDE 0x20 int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src, struct in6_addr *dest ); #endif /* _GPXE_ICMP6_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/isa_ids.h0000664000000000000000000000312312524662415021114 0ustar #ifndef ISA_IDS_H #define ISA_IDS_H /* * This file defines IDs as used by ISAPnP and EISA devices. These * IDs have the format: * * vendor byte 0 bit 7 must be zero * bits 6-2 first vendor char in compressed ASCII * bits 1-0 second vendor char in compressed ASCII (bits 4-3) * byte 1 bits 7-5 second vendor char in compressed ASCII (bits 2-0) * bits 4-0 third vendor char in compressed ASCII * product byte 0 bits 7-4 first hex digit of product number * bits 3-0 second hex digit of product number * byte 1 bits 7-4 third hex digit of product number * bits 3-0 hex digit of revision level * * ISA IDs are always expressed in little-endian order, even though * the underlying "meaning" is big-endian. */ FILE_LICENCE ( GPL2_OR_LATER ); #include /* * Construct a vendor ID from three ASCII characters * */ #define ISA_VENDOR( a, b, c ) \ bswap_16 ( ( ( ( (a) - 'A' + 1 ) & 0x1f ) << 10 ) | \ ( ( ( (b) - 'A' + 1 ) & 0x1f ) << 5 ) | \ ( ( ( (c) - 'A' + 1 ) & 0x1f ) << 0 ) ) #define ISAPNP_VENDOR( a, b, c ) ISA_VENDOR ( a, b, c ) #define EISA_VENDOR( a, b, c ) ISA_VENDOR ( a, b, c ) #define GENERIC_ISAPNP_VENDOR ISAPNP_VENDOR ( 'P','N','P' ) /* * Extract product ID and revision from combined product field * */ #define ISA_PROD_ID_MASK ( 0xf0ff ) #define ISA_PROD_ID(product) ( (product) & ISA_PROD_ID_MASK ) #define ISA_PROD_REV(product) ( ( (product) & ~ISA_PROD_ID_MASK ) >> 8 ) /* Functions in isa_ids.c */ extern char * isa_id_string ( unsigned int vendor, unsigned int product ); #endif /* ISA_IDS_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/i2c.h0000664000000000000000000001011012524662415020150 0ustar #ifndef _GPXE_I2C_H #define _GPXE_I2C_H /** @file * * I2C interface * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** An I2C device * * An I2C device represents a specific slave device on an I2C bus. It * is accessed via an I2C interface. */ struct i2c_device { /** Address of this device * * The actual address sent on the bus will look like * * * * The "word address overflow" is any excess bits from the * word address, i.e. any portion that does not fit within the * defined word address length. */ unsigned int dev_addr; /** Device address length, in bytes * * This is the number of bytes that comprise the device * address, defined to be the portion that terminates with the * read/write bit. */ unsigned int dev_addr_len; /** Word adddress length, in bytes * * This is the number of bytes that comprise the word address, * defined to be the portion that starts after the read/write * bit and ends before the first data byte. * * For some devices, this length will be zero (i.e. the word * address is contained entirely within the "word address * overflow"). */ unsigned int word_addr_len; }; /** An I2C interface * * An I2C interface provides access to an I2C bus, via which I2C * devices may be reached. */ struct i2c_interface { /** * Read data from I2C device * * @v i2c I2C interface * @v i2cdev I2C device * @v offset Starting offset within the device * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code */ int ( * read ) ( struct i2c_interface *i2c, struct i2c_device *i2cdev, unsigned int offset, uint8_t *data, unsigned int len ); /** * Write data to I2C device * * @v i2c I2C interface * @v i2cdev I2C device * @v offset Starting offset within the device * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code */ int ( * write ) ( struct i2c_interface *i2c, struct i2c_device *i2cdev, unsigned int offset, const uint8_t *data, unsigned int len ); }; /** A bit-bashing I2C interface * * This provides a standardised way to construct I2C buses via a * bit-bashing interface. */ struct i2c_bit_basher { /** I2C interface */ struct i2c_interface i2c; /** Bit-bashing interface */ struct bit_basher basher; }; /** Ten-bit address marker * * This value is ORed with the I2C device address to indicate a * ten-bit address format on the bus. */ #define I2C_TENBIT_ADDRESS 0x7800 /** An I2C write command */ #define I2C_WRITE 0 /** An I2C read command */ #define I2C_READ 1 /** Bit indices used for I2C bit-bashing interface */ enum { /** Serial clock */ I2C_BIT_SCL = 0, /** Serial data */ I2C_BIT_SDA, }; /** Delay required for bit-bashing operation */ #define I2C_UDELAY 5 /** Maximum number of cycles to use when attempting a bus reset */ #define I2C_RESET_MAX_CYCLES 32 /** * Check presence of I2C device * * @v i2c I2C interface * @v i2cdev I2C device * @ret rc Return status code * * Checks for the presence of the device on the I2C bus by attempting * a zero-length write. */ static inline int i2c_check_presence ( struct i2c_interface *i2c, struct i2c_device *i2cdev ) { return i2c->write ( i2c, i2cdev, 0, NULL, 0 ); } extern int init_i2c_bit_basher ( struct i2c_bit_basher *i2cbit, struct bit_basher_operations *bash_op ); /** * Initialise generic I2C EEPROM device * * @v i2cdev I2C device */ static inline __always_inline void init_i2c_eeprom ( struct i2c_device *i2cdev, unsigned int dev_addr ) { i2cdev->dev_addr = dev_addr; i2cdev->dev_addr_len = 1; i2cdev->word_addr_len = 1; } /** * Initialise Atmel AT24C11 * * @v i2cdev I2C device */ static inline __always_inline void init_at24c11 ( struct i2c_device *i2cdev ) { /* This chip has no device address; it must be the only chip * on the bus. The word address is contained entirely within * the device address field. */ i2cdev->dev_addr = 0; i2cdev->dev_addr_len = 1; i2cdev->word_addr_len = 0; } #endif /* _GPXE_I2C_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/base64.h0000664000000000000000000000077012524662415020572 0ustar #ifndef _GPXE_BASE64_H #define _GPXE_BASE64_H /** @file * * Base64 encoding * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** * Calculate length of base64-encoded string * * @v raw_len Raw string length (excluding NUL) * @ret encoded_len Encoded string length (excluding NUL) */ static inline size_t base64_encoded_len ( size_t raw_len ) { return ( ( ( raw_len + 3 - 1 ) / 3 ) * 4 ); } extern void base64_encode ( const char *raw, char *encoded ); #endif /* _GPXE_BASE64_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/process.h0000664000000000000000000000357112524662415021166 0ustar #ifndef _GPXE_PROCESS_H #define _GPXE_PROCESS_H /** @file * * Processes * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include /** A process */ struct process { /** List of processes */ struct list_head list; /** * Single-step the process * * This method should execute a single step of the process. * Returning from this method is isomorphic to yielding the * CPU to another process. */ void ( * step ) ( struct process *process ); /** Reference counter * * If this interface is not part of a reference-counted * object, this field may be NULL. */ struct refcnt *refcnt; }; extern void process_add ( struct process *process ); extern void process_del ( struct process *process ); extern void step ( void ); /** * Initialise process without adding to process list * * @v process Process * @v step Process' step() method */ static inline __attribute__ (( always_inline )) void process_init_stopped ( struct process *process, void ( * step ) ( struct process *process ), struct refcnt *refcnt ) { INIT_LIST_HEAD ( &process->list ); process->step = step; process->refcnt = refcnt; } /** * Initialise process and add to process list * * @v process Process * @v step Process' step() method */ static inline __attribute__ (( always_inline )) void process_init ( struct process *process, void ( * step ) ( struct process *process ), struct refcnt *refcnt ) { process_init_stopped ( process, step, refcnt ); process_add ( process ); } /** Permanent process table */ #define PERMANENT_PROCESSES __table ( struct process, "processes" ) /** * Declare a permanent process * * Permanent processes will be automatically added to the process list * at initialisation time. */ #define __permanent_process __table_entry ( PERMANENT_PROCESSES, 01 ) #endif /* _GPXE_PROCESS_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/dns.h0000664000000000000000000000353612524662415020275 0ustar #ifndef _GPXE_DNS_H #define _GPXE_DNS_H /** @file * * DNS protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /* * Constants * */ #define DNS_TYPE_A 1 #define DNS_TYPE_CNAME 5 #define DNS_TYPE_ANY 255 #define DNS_CLASS_IN 1 #define DNS_CLASS_CS 2 #define DNS_CLASS_CH 3 #define DNS_CLASS_HS 4 #define DNS_FLAG_QUERY ( 0x00 << 15 ) #define DNS_FLAG_RESPONSE ( 0x01 << 15 ) #define DNS_FLAG_QR(flags) ( (flags) & ( 0x01 << 15 ) ) #define DNS_FLAG_OPCODE_QUERY ( 0x00 << 11 ) #define DNS_FLAG_OPCODE_IQUERY ( 0x01 << 11 ) #define DNS_FLAG_OPCODE_STATUS ( 0x02 << 11 ) #define DNS_FLAG_OPCODE(flags) ( (flags) & ( 0x0f << 11 ) ) #define DNS_FLAG_RD ( 0x01 << 8 ) #define DNS_FLAG_RA ( 0x01 << 7 ) #define DNS_FLAG_RCODE_OK ( 0x00 << 0 ) #define DNS_FLAG_RCODE_NX ( 0x03 << 0 ) #define DNS_FLAG_RCODE(flags) ( (flags) & ( 0x0f << 0 ) ) #define DNS_PORT 53 #define DNS_MAX_RETRIES 3 #define DNS_MAX_CNAME_RECURSION 0x30 /* * DNS protocol structures * */ struct dns_header { uint16_t id; uint16_t flags; uint16_t qdcount; uint16_t ancount; uint16_t nscount; uint16_t arcount; } __attribute__ (( packed )); struct dns_query_info { uint16_t qtype; uint16_t qclass; } __attribute__ (( packed )); struct dns_query { struct dns_header dns; char payload[ 256 + sizeof ( struct dns_query_info ) ]; } __attribute__ (( packed )); struct dns_rr_info_common { uint16_t type; uint16_t class; uint32_t ttl; uint16_t rdlength; } __attribute__ (( packed )); struct dns_rr_info_a { struct dns_rr_info_common common; struct in_addr in_addr; } __attribute__ (( packed )); struct dns_rr_info_cname { struct dns_rr_info_common common; char cname[0]; } __attribute__ (( packed )); union dns_rr_info { struct dns_rr_info_common common; struct dns_rr_info_a a; struct dns_rr_info_cname cname; }; #endif /* _GPXE_DNS_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/rc80211.h0000664000000000000000000000075312524662415020507 0ustar #ifndef _GPXE_RC80211_H #define _GPXE_RC80211_H /** @file * * Rate-control algorithm prototype for 802.11. */ FILE_LICENCE ( GPL2_OR_LATER ); struct net80211_device; struct rc80211_ctx; struct rc80211_ctx * rc80211_init ( struct net80211_device *dev ); void rc80211_update_tx ( struct net80211_device *dev, int retries, int rc ); void rc80211_update_rx ( struct net80211_device *dev, int retry, u16 rate ); void rc80211_free ( struct rc80211_ctx *ctx ); #endif /* _GPXE_RC80211_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/mca.h0000664000000000000000000000410612524662415020243 0ustar /* * MCA bus driver code * * Abstracted from 3c509.c. * */ FILE_LICENCE ( GPL2_OR_LATER ); #ifndef MCA_H #define MCA_H #include #include #include /* * MCA constants * */ #define MCA_MOTHERBOARD_SETUP_REG 0x94 #define MCA_ADAPTER_SETUP_REG 0x96 #define MCA_MAX_SLOT_NR 0x07 /* Must be 2^n - 1 */ #define MCA_POS_REG(n) (0x100+(n)) /* Is there a standard that would define this? */ #define GENERIC_MCA_VENDOR ISA_VENDOR ( 'M', 'C', 'A' ) /** An MCA device ID list entry */ struct mca_device_id { /** Name */ const char *name; /** Device ID */ uint16_t id; }; /** An MCA device */ struct mca_device { /** Generic device */ struct device dev; /** Slot number */ unsigned int slot; /** POS register values */ unsigned char pos[8]; /** Driver for this device */ struct mca_driver *driver; /** Driver-private data * * Use mca_set_drvdata() and mca_get_drvdata() to access * this field. */ void *priv; /** Driver name */ const char *driver_name; }; #define MCA_ID(mca) ( ( (mca)->pos[1] << 8 ) + (mca)->pos[0] ) /** An MCA driver */ struct mca_driver { /** MCA ID table */ struct mca_device_id *ids; /** Number of entries in MCA ID table */ unsigned int id_count; /** * Probe device * * @v mca MCA device * @v id Matching entry in ID table * @ret rc Return status code */ int ( * probe ) ( struct mca_device *mca, const struct mca_device_id *id ); /** * Remove device * * @v mca MCA device */ void ( * remove ) ( struct mca_device *mca ); }; /** MCA driver table */ #define MCA_DRIVERS __table ( struct mca_driver, "mca_drivers" ) /** Declare an MCA driver */ #define __mca_driver __table_entry ( MCA_DRIVERS, 01 ) /** * Set MCA driver-private data * * @v mca MCA device * @v priv Private data */ static inline void mca_set_drvdata ( struct mca_device *mca, void *priv ) { mca->priv = priv; } /** * Get MCA driver-private data * * @v mca MCA device * @ret priv Private data */ static inline void * mca_get_drvdata ( struct mca_device *mca ) { return mca->priv; } #endif debian/grub-extras/disabled/gpxe/src/include/gpxe/filter.h0000664000000000000000000000436112524662415020773 0ustar #ifndef _GPXE_FILTER_H #define _GPXE_FILTER_H /** @file * * Data transfer filters * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** * Half of a data transfer filter * * Embed two of these structures within a structure implementing a * data transfer filter, and intialise with filter_init(). You can * then use the filter_xxx() methods as the data transfer interface * methods as required. */ struct xfer_filter_half { /** Data transfer interface */ struct xfer_interface xfer; /** Other half of the data transfer filter */ struct xfer_filter_half *other; }; /** * Get data transfer interface for the other half of a data transfer filter * * @v xfer Data transfer interface * @ret other Other half's data transfer interface */ static inline __attribute__ (( always_inline )) struct xfer_interface * filter_other_half ( struct xfer_interface *xfer ) { struct xfer_filter_half *half = container_of ( xfer, struct xfer_filter_half, xfer ); return &half->other->xfer; } extern void filter_close ( struct xfer_interface *xfer, int rc ); extern int filter_vredirect ( struct xfer_interface *xfer, int type, va_list args ); extern size_t filter_window ( struct xfer_interface *xfer ); extern struct io_buffer * filter_alloc_iob ( struct xfer_interface *xfer, size_t len ); extern int filter_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta ); extern int filter_deliver_raw ( struct xfer_interface *xfer, const void *data, size_t len ); /** * Initialise a data transfer filter * * @v left "Left" half of the filter * @v left_op Data transfer interface operations for "left" half * @v right "Right" half of the filter * @v right_op Data transfer interface operations for "right" half * @v refcnt Containing object reference counter, or NULL */ static inline void filter_init ( struct xfer_filter_half *left, struct xfer_interface_operations *left_op, struct xfer_filter_half *right, struct xfer_interface_operations *right_op, struct refcnt *refcnt ) { xfer_init ( &left->xfer, left_op, refcnt ); xfer_init ( &right->xfer, right_op, refcnt ); left->other = right; right->other = left; } #endif /* _GPXE_FILTER_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/isapnp.h0000664000000000000000000001673012524662415021003 0ustar /************************************************************************** * * isapnp.h -- Etherboot isapnp support for the 3Com 3c515 * Written 2002-2003 by Timothy Legge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Portions of this code: * Copyright (C) 2001 P.J.H.Fox (fox@roestock.demon.co.uk) * * * * REVISION HISTORY: * ================ * Version 0.1 April 26, 2002 TJL * Version 0.2 01/08/2003 TJL Renamed from 3c515_isapnp.h * * * Generalised into an ISAPnP bus that can be used by more than just * the 3c515 by Michael Brown * ***************************************************************************/ FILE_LICENCE ( GPL2_OR_LATER ); #ifndef ISAPNP_H #define ISAPNP_H #include #include #include #include /* * ISAPnP constants * */ /* Port addresses */ #define ISAPNP_ADDRESS 0x279 #define ISAPNP_WRITE_DATA 0xa79 #define ISAPNP_READ_PORT_MIN 0x203 #define ISAPNP_READ_PORT_START 0x213 /* ISAPnP spec says 0x203, but * Linux ISAPnP starts at * 0x213 with no explanatory * comment. 0x203 probably * clashes with something. */ #define ISAPNP_READ_PORT_MAX 0x3ff #define ISAPNP_READ_PORT_STEP 0x10 /* Can be any multiple of 4 * according to the spec, but * since ISA I/O addresses are * allocated in blocks of 16, * it makes no sense to use * any value less than 16. */ /* Card select numbers */ #define ISAPNP_CSN_MIN 0x01 #define ISAPNP_CSN_MAX 0x0f /* Registers */ #define ISAPNP_READPORT 0x00 #define ISAPNP_SERIALISOLATION 0x01 #define ISAPNP_CONFIGCONTROL 0x02 #define ISAPNP_WAKE 0x03 #define ISAPNP_RESOURCEDATA 0x04 #define ISAPNP_STATUS 0x05 #define ISAPNP_CARDSELECTNUMBER 0x06 #define ISAPNP_LOGICALDEVICENUMBER 0x07 #define ISAPNP_ACTIVATE 0x30 #define ISAPNP_IORANGECHECK 0x31 #define ISAPNP_IOBASE(n) ( 0x60 + ( (n) * 2 ) ) #define ISAPNP_IRQNO(n) ( 0x70 + ( (n) * 2 ) ) #define ISAPNP_IRQTYPE(n) ( 0x71 + ( (n) * 2 ) ) /* Bits in the CONFIGCONTROL register */ #define ISAPNP_CONFIG_RESET ( 1 << 0 ) #define ISAPNP_CONFIG_WAIT_FOR_KEY ( 1 << 1 ) #define ISAPNP_CONFIG_RESET_CSN ( 1 << 2 ) #define ISAPNP_CONFIG_RESET_DRV ( ISAPNP_CONFIG_RESET | \ ISAPNP_CONFIG_WAIT_FOR_KEY | \ ISAPNP_CONFIG_RESET_CSN ) /* The LFSR used for the initiation key and for checksumming */ #define ISAPNP_LFSR_SEED 0x6a /* Small tags */ #define ISAPNP_IS_SMALL_TAG(tag) ( ! ( (tag) & 0x80 ) ) #define ISAPNP_SMALL_TAG_NAME(tag) ( ( (tag) >> 3 ) & 0xf ) #define ISAPNP_SMALL_TAG_LEN(tag) ( ( (tag) & 0x7 ) ) #define ISAPNP_TAG_PNPVERNO 0x01 #define ISAPNP_TAG_LOGDEVID 0x02 #define ISAPNP_TAG_COMPATDEVID 0x03 #define ISAPNP_TAG_IRQ 0x04 #define ISAPNP_TAG_DMA 0x05 #define ISAPNP_TAG_STARTDEP 0x06 #define ISAPNP_TAG_ENDDEP 0x07 #define ISAPNP_TAG_IOPORT 0x08 #define ISAPNP_TAG_FIXEDIO 0x09 #define ISAPNP_TAG_RSVDSHORTA 0x0A #define ISAPNP_TAG_RSVDSHORTB 0x0B #define ISAPNP_TAG_RSVDSHORTC 0x0C #define ISAPNP_TAG_RSVDSHORTD 0x0D #define ISAPNP_TAG_VENDORSHORT 0x0E #define ISAPNP_TAG_END 0x0F /* Large tags */ #define ISAPNP_IS_LARGE_TAG(tag) ( ( (tag) & 0x80 ) ) #define ISAPNP_LARGE_TAG_NAME(tag) (tag) #define ISAPNP_TAG_MEMRANGE 0x81 #define ISAPNP_TAG_ANSISTR 0x82 #define ISAPNP_TAG_UNICODESTR 0x83 #define ISAPNP_TAG_VENDORLONG 0x84 #define ISAPNP_TAG_MEM32RANGE 0x85 #define ISAPNP_TAG_FIXEDMEM32RANGE 0x86 #define ISAPNP_TAG_RSVDLONG0 0xF0 #define ISAPNP_TAG_RSVDLONG1 0xF1 #define ISAPNP_TAG_RSVDLONG2 0xF2 #define ISAPNP_TAG_RSVDLONG3 0xF3 #define ISAPNP_TAG_RSVDLONG4 0xF4 #define ISAPNP_TAG_RSVDLONG5 0xF5 #define ISAPNP_TAG_RSVDLONG6 0xF6 #define ISAPNP_TAG_RSVDLONG7 0xF7 #define ISAPNP_TAG_RSVDLONG8 0xF8 #define ISAPNP_TAG_RSVDLONG9 0xF9 #define ISAPNP_TAG_RSVDLONGA 0xFA #define ISAPNP_TAG_RSVDLONGB 0xFB #define ISAPNP_TAG_RSVDLONGC 0xFC #define ISAPNP_TAG_RSVDLONGD 0xFD #define ISAPNP_TAG_RSVDLONGE 0xFE #define ISAPNP_TAG_RSVDLONGF 0xFF #define ISAPNP_TAG_PSEUDO_NEWBOARD 0x100 /** An ISAPnP serial identifier */ struct isapnp_identifier { /** Vendor ID */ uint16_t vendor_id; /** Product ID */ uint16_t prod_id; /** Serial number */ uint32_t serial; /** Checksum */ uint8_t checksum; } __attribute__ (( packed )); /** An ISAPnP logical device ID structure */ struct isapnp_logdevid { /** Vendor ID */ uint16_t vendor_id; /** Product ID */ uint16_t prod_id; /** Flags */ uint16_t flags; } __attribute__ (( packed )); /** An ISAPnP device ID list entry */ struct isapnp_device_id { /** Name */ const char *name; /** Vendor ID */ uint16_t vendor_id; /** Product ID */ uint16_t prod_id; }; /** An ISAPnP device */ struct isapnp_device { /** Generic device */ struct device dev; /** Vendor ID */ uint16_t vendor_id; /** Product ID */ uint16_t prod_id; /** I/O address */ uint16_t ioaddr; /** Interrupt number */ uint8_t irqno; /** Card Select Number */ uint8_t csn; /** Logical Device ID */ uint8_t logdev; /** Driver for this device */ struct isapnp_driver *driver; /** Driver-private data * * Use isapnp_set_drvdata() and isapnp_get_drvdata() to access * this field. */ void *priv; /** Driver name */ const char *driver_name; }; /** An ISAPnP driver */ struct isapnp_driver { /** ISAPnP ID table */ struct isapnp_device_id *ids; /** Number of entries in ISAPnP ID table */ unsigned int id_count; /** * Probe device * * @v isapnp ISAPnP device * @v id Matching entry in ID table * @ret rc Return status code */ int ( * probe ) ( struct isapnp_device *isapnp, const struct isapnp_device_id *id ); /** * Remove device * * @v isapnp ISAPnP device */ void ( * remove ) ( struct isapnp_device *isapnp ); }; /** ISAPnP driver table */ #define ISAPNP_DRIVERS __table ( struct isapnp_driver, "isapnp_drivers" ) /** Declare an ISAPnP driver */ #define __isapnp_driver __table_entry ( ISAPNP_DRIVERS, 01 ) extern uint16_t isapnp_read_port; extern void isapnp_device_activation ( struct isapnp_device *isapnp, int activation ); /** * Activate ISAPnP device * * @v isapnp ISAPnP device */ static inline void activate_isapnp_device ( struct isapnp_device *isapnp ) { isapnp_device_activation ( isapnp, 1 ); } /** * Deactivate ISAPnP device * * @v isapnp ISAPnP device */ static inline void deactivate_isapnp_device ( struct isapnp_device *isapnp ) { isapnp_device_activation ( isapnp, 0 ); } /** * Set ISAPnP driver-private data * * @v isapnp ISAPnP device * @v priv Private data */ static inline void isapnp_set_drvdata ( struct isapnp_device *isapnp, void *priv ) { isapnp->priv = priv; } /** * Get ISAPnP driver-private data * * @v isapnp ISAPnP device * @ret priv Private data */ static inline void * isapnp_get_drvdata ( struct isapnp_device *isapnp ) { return isapnp->priv; } #endif /* ISAPNP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/memmap.h0000664000000000000000000000117612524662415020763 0ustar #ifndef _GPXE_MEMMAP_H #define _GPXE_MEMMAP_H #include /** * @file * * Memory mapping * */ FILE_LICENCE ( GPL2_OR_LATER ); /** A usable memory region */ struct memory_region { /** Physical start address */ uint64_t start; /** Physical end address */ uint64_t end; }; /** Maximum number of memory regions we expect to encounter */ #define MAX_MEMORY_REGIONS 8 /** A memory map */ struct memory_map { /** Memory regions */ struct memory_region regions[MAX_MEMORY_REGIONS]; /** Number of used regions */ unsigned int count; }; extern void get_memmap ( struct memory_map *memmap ); #endif /* _GPXE_MEMMAP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/malloc.h0000664000000000000000000000257212524662415020757 0ustar #ifndef _GPXE_MALLOC_H #define _GPXE_MALLOC_H #include /** @file * * Dynamic memory allocation * */ FILE_LICENCE ( GPL2_OR_LATER ); /* * Prototypes for the standard functions (malloc() et al) are in * stdlib.h. Include only if you need the * non-standard functions, such as malloc_dma(). * */ #include extern size_t freemem; extern void * __malloc alloc_memblock ( size_t size, size_t align ); extern void free_memblock ( void *ptr, size_t size ); extern void mpopulate ( void *start, size_t len ); extern void mdumpfree ( void ); /** * Allocate memory for DMA * * @v size Requested size * @v align Physical alignment * @ret ptr Memory, or NULL * * Allocates physically-aligned memory for DMA. * * @c align must be a power of two. @c size may not be zero. */ static inline void * __malloc malloc_dma ( size_t size, size_t phys_align ) { return alloc_memblock ( size, phys_align ); } /** * Free memory allocated with malloc_dma() * * @v ptr Memory allocated by malloc_dma(), or NULL * @v size Size of memory, as passed to malloc_dma() * * Memory allocated with malloc_dma() can only be freed with * free_dma(); it cannot be freed with the standard free(). * * If @c ptr is NULL, no action is taken. */ static inline void free_dma ( void *ptr, size_t size ) { free_memblock ( ptr, size ); } #endif /* _GPXE_MALLOC_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/login_ui.h0000664000000000000000000000026212524662415021307 0ustar #ifndef _GPXE_LOGIN_UI_H #define _GPXE_LOGIN_UI_H /** @file * * Login UI * */ FILE_LICENCE ( GPL2_OR_LATER ); extern int login_ui ( void ); #endif /* _GPXE_LOGIN_UI_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ib_cmrc.h0000664000000000000000000000060012524662415021074 0ustar #ifndef _GPXE_IB_CMRC_H #define _GPXE_IB_CMRC_H /** @file * * Infiniband Communication-managed Reliable Connections * */ FILE_LICENCE ( BSD2 ); #include #include extern int ib_cmrc_open ( struct xfer_interface *xfer, struct ib_device *ibdev, struct ib_gid *dgid, struct ib_gid_half *service_id ); #endif /* _GPXE_IB_CMRC_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/chap.h0000664000000000000000000000241112524662415020413 0ustar #ifndef _GPXE_CHAP_H #define _GPXE_CHAP_H /** @file * * CHAP protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include struct digest_algorithm; /** A CHAP response */ struct chap_response { /** Digest algorithm used for the response */ struct digest_algorithm *digest; /** Context used by the digest algorithm */ uint8_t *digest_context; /** CHAP response */ uint8_t *response; /** Length of CHAP response */ size_t response_len; }; extern int chap_init ( struct chap_response *chap, struct digest_algorithm *digest ); extern void chap_update ( struct chap_response *chap, const void *data, size_t len ); extern void chap_respond ( struct chap_response *chap ); extern void chap_finish ( struct chap_response *chap ); /** * Add identifier data to the CHAP challenge * * @v chap CHAP response * @v identifier CHAP identifier * * The CHAP identifier is the first byte of the CHAP challenge. This * function is a notational convenience for calling chap_update() for * the identifier byte. */ static inline void chap_set_identifier ( struct chap_response *chap, unsigned int identifier ) { uint8_t ident_byte = identifier; chap_update ( chap, &ident_byte, sizeof ( ident_byte ) ); } #endif /* _GPXE_CHAP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ib_cm.h0000664000000000000000000000351612524662415020560 0ustar #ifndef _GPXE_IB_CM_H #define _GPXE_IB_CM_H /** @file * * Infiniband communication management * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include struct ib_mad_transaction; struct ib_connection; /** Infiniband connection operations */ struct ib_connection_operations { /** Handle change of connection status * * @v ibdev Infiniband device * @v qp Queue pair * @v conn Connection * @v rc Connection status code * @v private_data Private data, if available * @v private_data_len Length of private data */ void ( * changed ) ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_connection *conn, int rc, void *private_data, size_t private_data_len ); }; /** An Infiniband connection */ struct ib_connection { /** Infiniband device */ struct ib_device *ibdev; /** Queue pair */ struct ib_queue_pair *qp; /** Local communication ID */ uint32_t local_id; /** Remote communication ID */ uint32_t remote_id; /** Target service ID */ struct ib_gid_half service_id; /** Connection operations */ struct ib_connection_operations *op; /** List of connections */ struct list_head list; /** Path to target */ struct ib_path *path; /** Connection request management transaction */ struct ib_mad_transaction *madx; /** Length of connection request private data */ size_t private_data_len; /** Connection request private data */ uint8_t private_data[0]; }; extern struct ib_connection * ib_create_conn ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_gid *dgid, struct ib_gid_half *service_id, void *req_private_data, size_t req_private_data_len, struct ib_connection_operations *op ); extern void ib_destroy_conn ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_connection *conn ); #endif /* _GPXE_IB_CM_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/acpi.h0000664000000000000000000000171512524662415020422 0ustar #ifndef _GPXE_ACPI_H #define _GPXE_ACPI_H /** @file * * ACPI data structures * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** * An ACPI description header * * This is the structure common to the start of all ACPI system * description tables. */ struct acpi_description_header { /** ACPI signature (4 ASCII characters) */ char signature[4]; /** Length of table, in bytes, including header */ uint32_t length; /** ACPI Specification minor version number */ uint8_t revision; /** To make sum of entire table == 0 */ uint8_t checksum; /** OEM identification */ char oem_id[6]; /** OEM table identification */ char oem_table_id[8]; /** OEM revision number */ uint32_t oem_revision; /** ASL compiler vendor ID */ char asl_compiler_id[4]; /** ASL compiler revision number */ uint32_t asl_compiler_revision; } __attribute__ (( packed )); extern void acpi_fix_checksum ( struct acpi_description_header *acpi ); #endif /* _GPXE_ACPI_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ansiesc.h0000664000000000000000000000605312524662415021133 0ustar #ifndef _GPXE_ANSIESC_H #define _GPXE_ANSIESC_H /** @file * * ANSI escape sequences * * ANSI X3.64 (aka ECMA-48 or ISO/IEC 6429, available from * http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf) * defines escape sequences consisting of: * * A Control Sequence Introducer (CSI) * * Zero or more Parameter Bytes (P) * * Zero or more Intermediate Bytes (I) * * A Final Byte (F) * * The CSI consists of ESC (0x1b) followed by "[" (0x5b). The * Parameter Bytes, for a standardised (i.e. not private or * experimental) sequence, consist of a list of ASCII decimal integers * separated by semicolons. The Intermediate Bytes (in the range 0x20 * to 0x2f) and the Final Byte (in the range 0x40 to 0x4f) determine * the control function. * */ FILE_LICENCE ( GPL2_OR_LATER ); /** A handler for an escape sequence */ struct ansiesc_handler { /** The control function identifier * * The control function identifier consists of the * Intermediate Bytes (if any) and the Final Byte. In * practice, no more than one immediate byte is ever used, so * the byte combination can be efficiently expressed as a * single integer, in the obvious way (with the Final Byte * being the least significant byte). */ unsigned int function; /** Handle escape sequence * * @v count Parameter count * @v params Parameter list * * A negative parameter value indicates that the parameter was * omitted and that the default value for this control * function should be used. * * Since all parameters are optional, there is no way to * distinguish between "zero parameters" and "single parameter * omitted". Consequently, the parameter list will always * contain at least one item. */ void ( * handle ) ( unsigned int count, int params[] ); }; /** Maximum number of parameters within a single escape sequence */ #define ANSIESC_MAX_PARAMS 4 /** * ANSI escape sequence context * * This provides temporary storage for processing escape sequences, * and points to the list of escape sequence handlers. */ struct ansiesc_context { /** Array of handlers * * Must be terminated by a handler with @c function set to * zero. */ struct ansiesc_handler *handlers; /** Parameter count * * Will be zero when not currently in an escape sequence. */ unsigned int count; /** Parameter list */ int params[ANSIESC_MAX_PARAMS]; /** Control function identifier */ unsigned int function; }; /** Escape character */ #define ESC 0x1b /** Control Sequence Introducer */ #define CSI "\033[" /** * @defgroup ansifuncs ANSI escape sequence function identifiers * @{ */ /** Cursor position */ #define ANSIESC_CUP 'H' /** Erase in page */ #define ANSIESC_ED 'J' /** Erase from cursor to end of page */ #define ANSIESC_ED_TO_END 0 /** Erase from start of page to cursor */ #define ANSIESC_ED_FROM_START 1 /** Erase whole page */ #define ANSIESC_ED_ALL 2 /** Select graphic rendition */ #define ANSIESC_SGR 'm' /** @} */ extern int ansiesc_process ( struct ansiesc_context *ctx, int c ); #endif /* _GPXE_ANSIESC_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/segment.h0000664000000000000000000000041412524662415021143 0ustar #ifndef _GPXE_SEGMENT_H #define _GPXE_SEGMENT_H /** * @file * * Executable image segments * */ FILE_LICENCE ( GPL2_OR_LATER ); #include extern int prep_segment ( userptr_t segment, size_t filesz, size_t memsz ); #endif /* _GPXE_SEGMENT_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/http.h0000664000000000000000000000071012524662415020457 0ustar #ifndef _GPXE_HTTP_H #define _GPXE_HTTP_H /** @file * * Hyper Text Transport Protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); /** HTTP default port */ #define HTTP_PORT 80 /** HTTPS default port */ #define HTTPS_PORT 443 extern int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, unsigned int default_port, int ( * filter ) ( struct xfer_interface *, struct xfer_interface ** ) ); #endif /* _GPXE_HTTP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/pcibackup.h0000664000000000000000000000144012524662415021442 0ustar #ifndef _GPXE_PCIBACKUP_H #define _GPXE_PCIBACKUP_H /** @file * * PCI configuration space backup and restoration * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** A PCI configuration space backup */ struct pci_config_backup { uint32_t dwords[64]; }; /** PCI configuration space backup exclusion list end marker */ #define PCI_CONFIG_BACKUP_EXCLUDE_END 0xff /** Define a PCI configuration space backup exclusion list */ #define PCI_CONFIG_BACKUP_EXCLUDE(...) \ { __VA_ARGS__, PCI_CONFIG_BACKUP_EXCLUDE_END } extern void pci_backup ( struct pci_device *pci, struct pci_config_backup *backup, const uint8_t *exclude ); extern void pci_restore ( struct pci_device *pci, struct pci_config_backup *backup, const uint8_t *exclude ); #endif /* _GPXE_PCIBACKUP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ib_sma.h0000664000000000000000000000061212524662415020733 0ustar #ifndef _GPXE_IB_SMA_H #define _GPXE_IB_SMA_H /** @file * * Infiniband subnet management agent * */ FILE_LICENCE ( GPL2_OR_LATER ); struct ib_device; struct ib_mad_interface; extern int ib_create_sma ( struct ib_device *ibdev, struct ib_mad_interface *mi ); extern void ib_destroy_sma ( struct ib_device *ibdev, struct ib_mad_interface *mi ); #endif /* _GPXE_IB_SMA_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ib_srp.h0000664000000000000000000000363412524662415020766 0ustar #ifndef _GPXE_IB_SRP_H #define _GPXE_IB_SRP_H /** @file * * SCSI RDMA Protocol over Infiniband * */ FILE_LICENCE ( BSD2 ); #include #include #include /** SRP initiator port identifier for Infiniband */ struct ib_srp_initiator_port_id { /** Identifier extension */ struct ib_gid_half id_ext; /** IB channel adapter GUID */ struct ib_gid_half hca_guid; } __attribute__ (( packed )); /** SRP target port identifier for Infiniband */ struct ib_srp_target_port_id { /** Identifier extension */ struct ib_gid_half id_ext; /** I/O controller GUID */ struct ib_gid_half ioc_guid; } __attribute__ (( packed )); /** * Get Infiniband-specific initiator port ID * * @v port_ids SRP port IDs * @ret initiator_port_id Infiniband-specific initiator port ID */ static inline __always_inline struct ib_srp_initiator_port_id * ib_srp_initiator_port_id ( struct srp_port_ids *port_ids ) { return ( ( struct ib_srp_initiator_port_id * ) &port_ids->initiator ); } /** * Get Infiniband-specific target port ID * * @v port_ids SRP port IDs * @ret target_port_id Infiniband-specific target port ID */ static inline __always_inline struct ib_srp_target_port_id * ib_srp_target_port_id ( struct srp_port_ids *port_ids ) { return ( ( struct ib_srp_target_port_id * ) &port_ids->target ); } /** Infiniband-specific SRP parameters */ struct ib_srp_parameters { /** Source GID */ struct ib_gid sgid; /** Destination GID */ struct ib_gid dgid; /** Service ID */ struct ib_gid_half service_id; /** Partition key */ uint16_t pkey; }; /** * Get Infiniband-specific transport parameters * * @v srp SRP device * @ret ib_params Infiniband-specific transport parameters */ static inline __always_inline struct ib_srp_parameters * ib_srp_params ( struct srp_device *srp ) { return srp_transport_priv ( srp ); } extern struct srp_transport_type ib_srp_transport; #endif /* _GPXE_IB_SRP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/spi_bit.h0000664000000000000000000000254212524662415021136 0ustar #ifndef _GPXE_SPI_BIT_H #define _GPXE_SPI_BIT_H /** @file * * SPI bit-bashing interface * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** A bit-bashing SPI bus */ struct spi_bit_basher { /** SPI bus */ struct spi_bus bus; /** Bit-bashing interface */ struct bit_basher basher; /** Endianness of data * * SPI commands and addresses are always big-endian (i.e. MSB * transmitted first on the wire), but some cards * (e.g. natsemi) choose to regard the data stored in the * EEPROM as little-endian (i.e. LSB transmitted first on the * wire). */ int endianness; }; /** Bit indices used for SPI bit-bashing interface */ enum { /** Serial clock */ SPI_BIT_SCLK = 0, /** Master Out Slave In */ SPI_BIT_MOSI, /** Master In Slave Out */ SPI_BIT_MISO, /** Slave 0 select */ SPI_BIT_SS0, }; /** * Determine bit index for a particular slave * * @v slave Slave number * @ret index Bit index (i.e. SPI_BIT_SSN, where N=slave) */ #define SPI_BIT_SS( slave ) ( SPI_BIT_SS0 + (slave) ) /** Delay between SCLK transitions */ #define SPI_BIT_UDELAY 1 /** SPI bit basher treats data as big-endian */ #define SPI_BIT_BIG_ENDIAN 0 /** SPI bit basher treats data as little-endian */ #define SPI_BIT_LITTLE_ENDIAN 1 extern void init_spi_bit_basher ( struct spi_bit_basher *spibit ); #endif /* _GPXE_SPI_BIT_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/tcpip.h0000664000000000000000000000710012524662415020617 0ustar #ifndef _GPXE_TCPIP_H #define _GPXE_TCPIP_H /** @file * * Transport-network layer interface * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include struct io_buffer; struct net_device; /** Empty checksum value * * This is the TCP/IP checksum over a zero-length block of data. */ #define TCPIP_EMPTY_CSUM 0xffff /** * TCP/IP socket address * * This contains the fields common to socket addresses for all TCP/IP * address families. */ struct sockaddr_tcpip { /** Socket address family (part of struct @c sockaddr) */ sa_family_t st_family; /** TCP/IP port */ uint16_t st_port; /** Padding * * This ensures that a struct @c sockaddr_tcpip is large * enough to hold a socket address for any TCP/IP address * family. */ char pad[ sizeof ( struct sockaddr ) - ( sizeof ( sa_family_t ) + sizeof ( uint16_t ) ) ]; } __attribute__ (( may_alias )); /** * A transport-layer protocol of the TCP/IP stack (eg. UDP, TCP, etc) */ struct tcpip_protocol { /** Protocol name */ const char *name; /** * Process received packet * * @v iobuf I/O buffer * @v st_src Partially-filled source address * @v st_dest Partially-filled destination address * @v pshdr_csum Pseudo-header checksum * @ret rc Return status code * * This method takes ownership of the I/O buffer. */ int ( * rx ) ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ); /** * Transport-layer protocol number * * This is a constant of the type IP_XXX */ uint8_t tcpip_proto; }; /** * A network-layer protocol of the TCP/IP stack (eg. IPV4, IPv6, etc) */ struct tcpip_net_protocol { /** Protocol name */ const char *name; /** Network address family */ sa_family_t sa_family; /** * Transmit packet * * @v iobuf I/O buffer * @v tcpip_protocol Transport-layer protocol * @v st_src Source address, or NULL to use default * @v st_dest Destination address * @v netdev Network device (or NULL to route automatically) * @v trans_csum Transport-layer checksum to complete, or NULL * @ret rc Return status code * * This function takes ownership of the I/O buffer. */ int ( * tx ) ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, struct net_device *netdev, uint16_t *trans_csum ); }; /** TCP/IP transport-layer protocol table */ #define TCPIP_PROTOCOLS __table ( struct tcpip_protocol, "tcpip_protocols" ) /** Declare a TCP/IP transport-layer protocol */ #define __tcpip_protocol __table_entry ( TCPIP_PROTOCOLS, 01 ) /** TCP/IP network-layer protocol table */ #define TCPIP_NET_PROTOCOLS \ __table ( struct tcpip_net_protocol, "tcpip_net_protocols" ) /** Declare a TCP/IP network-layer protocol */ #define __tcpip_net_protocol __table_entry ( TCPIP_NET_PROTOCOLS, 01 ) extern int tcpip_rx ( struct io_buffer *iobuf, uint8_t tcpip_proto, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ); extern int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, struct net_device *netdev, uint16_t *trans_csum ); extern uint16_t tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ); extern uint16_t tcpip_chksum ( const void *data, size_t len ); #endif /* _GPXE_TCPIP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/tftp.h0000664000000000000000000000430212524662415020456 0ustar #ifndef _GPXE_TFTP_H #define _GPXE_TFTP_H /** @file * * TFTP protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #define TFTP_PORT 69 /**< Default TFTP server port */ #define TFTP_DEFAULT_BLKSIZE 512 /**< Default TFTP data block size */ #define TFTP_MAX_BLKSIZE 1432 #define TFTP_RRQ 1 /**< Read request opcode */ #define TFTP_WRQ 2 /**< Write request opcode */ #define TFTP_DATA 3 /**< Data block opcode */ #define TFTP_ACK 4 /**< Data block acknowledgement opcode */ #define TFTP_ERROR 5 /**< Error opcode */ #define TFTP_OACK 6 /**< Options acknowledgement opcode */ #define TFTP_ERR_FILE_NOT_FOUND 1 /**< File not found */ #define TFTP_ERR_ACCESS_DENIED 2 /**< Access violation */ #define TFTP_ERR_DISK_FULL 3 /**< Disk full or allocation exceeded */ #define TFTP_ERR_ILLEGAL_OP 4 /**< Illegal TFTP operation */ #define TFTP_ERR_UNKNOWN_TID 5 /**< Unknown transfer ID */ #define TFTP_ERR_FILE_EXISTS 6 /**< File already exists */ #define TFTP_ERR_UNKNOWN_USER 7 /**< No such user */ #define TFTP_ERR_BAD_OPTS 8 /**< Option negotiation failed */ #define MTFTP_PORT 1759 /**< Default MTFTP server port */ /** A TFTP read request (RRQ) packet */ struct tftp_rrq { uint16_t opcode; char data[0]; } __attribute__ (( packed )); /** A TFTP data (DATA) packet */ struct tftp_data { uint16_t opcode; uint16_t block; uint8_t data[0]; } __attribute__ (( packed )); /** A TFTP acknowledgement (ACK) packet */ struct tftp_ack { uint16_t opcode; uint16_t block; } __attribute__ (( packed )); /** A TFTP error (ERROR) packet */ struct tftp_error { uint16_t opcode; uint16_t errcode; char errmsg[0]; } __attribute__ (( packed )); /** A TFTP options acknowledgement (OACK) packet */ struct tftp_oack { uint16_t opcode; char data[0]; } __attribute__ (( packed )); /** The common header of all TFTP packets */ struct tftp_common { uint16_t opcode; } __attribute__ (( packed )); /** A union encapsulating all TFTP packet types */ union tftp_any { struct tftp_common common; struct tftp_rrq rrq; struct tftp_data data; struct tftp_ack ack; struct tftp_error error; struct tftp_oack oack; }; extern void tftp_set_request_blksize ( unsigned int blksize ); #endif /* _GPXE_TFTP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/gdbudp.h0000664000000000000000000000102012524662415020740 0ustar #ifndef _GPXE_GDBUDP_H #define _GPXE_GDBUDP_H /** @file * * GDB remote debugging over UDP * */ FILE_LICENCE ( GPL2_OR_LATER ); struct sockaddr_in; struct gdb_transport; /** * Set up the UDP transport with network address * * @name network device name * @addr IP address and UDP listen port, may be NULL and fields may be zero * @ret transport suitable for starting the GDB stub or NULL on error */ struct gdb_transport *gdbudp_configure ( const char *name, struct sockaddr_in *addr ); #endif /* _GPXE_GDBUDP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/null_nap.h0000664000000000000000000000052212524662415021311 0ustar #ifndef _GPXE_NULL_NAP_H #define _GPXE_NULL_NAP_H /** @file * * Null CPU sleeping * */ FILE_LICENCE ( GPL2_OR_LATER ); #ifdef NAP_NULL #define NAP_PREFIX_null #else #define NAP_PREFIX_null __null_ #endif static inline __always_inline void NAP_INLINE ( null, cpu_nap ) ( void ) { /* Do nothing */ } #endif /* _GPXE_NULL_NAP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/resolv.h0000664000000000000000000001073112524662415021016 0ustar #ifndef _GPXE_RESOLV_H #define _GPXE_RESOLV_H /** @file * * Name resolution * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include struct resolv_interface; /** Name resolution interface operations */ struct resolv_interface_operations { /** Name resolution completed * * @v resolv Name resolution interface * @v sa Completed socket address (if successful) * @v rc Final status code */ void ( * done ) ( struct resolv_interface *resolv, struct sockaddr *sa, int rc ); }; /** A name resolution interface */ struct resolv_interface { /** Generic object communication interface */ struct interface intf; /** Operations for received messages */ struct resolv_interface_operations *op; }; extern struct resolv_interface null_resolv; extern struct resolv_interface_operations null_resolv_ops; /** * Initialise a name resolution interface * * @v resolv Name resolution interface * @v op Name resolution interface operations * @v refcnt Containing object reference counter, or NULL */ static inline void resolv_init ( struct resolv_interface *resolv, struct resolv_interface_operations *op, struct refcnt *refcnt ) { resolv->intf.dest = &null_resolv.intf; resolv->intf.refcnt = refcnt; resolv->op = op; } /** * Get name resolution interface from generic object communication interface * * @v intf Generic object communication interface * @ret resolv Name resolution interface */ static inline __attribute__ (( always_inline )) struct resolv_interface * intf_to_resolv ( struct interface *intf ) { return container_of ( intf, struct resolv_interface, intf ); } /** * Get reference to destination name resolution interface * * @v resolv Name resolution interface * @ret dest Destination interface */ static inline __attribute__ (( always_inline )) struct resolv_interface * resolv_get_dest ( struct resolv_interface *resolv ) { return intf_to_resolv ( intf_get ( resolv->intf.dest ) ); } /** * Drop reference to name resolution interface * * @v resolv name resolution interface */ static inline __attribute__ (( always_inline )) void resolv_put ( struct resolv_interface *resolv ) { intf_put ( &resolv->intf ); } /** * Plug a name resolution interface into a new destination interface * * @v resolv Name resolution interface * @v dest New destination interface */ static inline __attribute__ (( always_inline )) void resolv_plug ( struct resolv_interface *resolv, struct resolv_interface *dest ) { plug ( &resolv->intf, &dest->intf ); } /** * Plug two name resolution interfaces together * * @v a Name resolution interface A * @v b Name resolution interface B */ static inline __attribute__ (( always_inline )) void resolv_plug_plug ( struct resolv_interface *a, struct resolv_interface *b ) { plug_plug ( &a->intf, &b->intf ); } /** * Unplug a name resolution interface * * @v resolv Name resolution interface */ static inline __attribute__ (( always_inline )) void resolv_unplug ( struct resolv_interface *resolv ) { plug ( &resolv->intf, &null_resolv.intf ); } /** * Stop using a name resolution interface * * @v resolv Name resolution interface * * After calling this method, no further messages will be received via * the interface. */ static inline void resolv_nullify ( struct resolv_interface *resolv ) { resolv->op = &null_resolv_ops; }; /** A name resolver */ struct resolver { /** Name of this resolver (e.g. "DNS") */ const char *name; /** Start name resolution * * @v resolv Name resolution interface * @v name Name to resolve * @v sa Socket address to complete * @ret rc Return status code */ int ( * resolv ) ( struct resolv_interface *resolv, const char *name, struct sockaddr *sa ); }; /** Numeric resolver priority */ #define RESOLV_NUMERIC 01 /** Normal resolver priority */ #define RESOLV_NORMAL 02 /** Resolvers table */ #define RESOLVERS __table ( struct resolver, "resolvers" ) /** Register as a name resolver */ #define __resolver( resolv_order ) __table_entry ( RESOLVERS, resolv_order ) extern void resolv_done ( struct resolv_interface *resolv, struct sockaddr *sa, int rc ); extern void ignore_resolv_done ( struct resolv_interface *resolv, struct sockaddr *sa, int rc ); extern struct resolv_interface_operations null_resolv_ops; extern struct resolv_interface null_resolv; extern int resolv ( struct resolv_interface *resolv, const char *name, struct sockaddr *sa ); #endif /* _GPXE_RESOLV_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/rotate.h0000664000000000000000000000136512524662415021005 0ustar #ifndef _GPXE_ROTATE_H #define _GPXE_ROTATE_H /** @file * * Bit operations */ FILE_LICENCE ( GPL2_OR_LATER ); #include static inline uint32_t rol32 ( uint32_t data, unsigned int rotation ) { return ( ( data << rotation ) | ( data >> ( 32 - rotation ) ) ); } static inline uint32_t ror32 ( uint32_t data, unsigned int rotation ) { return ( ( data >> rotation ) | ( data << ( 32 - rotation ) ) ); } static inline uint64_t rol64 ( uint64_t data, unsigned int rotation ) { return ( ( data << rotation ) | ( data >> ( 64 - rotation ) ) ); } static inline uint64_t ror64 ( uint64_t data, unsigned int rotation ) { return ( ( data >> rotation ) | ( data << ( 64 - rotation ) ) ); } #endif /* _GPXE_ROTATE_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/sanboot.h0000664000000000000000000000060212524662415021145 0ustar #ifndef _GPXE_SANBOOT_H #define _GPXE_SANBOOT_H FILE_LICENCE ( GPL2_OR_LATER ); #include struct sanboot_protocol { const char *prefix; int ( * boot ) ( const char *root_path ); }; #define SANBOOT_PROTOCOLS \ __table ( struct sanboot_protocol, "sanboot_protocols" ) #define __sanboot_protocol __table_entry ( SANBOOT_PROTOCOLS, 01 ) #endif /* _GPXE_SANBOOT_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/xfer.h0000664000000000000000000001745712524662415020464 0ustar #ifndef _GPXE_XFER_H #define _GPXE_XFER_H /** @file * * Data transfer interfaces * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include struct xfer_interface; struct xfer_metadata; /** Data transfer interface operations */ struct xfer_interface_operations { /** Close interface * * @v xfer Data transfer interface * @v rc Reason for close */ void ( * close ) ( struct xfer_interface *xfer, int rc ); /** Redirect to new location * * @v xfer Data transfer interface * @v type New location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ int ( * vredirect ) ( struct xfer_interface *xfer, int type, va_list args ); /** Check flow control window * * @v xfer Data transfer interface * @ret len Length of window * * Flow control is regarded as advisory but not mandatory. * Users who have control over their own rate of data * generation should perform a flow control check before * generating new data. Users who have no control (such as * NIC drivers or filter layers) are not obliged to check. * * Data transfer interfaces must be prepared to accept * datagrams even if they are advertising a window of zero * bytes. */ size_t ( * window ) ( struct xfer_interface *xfer ); /** Allocate I/O buffer * * @v xfer Data transfer interface * @v len I/O buffer payload length * @ret iobuf I/O buffer */ struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer, size_t len ); /** Deliver datagram as I/O buffer with metadata * * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code * * A data transfer interface that wishes to support only raw * data delivery should set this method to * xfer_deliver_as_raw(). */ int ( * deliver_iob ) ( struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta ); /** Deliver datagram as raw data * * @v xfer Data transfer interface * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code * * A data transfer interface that wishes to support only I/O * buffer delivery should set this method to * xfer_deliver_as_iob(). */ int ( * deliver_raw ) ( struct xfer_interface *xfer, const void *data, size_t len ); }; /** A data transfer interface */ struct xfer_interface { /** Generic object communication interface */ struct interface intf; /** Operations for received messages */ struct xfer_interface_operations *op; }; /** Basis positions for seek() events */ enum seek_whence { SEEK_CUR = 0, SEEK_SET, }; /** Data transfer metadata */ struct xfer_metadata { /** Position of data within stream */ off_t offset; /** Basis for data position * * Must be one of @c SEEK_CUR or @c SEEK_SET. */ int whence; /** Source socket address, or NULL */ struct sockaddr *src; /** Destination socket address, or NULL */ struct sockaddr *dest; /** Network device, or NULL */ struct net_device *netdev; }; /** * Describe seek basis * * @v whence Basis for new position */ static inline __attribute__ (( always_inline )) const char * whence_text ( int whence ) { switch ( whence ) { case SEEK_CUR: return "CUR"; case SEEK_SET: return "SET"; default: return "INVALID"; } } extern struct xfer_interface null_xfer; extern struct xfer_interface_operations null_xfer_ops; extern void xfer_close ( struct xfer_interface *xfer, int rc ); extern int xfer_vredirect ( struct xfer_interface *xfer, int type, va_list args ); extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... ); extern size_t xfer_window ( struct xfer_interface *xfer ); extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ); extern int xfer_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf ); extern int xfer_deliver_iob_meta ( struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta ); extern int xfer_deliver_raw ( struct xfer_interface *xfer, const void *data, size_t len ); extern int xfer_vprintf ( struct xfer_interface *xfer, const char *format, va_list args ); extern int __attribute__ (( format ( printf, 2, 3 ) )) xfer_printf ( struct xfer_interface *xfer, const char *format, ... ); extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ); extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc ); extern int ignore_xfer_vredirect ( struct xfer_interface *xfer, int type, va_list args ); extern size_t unlimited_xfer_window ( struct xfer_interface *xfer ); extern size_t no_xfer_window ( struct xfer_interface *xfer ); extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ); extern int xfer_deliver_as_raw ( struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta ); extern int xfer_deliver_as_iob ( struct xfer_interface *xfer, const void *data, size_t len ); extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer, const void *data __unused, size_t len ); /** * Initialise a data transfer interface * * @v xfer Data transfer interface * @v op Data transfer interface operations * @v refcnt Containing object reference counter, or NULL */ static inline void xfer_init ( struct xfer_interface *xfer, struct xfer_interface_operations *op, struct refcnt *refcnt ) { xfer->intf.dest = &null_xfer.intf; xfer->intf.refcnt = refcnt; xfer->op = op; } /** * Initialise a static data transfer interface * * @v operations Data transfer interface operations */ #define XFER_INIT( operations ) { \ .intf = { \ .dest = &null_xfer.intf, \ .refcnt = NULL, \ }, \ .op = operations, \ } /** * Get data transfer interface from generic object communication interface * * @v intf Generic object communication interface * @ret xfer Data transfer interface */ static inline __attribute__ (( always_inline )) struct xfer_interface * intf_to_xfer ( struct interface *intf ) { return container_of ( intf, struct xfer_interface, intf ); } /** * Get reference to destination data transfer interface * * @v xfer Data transfer interface * @ret dest Destination interface */ static inline __attribute__ (( always_inline )) struct xfer_interface * xfer_get_dest ( struct xfer_interface *xfer ) { return intf_to_xfer ( intf_get ( xfer->intf.dest ) ); } /** * Drop reference to data transfer interface * * @v xfer Data transfer interface */ static inline __attribute__ (( always_inline )) void xfer_put ( struct xfer_interface *xfer ) { intf_put ( &xfer->intf ); } /** * Plug a data transfer interface into a new destination interface * * @v xfer Data transfer interface * @v dest New destination interface */ static inline __attribute__ (( always_inline )) void xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) { plug ( &xfer->intf, &dest->intf ); } /** * Plug two data transfer interfaces together * * @v a Data transfer interface A * @v b Data transfer interface B */ static inline __attribute__ (( always_inline )) void xfer_plug_plug ( struct xfer_interface *a, struct xfer_interface *b ) { plug_plug ( &a->intf, &b->intf ); } /** * Unplug a data transfer interface * * @v xfer Data transfer interface */ static inline __attribute__ (( always_inline )) void xfer_unplug ( struct xfer_interface *xfer ) { plug ( &xfer->intf, &null_xfer.intf ); } /** * Stop using a data transfer interface * * @v xfer Data transfer interface * * After calling this method, no further messages will be received via * the interface. */ static inline void xfer_nullify ( struct xfer_interface *xfer ) { xfer->op = &null_xfer_ops; }; #endif /* _GPXE_XFER_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ib_mad.h0000664000000000000000000003524012524662415020721 0ustar #ifndef _GPXE_IB_MAD_H #define _GPXE_IB_MAD_H /** @file * * Infiniband management datagrams * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /***************************************************************************** * * Subnet management MADs * ***************************************************************************** */ /** A subnet management header * * Defined in sections 14.2.1.1 and 14.2.1.2 of the IBA. */ struct ib_smp_hdr { uint64_t mkey; uint16_t slid; uint16_t dlid; uint8_t reserved[28]; } __attribute__ (( packed )); /** Subnet management class version */ #define IB_SMP_CLASS_VERSION 1 /** Subnet management direction bit * * This bit resides in the "status" field in the MAD header. */ #define IB_SMP_STATUS_D_INBOUND 0x8000 /* Subnet management attributes */ #define IB_SMP_ATTR_NOTICE 0x0002 #define IB_SMP_ATTR_NODE_DESC 0x0010 #define IB_SMP_ATTR_NODE_INFO 0x0011 #define IB_SMP_ATTR_SWITCH_INFO 0x0012 #define IB_SMP_ATTR_GUID_INFO 0x0014 #define IB_SMP_ATTR_PORT_INFO 0x0015 #define IB_SMP_ATTR_PKEY_TABLE 0x0016 #define IB_SMP_ATTR_SL_TO_VL_TABLE 0x0017 #define IB_SMP_ATTR_VL_ARB_TABLE 0x0018 #define IB_SMP_ATTR_LINEAR_FORWARD_TABLE 0x0019 #define IB_SMP_ATTR_RANDOM_FORWARD_TABLE 0x001A #define IB_SMP_ATTR_MCAST_FORWARD_TABLE 0x001B #define IB_SMP_ATTR_SM_INFO 0x0020 #define IB_SMP_ATTR_VENDOR_DIAG 0x0030 #define IB_SMP_ATTR_LED_INFO 0x0031 #define IB_SMP_ATTR_VENDOR_MASK 0xFF00 /** * A Node Description attribute * * Defined in section 14.2.5.2 of the IBA */ struct ib_node_desc { char node_string[64]; } __attribute__ (( packed )); /** A Node Information attribute * * Defined in section 14.2.5.3 of the IBA. */ struct ib_node_info { uint8_t base_version; uint8_t class_version; uint8_t node_type; uint8_t num_ports; struct ib_gid_half sys_guid; struct ib_gid_half node_guid; struct ib_gid_half port_guid; uint16_t partition_cap; uint16_t device_id; uint32_t revision; uint8_t local_port_num; uint8_t vendor_id[3]; } __attribute__ ((packed)); #define IB_NODE_TYPE_HCA 0x01 #define IB_NODE_TYPE_SWITCH 0x02 #define IB_NODE_TYPE_ROUTER 0x03 /** A GUID Information attribute * * Defined in section 14.2.5.5 of the IBA. */ struct ib_guid_info { uint8_t guid[8][8]; } __attribute__ (( packed )); /** A Port Information attribute * * Defined in section 14.2.5.6 of the IBA. */ struct ib_port_info { uint64_t mkey; uint8_t gid_prefix[8]; uint16_t lid; uint16_t mastersm_lid; uint32_t cap_mask; uint16_t diag_code; uint16_t mkey_lease_period; uint8_t local_port_num; uint8_t link_width_enabled; uint8_t link_width_supported; uint8_t link_width_active; uint8_t link_speed_supported__port_state; uint8_t port_phys_state__link_down_def_state; uint8_t mkey_prot_bits__lmc; uint8_t link_speed_active__link_speed_enabled; uint8_t neighbour_mtu__mastersm_sl; uint8_t vl_cap__init_type; uint8_t vl_high_limit; uint8_t vl_arbitration_high_cap; uint8_t vl_arbitration_low_cap; uint8_t init_type_reply__mtu_cap; uint8_t vl_stall_count__hoq_life; uint8_t operational_vls__enforcement; uint16_t mkey_violations; uint16_t pkey_violations; uint16_t qkey_violations; uint8_t guid_cap; uint8_t client_reregister__subnet_timeout; uint8_t resp_time_value; uint8_t local_phy_errors__overrun_errors; uint16_t max_credit_hint; uint32_t link_round_trip_latency; } __attribute__ (( packed )); #define IB_LINK_WIDTH_1X 0x01 #define IB_LINK_WIDTH_4X 0x02 #define IB_LINK_WIDTH_8X 0x04 #define IB_LINK_WIDTH_12X 0x08 #define IB_LINK_SPEED_SDR 0x01 #define IB_LINK_SPEED_DDR 0x02 #define IB_LINK_SPEED_QDR 0x04 #define IB_PORT_STATE_DOWN 0x01 #define IB_PORT_STATE_INIT 0x02 #define IB_PORT_STATE_ARMED 0x03 #define IB_PORT_STATE_ACTIVE 0x04 #define IB_PORT_PHYS_STATE_SLEEP 0x01 #define IB_PORT_PHYS_STATE_POLLING 0x02 #define IB_MTU_256 0x01 #define IB_MTU_512 0x02 #define IB_MTU_1024 0x03 #define IB_MTU_2048 0x04 #define IB_MTU_4096 0x05 #define IB_VL_0 0x01 #define IB_VL_0_1 0x02 #define IB_VL_0_3 0x03 #define IB_VL_0_7 0x04 #define IB_VL_0_14 0x05 /** A Partition Key Table attribute * * Defined in section 14.2.5.7 of the IBA. */ struct ib_pkey_table { uint16_t pkey[32]; } __attribute__ (( packed )); /** A subnet management attribute */ union ib_smp_data { struct ib_node_desc node_desc; struct ib_node_info node_info; struct ib_guid_info guid_info; struct ib_port_info port_info; struct ib_pkey_table pkey_table; uint8_t bytes[64]; } __attribute__ (( packed )); /** A subnet management directed route path */ struct ib_smp_dr_path { uint8_t hops[64]; } __attribute__ (( packed )); /** Subnet management MAD class-specific data */ struct ib_smp_class_specific { uint8_t hop_pointer; uint8_t hop_count; } __attribute__ (( packed )); /***************************************************************************** * * Subnet administration MADs * ***************************************************************************** */ #define IB_SA_CLASS_VERSION 2 #define IB_SA_METHOD_DELETE_RESP 0x95 struct ib_rmpp_hdr { uint32_t raw[3]; } __attribute__ (( packed )); struct ib_sa_hdr { uint32_t sm_key[2]; uint16_t reserved; uint16_t attrib_offset; uint32_t comp_mask[2]; } __attribute__ (( packed )); #define IB_SA_ATTR_MC_MEMBER_REC 0x38 #define IB_SA_ATTR_PATH_REC 0x35 struct ib_path_record { uint32_t reserved0[2]; struct ib_gid dgid; struct ib_gid sgid; uint16_t dlid; uint16_t slid; uint32_t hop_limit__flow_label__raw_traffic; uint32_t pkey__numb_path__reversible__tclass; uint8_t reserved1; uint8_t reserved__sl; uint8_t mtu_selector__mtu; uint8_t rate_selector__rate; uint32_t preference__packet_lifetime__packet_lifetime_selector; uint32_t reserved2[35]; } __attribute__ (( packed )); #define IB_SA_PATH_REC_DGID (1<<2) #define IB_SA_PATH_REC_SGID (1<<3) struct ib_mc_member_record { struct ib_gid mgid; struct ib_gid port_gid; uint32_t qkey; uint16_t mlid; uint8_t mtu_selector__mtu; uint8_t tclass; uint16_t pkey; uint8_t rate_selector__rate; uint8_t packet_lifetime_selector__packet_lifetime; uint32_t sl__flow_label__hop_limit; uint8_t scope__join_state; uint8_t proxy_join__reserved; uint16_t reserved0; uint32_t reserved1[37]; } __attribute__ (( packed )); #define IB_SA_MCMEMBER_REC_MGID (1<<0) #define IB_SA_MCMEMBER_REC_PORT_GID (1<<1) #define IB_SA_MCMEMBER_REC_QKEY (1<<2) #define IB_SA_MCMEMBER_REC_MLID (1<<3) #define IB_SA_MCMEMBER_REC_MTU_SELECTOR (1<<4) #define IB_SA_MCMEMBER_REC_MTU (1<<5) #define IB_SA_MCMEMBER_REC_TRAFFIC_CLASS (1<<6) #define IB_SA_MCMEMBER_REC_PKEY (1<<7) #define IB_SA_MCMEMBER_REC_RATE_SELECTOR (1<<8) #define IB_SA_MCMEMBER_REC_RATE (1<<9) #define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR (1<<10) #define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME (1<<11) #define IB_SA_MCMEMBER_REC_SL (1<<12) #define IB_SA_MCMEMBER_REC_FLOW_LABEL (1<<13) #define IB_SA_MCMEMBER_REC_HOP_LIMIT (1<<14) #define IB_SA_MCMEMBER_REC_SCOPE (1<<15) #define IB_SA_MCMEMBER_REC_JOIN_STATE (1<<16) #define IB_SA_MCMEMBER_REC_PROXY_JOIN (1<<17) union ib_sa_data { struct ib_path_record path_record; struct ib_mc_member_record mc_member_record; } __attribute__ (( packed )); /***************************************************************************** * * Communication management MADs * ***************************************************************************** */ /** Communication management class version */ #define IB_CM_CLASS_VERSION 2 /* Communication management attributes */ #define IB_CM_ATTR_CLASS_PORT_INFO 0x0001 #define IB_CM_ATTR_CONNECT_REQUEST 0x0010 #define IB_CM_ATTR_MSG_RCPT_ACK 0x0011 #define IB_CM_ATTR_CONNECT_REJECT 0x0012 #define IB_CM_ATTR_CONNECT_REPLY 0x0013 #define IB_CM_ATTR_READY_TO_USE 0x0014 #define IB_CM_ATTR_DISCONNECT_REQUEST 0x0015 #define IB_CM_ATTR_DISCONNECT_REPLY 0x0016 #define IB_CM_ATTR_SERVICE_ID_RES_REQ 0x0016 #define IB_CM_ATTR_SERVICE_ID_RES_REQ_RESP 0x0018 #define IB_CM_ATTR_LOAD_ALTERNATE_PATH 0x0019 #define IB_CM_ATTR_ALTERNATE_PATH_RESPONSE 0x001a /** Communication management common fields */ struct ib_cm_common { /** Local communication ID */ uint32_t local_id; /** Remote communication ID */ uint32_t remote_id; /** Reserved */ uint8_t reserved[224]; } __attribute__ (( packed )); /** A communication management path */ struct ib_cm_path { /** Local port LID */ uint16_t local_lid; /** Remote port LID */ uint16_t remote_lid; /** Local port GID */ struct ib_gid local_gid; /** Remote port GID */ struct ib_gid remote_gid; /** Flow label and rate */ uint32_t flow_label__rate; /** Traffic class */ uint8_t tc; /** Hop limit */ uint8_t hop_limit; /** SL and subnet local*/ uint8_t sl__subnet_local; /** Local ACK timeout */ uint8_t local_ack_timeout; } __attribute__ (( packed )); /** A communication management connection request * * Defined in section 12.6.5 of the IBA. */ struct ib_cm_connect_request { /** Local communication ID */ uint32_t local_id; /** Reserved */ uint32_t reserved0[1]; /** Service ID */ struct ib_gid_half service_id; /** Local CA GUID */ struct ib_gid_half local_ca; /** Reserved */ uint32_t reserved1[1]; /** Local queue key */ uint32_t local_qkey; /** Local QPN and responder resources*/ uint32_t local_qpn__responder_resources; /** Local EECN and initiator depth */ uint32_t local_eecn__initiator_depth; /** Remote EECN, remote CM response timeout, transport service * type, EE flow control */ uint32_t remote_eecn__remote_timeout__service_type__ee_flow_ctrl; /** Starting PSN, local CM response timeout and retry count */ uint32_t starting_psn__local_timeout__retry_count; /** Partition key */ uint16_t pkey; /** Path packet payload MTU, RDC exists, RNR retry count */ uint8_t payload_mtu__rdc_exists__rnr_retry; /** Max CM retries and SRQ */ uint8_t max_cm_retries__srq; /** Primary path */ struct ib_cm_path primary; /** Alternate path */ struct ib_cm_path alternate; /** Private data */ uint8_t private_data[92]; } __attribute__ (( packed )); /** CM transport types */ #define IB_CM_TRANSPORT_RC 0 #define IB_CM_TRANSPORT_UC 1 #define IB_CM_TRANSPORT_RD 2 /** A communication management connection rejection * * Defined in section 12.6.7 of the IBA. */ struct ib_cm_connect_reject { /** Local communication ID */ uint32_t local_id; /** Remote communication ID */ uint32_t remote_id; /** Message rejected */ uint8_t message; /** Reject information length */ uint8_t info_len; /** Rejection reason */ uint16_t reason; /** Additional rejection information */ uint8_t info[72]; /** Private data */ uint8_t private_data[148]; } __attribute__ (( packed )); /** CM rejection reasons */ #define IB_CM_REJECT_BAD_SERVICE_ID 8 #define IB_CM_REJECT_STALE_CONN 10 #define IB_CM_REJECT_CONSUMER 28 /** A communication management connection reply * * Defined in section 12.6.8 of the IBA. */ struct ib_cm_connect_reply { /** Local communication ID */ uint32_t local_id; /** Remote communication ID */ uint32_t remote_id; /** Local queue key */ uint32_t local_qkey; /** Local QPN */ uint32_t local_qpn; /** Local EECN */ uint32_t local_eecn; /** Starting PSN */ uint32_t starting_psn; /** Responder resources */ uint8_t responder_resources; /** Initiator depth */ uint8_t initiator_depth; /** Target ACK delay, failover accepted, and end-to-end flow control */ uint8_t target_ack_delay__failover_accepted__ee_flow_ctrl; /** RNR retry count, SRQ */ uint8_t rnr_retry__srq; /** Local CA GUID */ struct ib_gid_half local_ca; /** Private data */ uint8_t private_data[196]; } __attribute__ (( packed )); /** A communication management ready to use reply * * Defined in section 12.6.9 of the IBA. */ struct ib_cm_ready_to_use { /** Local communication ID */ uint32_t local_id; /** Remote communication ID */ uint32_t remote_id; /** Private data */ uint8_t private_data[224]; } __attribute__ (( packed )); /** A communication management attribute */ union ib_cm_data { struct ib_cm_common common; struct ib_cm_connect_request connect_request; struct ib_cm_connect_reject connect_reject; struct ib_cm_connect_reply connect_reply; struct ib_cm_ready_to_use ready_to_use; uint8_t bytes[232]; } __attribute__ (( packed )); /***************************************************************************** * * MADs * ***************************************************************************** */ /** Management datagram class_specific data */ union ib_mad_class_specific { uint16_t raw; struct ib_smp_class_specific smp; } __attribute__ (( packed )); /** A management datagram common header * * Defined in section 13.4.2 of the IBA. */ struct ib_mad_hdr { uint8_t base_version; uint8_t mgmt_class; uint8_t class_version; uint8_t method; uint16_t status; union ib_mad_class_specific class_specific; uint32_t tid[2]; uint16_t attr_id; uint8_t reserved[2]; uint32_t attr_mod; } __attribute__ (( packed )); /* Management base version */ #define IB_MGMT_BASE_VERSION 1 /* Management classes */ #define IB_MGMT_CLASS_SUBN_LID_ROUTED 0x01 #define IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE 0x81 #define IB_MGMT_CLASS_SUBN_ADM 0x03 #define IB_MGMT_CLASS_PERF_MGMT 0x04 #define IB_MGMT_CLASS_BM 0x05 #define IB_MGMT_CLASS_DEVICE_MGMT 0x06 #define IB_MGMT_CLASS_CM 0x07 #define IB_MGMT_CLASS_SNMP 0x08 #define IB_MGMT_CLASS_VENDOR_RANGE2_START 0x30 #define IB_MGMT_CLASS_VENDOR_RANGE2_END 0x4f #define IB_MGMT_CLASS_MASK 0x7f /* Management methods */ #define IB_MGMT_METHOD_GET 0x01 #define IB_MGMT_METHOD_SET 0x02 #define IB_MGMT_METHOD_GET_RESP 0x81 #define IB_MGMT_METHOD_SEND 0x03 #define IB_MGMT_METHOD_TRAP 0x05 #define IB_MGMT_METHOD_REPORT 0x06 #define IB_MGMT_METHOD_REPORT_RESP 0x86 #define IB_MGMT_METHOD_TRAP_REPRESS 0x07 #define IB_MGMT_METHOD_DELETE 0x15 /* Status codes */ #define IB_MGMT_STATUS_OK 0x0000 #define IB_MGMT_STATUS_BAD_VERSION 0x0001 #define IB_MGMT_STATUS_UNSUPPORTED_METHOD 0x0002 #define IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR 0x0003 #define IB_MGMT_STATUS_INVALID_VALUE 0x0004 /** A subnet management MAD */ struct ib_mad_smp { struct ib_mad_hdr mad_hdr; struct ib_smp_hdr smp_hdr; union ib_smp_data smp_data; struct ib_smp_dr_path initial_path; struct ib_smp_dr_path return_path; } __attribute__ (( packed )); /** A subnet administration MAD */ struct ib_mad_sa { struct ib_mad_hdr mad_hdr; struct ib_rmpp_hdr rmpp_hdr; struct ib_sa_hdr sa_hdr; union ib_sa_data sa_data; } __attribute__ (( packed )); /** A communication management MAD */ struct ib_mad_cm { struct ib_mad_hdr mad_hdr; union ib_cm_data cm_data; } __attribute__ (( packed )); /** A management datagram */ union ib_mad { struct ib_mad_hdr hdr; struct ib_mad_smp smp; struct ib_mad_sa sa; struct ib_mad_cm cm; uint8_t bytes[256]; } __attribute__ (( packed )); #endif /* _GPXE_IB_MAD_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/cbc.h0000664000000000000000000000612112524662415020231 0ustar #ifndef _GPXE_CBC_H #define _GPXE_CBC_H /** @file * * Cipher-block chaining * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** * Set key * * @v ctx Context * @v key Key * @v keylen Key length * @v raw_cipher Underlying cipher algorithm * @v cbc_ctx CBC context * @ret rc Return status code */ static inline int cbc_setkey ( void *ctx, const void *key, size_t keylen, struct cipher_algorithm *raw_cipher, void *cbc_ctx __unused ) { return cipher_setkey ( raw_cipher, ctx, key, keylen ); } /** * Set initialisation vector * * @v ctx Context * @v iv Initialisation vector * @v raw_cipher Underlying cipher algorithm * @v cbc_ctx CBC context */ static inline void cbc_setiv ( void *ctx __unused, const void *iv, struct cipher_algorithm *raw_cipher, void *cbc_ctx ) { memcpy ( cbc_ctx, iv, raw_cipher->blocksize ); } extern void cbc_encrypt ( void *ctx, const void *src, void *dst, size_t len, struct cipher_algorithm *raw_cipher, void *cbc_ctx ); extern void cbc_decrypt ( void *ctx, const void *src, void *dst, size_t len, struct cipher_algorithm *raw_cipher, void *cbc_ctx ); /** * Create a cipher-block chaining mode of behaviour of an existing cipher * * @v _cbc_name Name for the new CBC cipher * @v _cbc_cipher New cipher algorithm * @v _raw_cipher Underlying cipher algorithm * @v _raw_context Context structure for the underlying cipher * @v _blocksize Cipher block size */ #define CBC_CIPHER( _cbc_name, _cbc_cipher, _raw_cipher, _raw_context, \ _blocksize ) \ struct _cbc_name ## _context { \ _raw_context raw_ctx; \ uint8_t cbc_ctx[_blocksize]; \ }; \ static int _cbc_name ## _setkey ( void *ctx, const void *key, \ size_t keylen ) { \ struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \ return cbc_setkey ( &_cbc_name ## _ctx->raw_ctx, key, keylen, \ &_raw_cipher, &_cbc_name ## _ctx->cbc_ctx );\ } \ static void _cbc_name ## _setiv ( void *ctx, const void *iv ) { \ struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \ cbc_setiv ( &_cbc_name ## _ctx->raw_ctx, iv, \ &_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \ } \ static void _cbc_name ## _encrypt ( void *ctx, const void *src, \ void *dst, size_t len ) { \ struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \ cbc_encrypt ( &_cbc_name ## _ctx->raw_ctx, src, dst, len, \ &_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \ } \ static void _cbc_name ## _decrypt ( void *ctx, const void *src, \ void *dst, size_t len ) { \ struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \ cbc_decrypt ( &_cbc_name ## _ctx->raw_ctx, src, dst, len, \ &_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \ } \ struct cipher_algorithm _cbc_cipher = { \ .name = #_cbc_name, \ .ctxsize = sizeof ( struct _cbc_name ## _context ), \ .blocksize = _blocksize, \ .setkey = _cbc_name ## _setkey, \ .setiv = _cbc_name ## _setiv, \ .encrypt = _cbc_name ## _encrypt, \ .decrypt = _cbc_name ## _decrypt, \ }; #endif /* _GPXE_CBC_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/infiniband.h0000664000000000000000000004070712524662415021613 0ustar #ifndef _GPXE_INFINIBAND_H #define _GPXE_INFINIBAND_H /** @file * * Infiniband protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include /** Subnet management interface QPN */ #define IB_QPN_SMI 0 /** Subnet management interface queue key */ #define IB_QKEY_SMI 0 /** General service interface QPN */ #define IB_QPN_GSI 1 /** General service interface queue key */ #define IB_QKEY_GSI 0x80010000UL /** Broadcast QPN */ #define IB_QPN_BROADCAST 0xffffffUL /** Default Infiniband partition key */ #define IB_PKEY_NONE 0xffff /** * Maximum payload size * * This is currently hard-coded in various places (drivers, subnet * management agent, etc.) to 2048. */ #define IB_MAX_PAYLOAD_SIZE 2048 struct ib_device; struct ib_queue_pair; struct ib_address_vector; struct ib_completion_queue; struct ib_mad_interface; /** Infiniband transmission rates */ enum ib_rate { IB_RATE_2_5 = 2, IB_RATE_10 = 3, IB_RATE_30 = 4, IB_RATE_5 = 5, IB_RATE_20 = 6, IB_RATE_40 = 7, IB_RATE_60 = 8, IB_RATE_80 = 9, IB_RATE_120 = 10, }; /** An Infiniband Address Vector */ struct ib_address_vector { /** Queue Pair Number */ unsigned long qpn; /** Queue key * * Not specified for received packets. */ unsigned long qkey; /** Local ID */ unsigned int lid; /** Rate * * Not specified for received packets. */ enum ib_rate rate; /** Service level */ unsigned int sl; /** GID is present */ unsigned int gid_present; /** GID, if present */ struct ib_gid gid; }; /** An Infiniband Work Queue */ struct ib_work_queue { /** Containing queue pair */ struct ib_queue_pair *qp; /** "Is a send queue" flag */ int is_send; /** Associated completion queue */ struct ib_completion_queue *cq; /** List of work queues on this completion queue */ struct list_head list; /** Packet sequence number */ uint32_t psn; /** Number of work queue entries */ unsigned int num_wqes; /** Number of occupied work queue entries */ unsigned int fill; /** Next work queue entry index * * This is the index of the next entry to be filled (i.e. the * first empty entry). This value is not bounded by num_wqes; * users must logical-AND with (num_wqes-1) to generate an * array index. */ unsigned long next_idx; /** I/O buffers assigned to work queue */ struct io_buffer **iobufs; /** Driver private data */ void *drv_priv; }; /** An Infiniband multicast GID */ struct ib_multicast_gid { /** List of multicast GIDs on this QP */ struct list_head list; /** Multicast GID */ struct ib_gid gid; }; /** An Infiniband queue pair type */ enum ib_queue_pair_type { IB_QPT_SMI, IB_QPT_GSI, IB_QPT_UD, IB_QPT_RC, }; /** An Infiniband Queue Pair */ struct ib_queue_pair { /** Containing Infiniband device */ struct ib_device *ibdev; /** List of queue pairs on this Infiniband device */ struct list_head list; /** Queue pair number */ unsigned long qpn; /** Externally-visible queue pair number * * This may differ from the real queue pair number (e.g. when * the HCA cannot use the management QPNs 0 and 1 as hardware * QPNs and needs to remap them). */ unsigned long ext_qpn; /** Queue pair type */ enum ib_queue_pair_type type; /** Queue key */ unsigned long qkey; /** Send queue */ struct ib_work_queue send; /** Receive queue */ struct ib_work_queue recv; /** List of multicast GIDs */ struct list_head mgids; /** Address vector */ struct ib_address_vector av; /** Driver private data */ void *drv_priv; /** Queue owner private data */ void *owner_priv; }; /** Infiniband completion queue operations */ struct ib_completion_queue_operations { /** * Complete Send WQE * * @v ibdev Infiniband device * @v qp Queue pair * @v iobuf I/O buffer * @v rc Completion status code */ void ( * complete_send ) ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf, int rc ); /** * Complete Receive WQE * * @v ibdev Infiniband device * @v qp Queue pair * @v av Address vector, or NULL * @v iobuf I/O buffer * @v rc Completion status code */ void ( * complete_recv ) ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf, int rc ); }; /** An Infiniband Completion Queue */ struct ib_completion_queue { /** Containing Infiniband device */ struct ib_device *ibdev; /** List of completion queues on this Infiniband device */ struct list_head list; /** Completion queue number */ unsigned long cqn; /** Number of completion queue entries */ unsigned int num_cqes; /** Next completion queue entry index * * This is the index of the next entry to be filled (i.e. the * first empty entry). This value is not bounded by num_wqes; * users must logical-AND with (num_wqes-1) to generate an * array index. */ unsigned long next_idx; /** List of work queues completing to this queue */ struct list_head work_queues; /** Completion queue operations */ struct ib_completion_queue_operations *op; /** Driver private data */ void *drv_priv; }; /** * Infiniband device operations * * These represent a subset of the Infiniband Verbs. */ struct ib_device_operations { /** Create completion queue * * @v ibdev Infiniband device * @v cq Completion queue * @ret rc Return status code */ int ( * create_cq ) ( struct ib_device *ibdev, struct ib_completion_queue *cq ); /** Destroy completion queue * * @v ibdev Infiniband device * @v cq Completion queue */ void ( * destroy_cq ) ( struct ib_device *ibdev, struct ib_completion_queue *cq ); /** Create queue pair * * @v ibdev Infiniband device * @v qp Queue pair * @ret rc Return status code */ int ( * create_qp ) ( struct ib_device *ibdev, struct ib_queue_pair *qp ); /** Modify queue pair * * @v ibdev Infiniband device * @v qp Queue pair * @ret rc Return status code */ int ( * modify_qp ) ( struct ib_device *ibdev, struct ib_queue_pair *qp ); /** Destroy queue pair * * @v ibdev Infiniband device * @v qp Queue pair */ void ( * destroy_qp ) ( struct ib_device *ibdev, struct ib_queue_pair *qp ); /** Post send work queue entry * * @v ibdev Infiniband device * @v qp Queue pair * @v av Address vector * @v iobuf I/O buffer * @ret rc Return status code * * If this method returns success, the I/O buffer remains * owned by the queue pair. If this method returns failure, * the I/O buffer is immediately released; the failure is * interpreted as "failure to enqueue buffer". */ int ( * post_send ) ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf ); /** Post receive work queue entry * * @v ibdev Infiniband device * @v qp Queue pair * @v iobuf I/O buffer * @ret rc Return status code * * If this method returns success, the I/O buffer remains * owned by the queue pair. If this method returns failure, * the I/O buffer is immediately released; the failure is * interpreted as "failure to enqueue buffer". */ int ( * post_recv ) ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf ); /** Poll completion queue * * @v ibdev Infiniband device * @v cq Completion queue * * The relevant completion handler (specified at completion * queue creation time) takes ownership of the I/O buffer. */ void ( * poll_cq ) ( struct ib_device *ibdev, struct ib_completion_queue *cq ); /** * Poll event queue * * @v ibdev Infiniband device */ void ( * poll_eq ) ( struct ib_device *ibdev ); /** * Open port * * @v ibdev Infiniband device * @ret rc Return status code */ int ( * open ) ( struct ib_device *ibdev ); /** * Close port * * @v ibdev Infiniband device */ void ( * close ) ( struct ib_device *ibdev ); /** Attach to multicast group * * @v ibdev Infiniband device * @v qp Queue pair * @v gid Multicast GID * @ret rc Return status code */ int ( * mcast_attach ) ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_gid *gid ); /** Detach from multicast group * * @v ibdev Infiniband device * @v qp Queue pair * @v gid Multicast GID */ void ( * mcast_detach ) ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_gid *gid ); /** Set port information * * @v ibdev Infiniband device * @v mad Set port information MAD * * This method is required only by adapters that do not have * an embedded SMA. */ int ( * set_port_info ) ( struct ib_device *ibdev, union ib_mad *mad ); /** Set partition key table * * @v ibdev Infiniband device * @v mad Set partition key table MAD * * This method is required only by adapters that do not have * an embedded SMA. */ int ( * set_pkey_table ) ( struct ib_device *ibdev, union ib_mad *mad ); }; /** An Infiniband device */ struct ib_device { /** Reference counter */ struct refcnt refcnt; /** List of Infiniband devices */ struct list_head list; /** List of open Infiniband devices */ struct list_head open_list; /** Underlying device */ struct device *dev; /** List of completion queues */ struct list_head cqs; /** List of queue pairs */ struct list_head qps; /** Infiniband operations */ struct ib_device_operations *op; /** Port number */ unsigned int port; /** Port open request counter */ unsigned int open_count; /** Port state */ uint8_t port_state; /** Link width supported */ uint8_t link_width_supported; /** Link width enabled */ uint8_t link_width_enabled; /** Link width active */ uint8_t link_width_active; /** Link speed supported */ uint8_t link_speed_supported; /** Link speed enabled */ uint8_t link_speed_enabled; /** Link speed active */ uint8_t link_speed_active; /** Port GID */ struct ib_gid gid; /** Port LID */ uint16_t lid; /** Subnet manager LID */ uint16_t sm_lid; /** Subnet manager SL */ uint8_t sm_sl; /** Partition key */ uint16_t pkey; /** RDMA key * * This is a single key allowing unrestricted access to * memory. */ uint32_t rdma_key; /** Subnet management interface */ struct ib_mad_interface *smi; /** General services interface */ struct ib_mad_interface *gsi; /** Driver private data */ void *drv_priv; /** Owner private data */ void *owner_priv; }; extern struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes, struct ib_completion_queue_operations *op ); extern void ib_destroy_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq ); extern void ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq ); extern struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev, enum ib_queue_pair_type type, unsigned int num_send_wqes, struct ib_completion_queue *send_cq, unsigned int num_recv_wqes, struct ib_completion_queue *recv_cq ); extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ); extern void ib_destroy_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ); extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev, unsigned long qpn ); extern struct ib_queue_pair * ib_find_qp_mgid ( struct ib_device *ibdev, struct ib_gid *gid ); extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq, unsigned long qpn, int is_send ); extern int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf ); extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf ); extern void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf, int rc ); extern void ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf, int rc ); extern void ib_refill_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp ); extern int ib_open ( struct ib_device *ibdev ); extern void ib_close ( struct ib_device *ibdev ); extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_gid *gid ); extern void ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_gid *gid ); extern int ib_get_hca_info ( struct ib_device *ibdev, struct ib_gid_half *hca_guid ); extern int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad ); extern int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad ); extern struct ib_device * alloc_ibdev ( size_t priv_size ); extern int register_ibdev ( struct ib_device *ibdev ); extern void unregister_ibdev ( struct ib_device *ibdev ); extern struct ib_device * find_ibdev ( struct ib_gid *gid ); extern struct ib_device * last_opened_ibdev ( void ); extern void ib_link_state_changed ( struct ib_device *ibdev ); extern void ib_poll_eq ( struct ib_device *ibdev ); extern struct list_head ib_devices; /** Iterate over all network devices */ #define for_each_ibdev( ibdev ) \ list_for_each_entry ( (ibdev), &ib_devices, list ) /** * Check link state * * @v ibdev Infiniband device * @ret link_up Link is up */ static inline __always_inline int ib_link_ok ( struct ib_device *ibdev ) { return ( ibdev->port_state == IB_PORT_STATE_ACTIVE ); } /** * Get reference to Infiniband device * * @v ibdev Infiniband device * @ret ibdev Infiniband device */ static inline __always_inline struct ib_device * ibdev_get ( struct ib_device *ibdev ) { ref_get ( &ibdev->refcnt ); return ibdev; } /** * Drop reference to Infiniband device * * @v ibdev Infiniband device */ static inline __always_inline void ibdev_put ( struct ib_device *ibdev ) { ref_put ( &ibdev->refcnt ); } /** * Set Infiniband work queue driver-private data * * @v wq Work queue * @v priv Private data */ static inline __always_inline void ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) { wq->drv_priv = priv; } /** * Get Infiniband work queue driver-private data * * @v wq Work queue * @ret priv Private data */ static inline __always_inline void * ib_wq_get_drvdata ( struct ib_work_queue *wq ) { return wq->drv_priv; } /** * Set Infiniband queue pair driver-private data * * @v qp Queue pair * @v priv Private data */ static inline __always_inline void ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) { qp->drv_priv = priv; } /** * Get Infiniband queue pair driver-private data * * @v qp Queue pair * @ret priv Private data */ static inline __always_inline void * ib_qp_get_drvdata ( struct ib_queue_pair *qp ) { return qp->drv_priv; } /** * Set Infiniband queue pair owner-private data * * @v qp Queue pair * @v priv Private data */ static inline __always_inline void ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) { qp->owner_priv = priv; } /** * Get Infiniband queue pair owner-private data * * @v qp Queue pair * @ret priv Private data */ static inline __always_inline void * ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) { return qp->owner_priv; } /** * Set Infiniband completion queue driver-private data * * @v cq Completion queue * @v priv Private data */ static inline __always_inline void ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) { cq->drv_priv = priv; } /** * Get Infiniband completion queue driver-private data * * @v cq Completion queue * @ret priv Private data */ static inline __always_inline void * ib_cq_get_drvdata ( struct ib_completion_queue *cq ) { return cq->drv_priv; } /** * Set Infiniband device driver-private data * * @v ibdev Infiniband device * @v priv Private data */ static inline __always_inline void ib_set_drvdata ( struct ib_device *ibdev, void *priv ) { ibdev->drv_priv = priv; } /** * Get Infiniband device driver-private data * * @v ibdev Infiniband device * @ret priv Private data */ static inline __always_inline void * ib_get_drvdata ( struct ib_device *ibdev ) { return ibdev->drv_priv; } /** * Set Infiniband device owner-private data * * @v ibdev Infiniband device * @v priv Private data */ static inline __always_inline void ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) { ibdev->owner_priv = priv; } /** * Get Infiniband device owner-private data * * @v ibdev Infiniband device * @ret priv Private data */ static inline __always_inline void * ib_get_ownerdata ( struct ib_device *ibdev ) { return ibdev->owner_priv; } #endif /* _GPXE_INFINIBAND_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/iobuf.h0000664000000000000000000001305012524662415020605 0ustar #ifndef _GPXE_IOBUF_H #define _GPXE_IOBUF_H /** @file * * I/O buffers * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include /** * I/O buffer alignment * * I/O buffers allocated via alloc_iob() are guaranteed to be * physically aligned to this boundary. Some cards cannot DMA across * a 4kB boundary. With a standard Ethernet MTU, aligning to a 2kB * boundary is sufficient to guarantee no 4kB boundary crossings. For * a jumbo Ethernet MTU, a packet may be larger than 4kB anyway. */ #define IOB_ALIGN 2048 /** * Minimum I/O buffer length * * alloc_iob() will round up the allocated length to this size if * necessary. This is used on behalf of hardware that is not capable * of auto-padding. */ #define IOB_ZLEN 64 /** * A persistent I/O buffer * * This data structure encapsulates a long-lived I/O buffer. The * buffer may be passed between multiple owners, queued for possible * retransmission, etc. */ struct io_buffer { /** List of which this buffer is a member * * The list must belong to the current owner of the buffer. * Different owners may maintain different lists (e.g. a * retransmission list for TCP). */ struct list_head list; /** Start of the buffer */ void *head; /** Start of data */ void *data; /** End of data */ void *tail; /** End of the buffer */ void *end; }; /** * Reserve space at start of I/O buffer * * @v iobuf I/O buffer * @v len Length to reserve * @ret data Pointer to new start of buffer */ static inline void * iob_reserve ( struct io_buffer *iobuf, size_t len ) { iobuf->data += len; iobuf->tail += len; return iobuf->data; } #define iob_reserve( iobuf, len ) ( { \ void *__result; \ __result = iob_reserve ( (iobuf), (len) ); \ assert ( (iobuf)->tail <= (iobuf)->end ); \ __result; } ) /** * Add data to start of I/O buffer * * @v iobuf I/O buffer * @v len Length to add * @ret data Pointer to new start of buffer */ static inline void * iob_push ( struct io_buffer *iobuf, size_t len ) { iobuf->data -= len; return iobuf->data; } #define iob_push( iobuf, len ) ( { \ void *__result; \ __result = iob_push ( (iobuf), (len) ); \ assert ( (iobuf)->data >= (iobuf)->head ); \ __result; } ) /** * Remove data from start of I/O buffer * * @v iobuf I/O buffer * @v len Length to remove * @ret data Pointer to new start of buffer */ static inline void * iob_pull ( struct io_buffer *iobuf, size_t len ) { iobuf->data += len; assert ( iobuf->data <= iobuf->tail ); return iobuf->data; } #define iob_pull( iobuf, len ) ( { \ void *__result; \ __result = iob_pull ( (iobuf), (len) ); \ assert ( (iobuf)->data <= (iobuf)->tail ); \ __result; } ) /** * Add data to end of I/O buffer * * @v iobuf I/O buffer * @v len Length to add * @ret data Pointer to newly added space */ static inline void * iob_put ( struct io_buffer *iobuf, size_t len ) { void *old_tail = iobuf->tail; iobuf->tail += len; return old_tail; } #define iob_put( iobuf, len ) ( { \ void *__result; \ __result = iob_put ( (iobuf), (len) ); \ assert ( (iobuf)->tail <= (iobuf)->end ); \ __result; } ) /** * Remove data from end of I/O buffer * * @v iobuf I/O buffer * @v len Length to remove */ static inline void iob_unput ( struct io_buffer *iobuf, size_t len ) { iobuf->tail -= len; } #define iob_unput( iobuf, len ) do { \ iob_unput ( (iobuf), (len) ); \ assert ( (iobuf)->tail >= (iobuf)->data ); \ } while ( 0 ) /** * Empty an I/O buffer * * @v iobuf I/O buffer */ static inline void iob_empty ( struct io_buffer *iobuf ) { iobuf->tail = iobuf->data; } /** * Calculate length of data in an I/O buffer * * @v iobuf I/O buffer * @ret len Length of data in buffer */ static inline size_t iob_len ( struct io_buffer *iobuf ) { return ( iobuf->tail - iobuf->data ); } /** * Calculate available space at start of an I/O buffer * * @v iobuf I/O buffer * @ret len Length of data available at start of buffer */ static inline size_t iob_headroom ( struct io_buffer *iobuf ) { return ( iobuf->data - iobuf->head ); } /** * Calculate available space at end of an I/O buffer * * @v iobuf I/O buffer * @ret len Length of data available at end of buffer */ static inline size_t iob_tailroom ( struct io_buffer *iobuf ) { return ( iobuf->end - iobuf->tail ); } /** * Create a temporary I/O buffer * * @v iobuf I/O buffer * @v data Data buffer * @v len Length of data * @v max_len Length of buffer * * It is sometimes useful to use the iob_xxx() methods on temporary * data buffers. */ static inline void iob_populate ( struct io_buffer *iobuf, void *data, size_t len, size_t max_len ) { iobuf->head = iobuf->data = data; iobuf->tail = ( data + len ); iobuf->end = ( data + max_len ); } /** * Disown an I/O buffer * * @v iobuf I/O buffer * * There are many functions that take ownership of the I/O buffer they * are passed as a parameter. The caller should not retain a pointer * to the I/O buffer. Use iob_disown() to automatically nullify the * caller's pointer, e.g.: * * xfer_deliver_iob ( xfer, iob_disown ( iobuf ) ); * * This will ensure that iobuf is set to NULL for any code after the * call to xfer_deliver_iob(). */ #define iob_disown( iobuf ) ( { \ struct io_buffer *__iobuf = (iobuf); \ (iobuf) = NULL; \ __iobuf; } ) extern struct io_buffer * __malloc alloc_iob ( size_t len ); extern void free_iob ( struct io_buffer *iobuf ); extern void iob_pad ( struct io_buffer *iobuf, size_t min_len ); extern int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len ); #endif /* _GPXE_IOBUF_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/net80211.h0000664000000000000000000010173712524662415020675 0ustar #ifndef _GPXE_NET80211_H #define _GPXE_NET80211_H #include #include #include #include #include /** @file * * The gPXE 802.11 MAC layer. */ /* * Major things NOT YET supported: * - any type of security * - 802.11n * * Major things that probably will NEVER be supported, barring a * compelling use case and/or corporate sponsorship: * - QoS * - 802.1X authentication ("WPA Enterprise") * - Contention-free periods * - "ad-hoc" networks (IBSS), monitor mode, host AP mode * - hidden networks on the 5GHz band due to regulatory issues * - spectrum management on the 5GHz band (TPC and DFS), as required * in some non-US regulatory domains * - Clause 14 PHYs (Frequency-Hopping Spread Spectrum on 2.4GHz) * and Clause 16 PHYs (infrared) - I'm not aware of any real-world * use of these. */ FILE_LICENCE ( GPL2_OR_LATER ); /* All 802.11 devices are handled using a generic "802.11 device" net_device, with a link in its `priv' field to a net80211_device which we use to handle 802.11-specific details. */ /** @defgroup net80211_band RF bands on which an 802.11 device can transmit */ /** @{ */ /** The 2.4 GHz ISM band, unlicensed in most countries */ #define NET80211_BAND_2GHZ 0 /** The band from 4.9 GHz to 5.7 GHz, which tends to be more restricted */ #define NET80211_BAND_5GHZ 1 /** Number of RF bands */ #define NET80211_NR_BANDS 2 /** Bitmask for the 2GHz band */ #define NET80211_BAND_BIT_2GHZ (1 << 0) /** Bitmask for the 5GHz band */ #define NET80211_BAND_BIT_5GHZ (1 << 1) /** @} */ /** @defgroup net80211_mode 802.11 operation modes supported by hardware */ /** @{ */ /** 802.11a: 54 Mbps operation using OFDM signaling on the 5GHz band */ #define NET80211_MODE_A (1 << 0) /** 802.11b: 1-11 Mbps operation using DSSS/CCK signaling on the 2.4GHz band */ #define NET80211_MODE_B (1 << 1) /** 802.11g: 54 Mbps operation using ERP/OFDM signaling on the 2.4GHz band */ #define NET80211_MODE_G (1 << 2) /** 802.11n: High-rate operation using MIMO technology on 2.4GHz or 5GHz */ #define NET80211_MODE_N (1 << 3) /** @} */ /** @defgroup net80211_cfg Constants for the net80211 config callback */ /** @{ */ /** Channel choice (@c dev->channel) or regulatory parameters have changed */ #define NET80211_CFG_CHANNEL (1 << 0) /** Requested transmission rate (@c dev->rate) has changed */ #define NET80211_CFG_RATE (1 << 1) /** Association has been established with a new BSS (@c dev->bssid) */ #define NET80211_CFG_ASSOC (1 << 2) /** Low-level link parameters (short preamble, protection, etc) have changed */ #define NET80211_CFG_PHY_PARAMS (1 << 3) /** @} */ /** An 802.11 security handshaking protocol */ enum net80211_security_proto { /** No security handshaking * * This might be used with an open network or with WEP, as * WEP does not have a cryptographic handshaking phase. */ NET80211_SECPROT_NONE = 0, /** Pre-shared key handshaking * * This implements the "WPA Personal" handshake. 802.1X * authentication is not performed -- the user supplies a * pre-shared key directly -- but there is a 4-way handshake * between client and AP to verify that both have the same key * without revealing the contents of that key. */ NET80211_SECPROT_PSK = 1, /** Full EAP 802.1X handshaking * * This implements the "WPA Enterprise" handshake, connecting * to an 802.1X authentication server to provide credentials * and receive a pairwise master key (PMK), which is then used * in the same 4-way handshake as the PSK method. */ NET80211_SECPROT_EAP = 2, }; /** An 802.11 data encryption algorithm */ enum net80211_crypto_alg { /** No security, an "Open" network */ NET80211_CRYPT_NONE = 0, /** Network protected with WEP (awful RC4-based system) * * WEP uses a naive application of RC4, with a monotonically * increasing initialization vector that is prepended to the * key to initialize the RC4 keystream. It is highly insecure * and can be completely cracked or subverted using automated, * robust, freely available tools (aircrack-ng) in minutes. * * 40-bit and 104-bit WEP are differentiated only by the size * of the key. They may be advertised as 64-bit and 128-bit, * counting the non-random IV as part of the key bits. */ NET80211_CRYPT_WEP = 1, /** Network protected with TKIP (better RC4-based system) * * Usually known by its trade name of WPA (Wi-Fi Protected * Access), TKIP implements a message integrity code (MIC) * called Michael, a timestamp counter for replay prevention, * and a key mixing function that together remove almost all * the security problems with WEP. Countermeasures are * implemented to prevent high data-rate attacks. * * There exists one known attack on TKIP, that allows one to * send between 7 and 15 arbitrary short data packets on a * QoS-enabled network given about an hour of data * gathering. Since gPXE does not support QoS for 802.11 * networks, this is not a threat to us. The only other method * is a brute-force passphrase attack. */ NET80211_CRYPT_TKIP = 2, /** Network protected with CCMP (AES-based system) * * Often called WPA2 in commerce, or RSNA (Robust Security * Network Architecture) in the 802.11 standard, CCMP is * highly secure and does not have any known attack vectors. * Since it is based on a block cipher, the statistical * correlation and "chopchop" attacks used with great success * against WEP and minor success against TKIP fail. */ NET80211_CRYPT_CCMP = 3, }; /** @defgroup net80211_state Bits for the 802.11 association state field */ /** @{ */ /** An error code indicating the failure mode, or 0 if successful */ #define NET80211_STATUS_MASK 0x7F /** Whether the error code provided is a "reason" code, not a "status" code */ #define NET80211_IS_REASON 0x80 /** Whether we have found the network we will be associating with */ #define NET80211_PROBED (1 << 8) /** Whether we have successfully authenticated with the network * * This usually has nothing to do with actual security; it is a * holdover from older 802.11 implementation ideas. */ #define NET80211_AUTHENTICATED (1 << 9) /** Whether we have successfully associated with the network */ #define NET80211_ASSOCIATED (1 << 10) /** Whether we have completed security handshaking with the network * * Once this is set, we can send data packets. For that reason this * bit is set even in cases where no security handshaking is * required. */ #define NET80211_CRYPTO_SYNCED (1 << 11) /** Whether the auto-association task is running */ #define NET80211_WORKING (1 << 12) /** Whether the auto-association task is waiting for a reply from the AP */ #define NET80211_WAITING (1 << 13) /** Whether the auto-association task should be suppressed * * This is set by the `iwlist' command so that it can open the device * without starting another probe process that will interfere with its * own. */ #define NET80211_NO_ASSOC (1 << 14) /** Whether this association was performed using a broadcast SSID * * If the user opened this device without netX/ssid set, the device's * SSID will be set to that of the network it chooses to associate * with, but the netX/ssid setting will remain blank. If we don't * remember that we started from no specified SSID, it will appear * every time settings are updated (e.g. after DHCP) that we need to * reassociate due to the difference between the set SSID and our own. */ #define NET80211_AUTO_SSID (1 << 15) /** @} */ /** @defgroup net80211_phy 802.11 physical layer flags */ /** @{ */ /** Whether to use RTS/CTS or CTS-to-self protection for transmissions * * Since the RTS or CTS is transmitted using 802.11b signaling, and * includes a field indicating the amount of time that will be used by * transmission of the following packet, this serves as an effective * protection mechanism to avoid 802.11b clients interfering with * 802.11g clients on mixed networks. */ #define NET80211_PHY_USE_PROTECTION (1 << 1) /** Whether to use 802.11b short preamble operation * * Short-preamble operation can moderately increase throughput on * 802.11b networks operating between 2Mbps and 11Mbps. It is * irrelevant for 802.11g data rates, since they use a different * modulation scheme. */ #define NET80211_PHY_USE_SHORT_PREAMBLE (1 << 2) /** Whether to use 802.11g short slot operation * * This affects a low-level timing parameter of 802.11g transmissions. */ #define NET80211_PHY_USE_SHORT_SLOT (1 << 3) /** @} */ /** The maximum number of TX rates we allow to be configured simultaneously */ #define NET80211_MAX_RATES 16 /** The maximum number of channels we allow to be configured simultaneously */ #define NET80211_MAX_CHANNELS 32 /** Seconds we'll wait to get all fragments of a packet */ #define NET80211_FRAG_TIMEOUT 2 /** The number of fragments we can receive at once * * The 802.11 standard requires that this be at least 3. */ #define NET80211_NR_CONCURRENT_FRAGS 3 /** Maximum TX power to allow (dBm), if we don't get a regulatory hint */ #define NET80211_REG_TXPOWER 20 struct net80211_device; /** Operations that must be implemented by an 802.11 driver */ struct net80211_device_operations { /** Open 802.11 device * * @v dev 802.11 device * @ret rc Return status code * * This method should allocate RX I/O buffers and enable the * hardware to start transmitting and receiving packets on the * channels its net80211_register() call indicated it could * handle. It does not need to tune the antenna to receive * packets on any particular channel. */ int ( * open ) ( struct net80211_device *dev ); /** Close 802.11 network device * * @v dev 802.11 device * * This method should stop the flow of packets, and call * net80211_tx_complete() for any packets remaining in the * device's TX queue. */ void ( * close ) ( struct net80211_device *dev ); /** Transmit packet on 802.11 network device * * @v dev 802.11 device * @v iobuf I/O buffer * @ret rc Return status code * * This method should cause the hardware to initiate * transmission of the I/O buffer, using the channel and rate * most recently indicated by an appropriate call to the * @c config callback. The 802.11 layer guarantees that said * channel and rate will be the same as those currently * reflected in the fields of @a dev. * * If this method returns success, the I/O buffer remains * owned by the network layer's TX queue, and the driver must * eventually call net80211_tx_complete() to free the buffer * whether transmission succeeded or not. If this method * returns failure, it will be interpreted as "failure to * enqueue buffer" and the I/O buffer will be immediately * released. * * This method is guaranteed to be called only when the device * is open. */ int ( * transmit ) ( struct net80211_device *dev, struct io_buffer *iobuf ); /** Poll for completed and received packets * * @v dev 802.11 device * * This method should cause the hardware to check for * completed transmissions and received packets. Any received * packets should be delivered via net80211_rx(), and * completed transmissions should be indicated using * net80211_tx_complete(). * * This method is guaranteed to be called only when the device * is open. */ void ( * poll ) ( struct net80211_device *dev ); /** Enable or disable interrupts * * @v dev 802.11 device * @v enable If TRUE, interrupts should be enabled */ void ( * irq ) ( struct net80211_device *dev, int enable ); /** Update hardware state to match 802.11 layer state * * @v dev 802.11 device * @v changed Set of flags indicating what may have changed * @ret rc Return status code * * This method should cause the hardware state to be * reinitialized from the state indicated in fields of * net80211_device, in the areas indicated by bits set in * @a changed. If the hardware is unable to do so, this method * may return an appropriate error indication. * * This method is guaranteed to be called only when the device * is open. */ int ( * config ) ( struct net80211_device *dev, int changed ); }; /** An 802.11 RF channel. */ struct net80211_channel { /** The band with which this channel is associated */ u8 band; /** A channel number interpreted according to the band * * The 2.4GHz band uses channel numbers from 1-13 at 5MHz * intervals such that channel 1 is 2407 MHz; channel 14, * legal for use only in Japan, is defined separately as 2484 * MHz. Adjacent channels will overlap, since 802.11 * transmissions use a 20 MHz (4-channel) bandwidth. Most * commonly, channels 1, 6, and 11 are used. * * The 5GHz band uses channel numbers derived directly from * the frequency; channel 0 is 5000 MHz, and channels are * always spaced 5 MHz apart. Channel numbers over 180 are * relative to 4GHz instead of 5GHz, but these are rarely * seen. Most channels are not legal for use. */ u8 channel_nr; /** The center frequency for this channel * * Currently a bandwidth of 20 MHz is assumed. */ u16 center_freq; /** Hardware channel value */ u16 hw_value; /** Maximum allowable transmit power, in dBm * * This should be interpreted as EIRP, the power supplied to * an ideal isotropic antenna in order to achieve the same * average signal intensity as the real hardware at a * particular distance. * * Currently no provision is made for directional antennas. */ u8 maxpower; }; /** Information on the capabilities of an 802.11 hardware device * * In its probe callback, an 802.11 driver must read hardware * registers to determine the appropriate contents of this structure, * fill it, and pass it to net80211_register() so that the 802.11 * layer knows how to treat the hardware and what to advertise as * supported to access points. */ struct net80211_hw_info { /** Default hardware MAC address. * * The user may change this by setting the @c netX/mac setting * before the driver's open function is called; in that case * the driver must set the hardware MAC address to the address * contained in the wrapping net_device's ll_addr field, or if * that is impossible, set that ll_addr field back to the * unchangeable hardware MAC address. */ u8 hwaddr[ETH_ALEN]; /** A bitwise OR of the 802.11x modes supported by this device */ int modes; /** A bitwise OR of the bands on which this device can communicate */ int bands; /** A set of flags indicating peculiarities of this device. */ enum { /** Received frames include a frame check sequence. */ NET80211_HW_RX_HAS_FCS = (1 << 1), /** Hardware doesn't support 2.4GHz short preambles * * This is only relevant for 802.11b operation above * 2Mbps. All 802.11g devices support short preambles. */ NET80211_HW_NO_SHORT_PREAMBLE = (1 << 2), /** Hardware doesn't support 802.11g short slot operation */ NET80211_HW_NO_SHORT_SLOT = (1 << 3), } flags; /** Signal strength information that can be provided by the device * * Signal strength is passed to net80211_rx(), primarily to * allow determination of the closest access point for a * multi-AP network. The units are provided for completeness * of status displays. */ enum { /** No signal strength information supported */ NET80211_SIGNAL_NONE = 0, /** Signal strength in arbitrary units */ NET80211_SIGNAL_ARBITRARY, /** Signal strength in decibels relative to arbitrary base */ NET80211_SIGNAL_DB, /** Signal strength in decibels relative to 1mW */ NET80211_SIGNAL_DBM, } signal_type; /** Maximum signal in arbitrary cases * * If signal_type is NET80211_SIGNAL_ARBITRARY or * NET80211_SIGNAL_DB, the driver should report it on a scale * from 0 to signal_max. */ unsigned signal_max; /** List of RF channels supported by the card */ struct net80211_channel channels[NET80211_MAX_CHANNELS]; /** Number of supported channels */ int nr_channels; /** List of transmission rates supported by the card, indexed by band * * Rates should be in 100kbps increments (e.g. 11 Mbps would * be represented as the number 110). */ u16 rates[NET80211_NR_BANDS][NET80211_MAX_RATES]; /** Number of supported rates, indexed by band */ int nr_rates[NET80211_NR_BANDS]; /** Estimate of the time required to change channels, in microseconds * * If this is not known, a guess on the order of a few * milliseconds (value of 1000-5000) is reasonable. */ unsigned channel_change_time; }; /** Structure tracking received fragments for a packet * * We set up a fragment cache entry when we receive a packet marked as * fragment 0 with the "more fragments" bit set in its frame control * header. We are required by the 802.11 standard to track 3 * fragmented packets arriving simultaneously; if we receive more we * may drop some. Upon receipt of a new fragment-0 packet, if no entry * is available or expired, we take over the most @e recent entry for * the new packet, since we don't want to starve old entries from ever * finishing at all. If we get a fragment after the zeroth with no * cache entry for its packet, we drop it. */ struct net80211_frag_cache { /** Whether this cache entry is in use */ u8 in_use; /** Sequence number of this MSDU (packet) */ u16 seqnr; /** Timestamp from point at which first fragment was collected */ u32 start_ticks; /** Buffers for each fragment */ struct io_buffer *iob[16]; }; /** Interface to an 802.11 cryptographic algorithm * * Cryptographic algorithms define a net80211_crypto structure * statically, using a gPXE linker table to make it available to the * 802.11 layer. When the algorithm needs to be used, the 802.11 code * will allocate a copy of the static definition plus whatever space * the algorithm has requested for private state, and point * net80211_device::crypto at it. */ struct net80211_crypto { /** The cryptographic algorithm implemented */ enum net80211_crypto_alg algorithm; /** Initialize cryptographic algorithm using a given key * * @v crypto 802.11 cryptographic algorithm * @v key Pointer to key bytes * @v keylen Number of key bytes * @ret rc Return status code * * This method is passed the communication key provided by the * security handshake handler, which will already be in the * low-level form required. */ int ( * initialize ) ( struct net80211_crypto *crypto, u8 *key, int keylen ); /** Encrypt a frame using the cryptographic algorithm * * @v crypto 802.11 cryptographic algorithm * @v iob I/O buffer * @ret eiob Newly allocated I/O buffer with encrypted packet * * This method is called to encrypt a single frame. It is * guaranteed that initialize() will have completed * successfully before this method is called. * * The frame passed already has an 802.11 header prepended, * but the PROTECTED bit in the frame control field will not * be set; this method is responsible for setting it. The * returned I/O buffer should contain a complete copy of @a * iob, including the 802.11 header, but with the PROTECTED * bit set, the data encrypted, and whatever encryption * headers/trailers are necessary added. * * This method should never free the passed I/O buffer. * * Return NULL if the packet could not be encrypted, due to * memory limitations or otherwise. */ struct io_buffer * ( * encrypt ) ( struct net80211_crypto *crypto, struct io_buffer *iob ); /** Decrypt a frame using the cryptographic algorithm * * @v crypto 802.11 cryptographic algorithm * @v eiob Encrypted I/O buffer * @ret iob Newly allocated I/O buffer with decrypted packet * * This method is called to decrypt a single frame. It is * guaranteed that initialize() will have completed * successfully before this method is called. * * Decryption follows the reverse of the pattern used for * encryption: this method must copy the 802.11 header into * the returned packet, decrypt the data stream, remove any * encryption header or trailer, and clear the PROTECTED bit * in the frame control header. * * This method should never free the passed I/O buffer. * * Return NULL if memory was not available for decryption, if * a consistency or integrity check on the decrypted frame * failed, or if the decrypted frame should not be processed * by the network stack for any other reason. */ struct io_buffer * ( * decrypt ) ( struct net80211_crypto *crypto, struct io_buffer *iob ); /** Length of private data requested to be allocated */ int priv_len; /** Private data for the algorithm to store key and state info */ void *priv; }; struct net80211_probe_ctx; struct net80211_assoc_ctx; /** Structure encapsulating the complete state of an 802.11 device * * An 802.11 device is always wrapped by a network device, and this * network device is always pointed to by the @a netdev field. In * general, operations should never be performed by 802.11 code using * netdev functions directly. It is usually the case that the 802.11 * layer might need to do some processing or bookkeeping on top of * what the netdevice code will do. */ struct net80211_device { /** The net_device that wraps us. */ struct net_device *netdev; /** List of 802.11 devices. */ struct list_head list; /** 802.11 device operations */ struct net80211_device_operations *op; /** Driver private data */ void *priv; /** Information about the hardware, provided to net80211_register() */ struct net80211_hw_info *hw; /* ---------- Channel and rate fields ---------- */ /** A list of all possible channels we might use */ struct net80211_channel channels[NET80211_MAX_CHANNELS]; /** The number of channels in the channels array */ u8 nr_channels; /** The channel currently in use, as an index into the channels array */ u8 channel; /** A list of all possible TX rates we might use * * Rates are in units of 100 kbps. */ u16 rates[NET80211_MAX_RATES]; /** The number of transmission rates in the rates array */ u8 nr_rates; /** The rate currently in use, as an index into the rates array */ u8 rate; /** The rate to use for RTS/CTS transmissions * * This is always the fastest basic rate that is not faster * than the data rate in use. Also an index into the rates array. */ u8 rtscts_rate; /** Bitmask of basic rates * * If bit N is set in this value, with the LSB considered to * be bit 0, then rate N in the rates array is a "basic" rate. * * We don't decide which rates are "basic"; our AP does, and * we respect its wishes. We need to be able to identify basic * rates in order to calculate the duration of a CTS packet * used for 802.11 g/b interoperability. */ u32 basic_rates; /* ---------- Association fields ---------- */ /** The asynchronous association process. * * When an 802.11 netdev is opened, or when the user changes * the SSID setting on an open 802.11 device, an * autoassociation task is started by net80211_autoassocate() * to associate with the new best network. The association is * asynchronous, but no packets can be transmitted until it is * complete. If it is successful, the wrapping net_device is * set as "link up". If it fails, @c assoc_rc will be set with * an error indication. */ struct process proc_assoc; /** Network with which we are associating * * This will be NULL when we are not actively in the process * of associating with a network we have already successfully * probed for. */ struct net80211_wlan *associating; /** Context for the association process * * This is a probe_ctx if the @c PROBED flag is not set in @c * state, and an assoc_ctx otherwise. */ union { struct net80211_probe_ctx *probe; struct net80211_assoc_ctx *assoc; } ctx; /** State of our association to the network * * Since the association process happens asynchronously, it's * necessary to have some channel of communication so the * driver can say "I got an association reply and we're OK" or * similar. This variable provides that link. It is a bitmask * of any of NET80211_PROBED, NET80211_AUTHENTICATED, * NET80211_ASSOCIATED, NET80211_CRYPTO_SYNCED to indicate how * far along in associating we are; NET80211_WORKING if the * association task is running; and NET80211_WAITING if a * packet has been sent that we're waiting for a reply to. We * can only be crypto-synced if we're associated, we can * only be associated if we're authenticated, we can only be * authenticated if we've probed. * * If an association process fails (that is, we receive a * packet with an error indication), the error code is copied * into bits 6-0 of this variable and bit 7 is set to specify * what type of error code it is. An AP can provide either a * "status code" (0-51 are defined) explaining why it refused * an association immediately, or a "reason code" (0-45 are * defined) explaining why it canceled an association after it * had originally OK'ed it. Status and reason codes serve * similar functions, but they use separate error message * tables. A gPXE-formatted return status code (negative) is * placed in @c assoc_rc. * * If the failure to associate is indicated by a status code, * the NET80211_IS_REASON bit will be clear; if it is * indicated by a reason code, the bit will be set. If we were * successful, both zero status and zero reason mean success, * so there is no ambiguity. * * To prevent association when opening the device, user code * can set the NET80211_NO_ASSOC bit. The final bit in this * variable, NET80211_AUTO_SSID, is used to remember whether * we picked our SSID through automated probing as opposed to * user specification; the distinction becomes relevant in the * settings applicator. */ u16 state; /** Return status code associated with @c state */ int assoc_rc; /* ---------- Parameters of currently associated network ---------- */ /** 802.11 cryptographic algorithm for our current network * * For an open network, this will be set to NULL. */ struct net80211_crypto *crypto; /** MAC address of the access point most recently associated */ u8 bssid[ETH_ALEN]; /** SSID of the access point we are or will be associated with * * Although the SSID field in 802.11 packets is generally not * NUL-terminated, here and in net80211_wlan we add a NUL for * convenience. */ char essid[IEEE80211_MAX_SSID_LEN+1]; /** Association ID given to us by the AP */ u16 aid; /** TSFT value for last beacon received, microseconds */ u64 last_beacon_timestamp; /** Time between AP sending beacons, microseconds */ u32 tx_beacon_interval; /** Smoothed average time between beacons, microseconds */ u32 rx_beacon_interval; /* ---------- Physical layer information ---------- */ /** Physical layer options * * These control the use of CTS protection, short preambles, * and short-slot operation. */ int phy_flags; /** Signal strength of last received packet */ int last_signal; /** Rate control state */ struct rc80211_ctx *rctl; /* ---------- Packet handling state ---------- */ /** Fragment reassembly state */ struct net80211_frag_cache frags[NET80211_NR_CONCURRENT_FRAGS]; /** The sequence number of the last packet we sent */ u16 last_tx_seqnr; /** Packet duplication elimination state * * We are only required to handle immediate duplicates for * each direct sender, and since we can only have one direct * sender (the AP), we need only keep the sequence control * field from the most recent packet we've received. Thus, * this field stores the last sequence control field we've * received for a packet from the AP. */ u16 last_rx_seq; /** RX management packet queue * * Sometimes we want to keep probe, beacon, and action packets * that we receive, such as when we're scanning for networks. * Ordinarily we drop them because they are sent at a large * volume (ten beacons per second per AP, broadcast) and we * have no need of them except when we're scanning. * * When keep_mgmt is TRUE, received probe, beacon, and action * management packets will be stored in this queue. */ struct list_head mgmt_queue; /** RX management packet info queue * * We need to keep track of the signal strength for management * packets we're keeping, because that provides the only way * to distinguish between multiple APs for the same network. * Since we can't extend io_buffer to store signal, this field * heads a linked list of "RX packet info" structures that * contain that signal strength field. Its entries always * parallel the entries in mgmt_queue, because the two queues * are always added to or removed from in parallel. */ struct list_head mgmt_info_queue; /** Whether to store management packets * * Received beacon, probe, and action packets will be added to * mgmt_queue (and their signal strengths added to * mgmt_info_queue) only when this variable is TRUE. It should * be set by net80211_keep_mgmt() (which returns the old * value) only when calling code is prepared to poll the * management queue frequently, because packets will otherwise * pile up and exhaust memory. */ int keep_mgmt; }; /** Structure representing a probed network. * * This is returned from the net80211_probe_finish functions and * passed to the low-level association functions. At least essid, * bssid, channel, beacon, and security must be filled in if you want * to build this structure manually. */ struct net80211_wlan { /** The human-readable ESSID (network name) * * Although the 802.11 SSID field is generally not * NUL-terminated, the gPXE code adds an extra NUL (and * expects one in this structure) for convenience. */ char essid[IEEE80211_MAX_SSID_LEN+1]; /** MAC address of the strongest-signal access point for this ESSID */ u8 bssid[ETH_ALEN]; /** Signal strength of beacon frame from that access point */ int signal; /** The channel on which that access point communicates * * This is a raw channel number (net80211_channel::channel_nr), * so that it will not be affected by reconfiguration of the * device channels array. */ int channel; /** The complete beacon or probe-response frame received */ struct io_buffer *beacon; /** Security handshaking method used on the network */ enum net80211_security_proto handshaking; /** Cryptographic algorithm used on the network */ enum net80211_crypto_alg crypto; /** Link to allow chaining multiple structures into a list to be returned from net80211_probe_finish_all(). */ struct list_head list; }; /** * @defgroup net80211_probe 802.11 network location API * @{ */ int net80211_prepare_probe ( struct net80211_device *dev, int band, int active ); struct net80211_probe_ctx * net80211_probe_start ( struct net80211_device *dev, const char *essid, int active ); int net80211_probe_step ( struct net80211_probe_ctx *ctx ); struct net80211_wlan * net80211_probe_finish_best ( struct net80211_probe_ctx *ctx ); struct list_head *net80211_probe_finish_all ( struct net80211_probe_ctx *ctx ); void net80211_free_wlan ( struct net80211_wlan *wlan ); void net80211_free_wlanlist ( struct list_head *list ); /** @} */ /** * @defgroup net80211_mgmt 802.11 network management API * @{ */ struct net80211_device * net80211_get ( struct net_device *netdev ); void net80211_autoassociate ( struct net80211_device *dev ); int net80211_change_channel ( struct net80211_device *dev, int channel ); void net80211_set_rate_idx ( struct net80211_device *dev, int rate ); int net80211_keep_mgmt ( struct net80211_device *dev, int enable ); struct io_buffer * net80211_mgmt_dequeue ( struct net80211_device *dev, int *signal ); int net80211_tx_mgmt ( struct net80211_device *dev, u16 fc, u8 bssid[ETH_ALEN], struct io_buffer *iob ); /** @} */ /** * @defgroup net80211_assoc 802.11 network association API * @{ */ int net80211_prepare_assoc ( struct net80211_device *dev, struct net80211_wlan *wlan ); int net80211_send_auth ( struct net80211_device *dev, struct net80211_wlan *wlan, int method ); int net80211_send_assoc ( struct net80211_device *dev, struct net80211_wlan *wlan ); /** @} */ /** * @defgroup net80211_driver 802.11 driver interface API * @{ */ struct net80211_device *net80211_alloc ( size_t priv_size ); int net80211_register ( struct net80211_device *dev, struct net80211_device_operations *ops, struct net80211_hw_info *hw ); u16 net80211_duration ( struct net80211_device *dev, int bytes, u16 rate ); void net80211_rx ( struct net80211_device *dev, struct io_buffer *iob, int signal, u16 rate ); void net80211_rx_err ( struct net80211_device *dev, struct io_buffer *iob, int rc ); void net80211_tx_complete ( struct net80211_device *dev, struct io_buffer *iob, int retries, int rc ); void net80211_unregister ( struct net80211_device *dev ); void net80211_free ( struct net80211_device *dev ); /** @} */ /** * Calculate duration field for a CTS control frame * * @v dev 802.11 device * @v size Size of the packet being cleared to send * * A CTS control frame's duration field captures the frame being * protected and its 10-byte ACK. */ static inline u16 net80211_cts_duration ( struct net80211_device *dev, int size ) { return ( net80211_duration ( dev, 10, dev->rates[dev->rtscts_rate] ) + net80211_duration ( dev, size, dev->rates[dev->rate] ) ); } #endif debian/grub-extras/disabled/gpxe/src/include/gpxe/tcp.h0000664000000000000000000002172012524662415020272 0ustar #ifndef _GPXE_TCP_H #define _GPXE_TCP_H /** @file * * TCP protocol * * This file defines the gPXE TCP API. * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** * A TCP header */ struct tcp_header { uint16_t src; /* Source port */ uint16_t dest; /* Destination port */ uint32_t seq; /* Sequence number */ uint32_t ack; /* Acknowledgement number */ uint8_t hlen; /* Header length (4), Reserved (4) */ uint8_t flags; /* Reserved (2), Flags (6) */ uint16_t win; /* Advertised window */ uint16_t csum; /* Checksum */ uint16_t urg; /* Urgent pointer */ }; /** @defgroup tcpopts TCP options * @{ */ /** End of TCP options list */ #define TCP_OPTION_END 0 /** TCP option pad */ #define TCP_OPTION_NOP 1 /** Generic TCP option */ struct tcp_option { uint8_t kind; uint8_t length; } __attribute__ (( packed )); /** TCP MSS option */ struct tcp_mss_option { uint8_t kind; uint8_t length; uint16_t mss; } __attribute__ (( packed )); /** Code for the TCP MSS option */ #define TCP_OPTION_MSS 2 /** TCP timestamp option */ struct tcp_timestamp_option { uint8_t kind; uint8_t length; uint32_t tsval; uint32_t tsecr; } __attribute__ (( packed )); /** Padded TCP timestamp option (used for sending) */ struct tcp_timestamp_padded_option { uint8_t nop[2]; struct tcp_timestamp_option tsopt; } __attribute__ (( packed )); /** Code for the TCP timestamp option */ #define TCP_OPTION_TS 8 /** Parsed TCP options */ struct tcp_options { /** MSS option, if present */ const struct tcp_mss_option *mssopt; /** Timestampe option, if present */ const struct tcp_timestamp_option *tsopt; }; /** @} */ /* * TCP flags */ #define TCP_CWR 0x80 #define TCP_ECE 0x40 #define TCP_URG 0x20 #define TCP_ACK 0x10 #define TCP_PSH 0x08 #define TCP_RST 0x04 #define TCP_SYN 0x02 #define TCP_FIN 0x01 /** * @defgroup tcpstates TCP states * * The TCP state is defined by a combination of the flags that have * been sent to the peer, the flags that have been acknowledged by the * peer, and the flags that have been received from the peer. * * @{ */ /** TCP flags that have been sent in outgoing packets */ #define TCP_STATE_SENT(flags) ( (flags) << 0 ) #define TCP_FLAGS_SENT(state) ( ( (state) >> 0 ) & 0xff ) /** TCP flags that have been acknowledged by the peer * * Note that this applies only to SYN and FIN. */ #define TCP_STATE_ACKED(flags) ( (flags) << 8 ) #define TCP_FLAGS_ACKED(state) ( ( (state) >> 8 ) & 0xff ) /** TCP flags that have been received from the peer * * Note that this applies only to SYN and FIN, and that once SYN has * been received, we should always be sending ACK. */ #define TCP_STATE_RCVD(flags) ( (flags) << 16 ) #define TCP_FLAGS_RCVD(state) ( ( (state) >> 16 ) & 0xff ) /** TCP flags that are currently being sent in outgoing packets */ #define TCP_FLAGS_SENDING(state) \ ( TCP_FLAGS_SENT ( state ) & ~TCP_FLAGS_ACKED ( state ) ) /** CLOSED * * The connection has not yet been used for anything. */ #define TCP_CLOSED TCP_RST /** LISTEN * * Not currently used as a state; we have no support for listening * connections. Given a unique value to avoid compiler warnings. */ #define TCP_LISTEN 0 /** SYN_SENT * * SYN has been sent, nothing has yet been received or acknowledged. */ #define TCP_SYN_SENT ( TCP_STATE_SENT ( TCP_SYN ) ) /** SYN_RCVD * * SYN has been sent but not acknowledged, SYN has been received. */ #define TCP_SYN_RCVD ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK ) | \ TCP_STATE_RCVD ( TCP_SYN ) ) /** ESTABLISHED * * SYN has been sent and acknowledged, SYN has been received. */ #define TCP_ESTABLISHED ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK ) | \ TCP_STATE_ACKED ( TCP_SYN ) | \ TCP_STATE_RCVD ( TCP_SYN ) ) /** FIN_WAIT_1 * * SYN has been sent and acknowledged, SYN has been received, FIN has * been sent but not acknowledged, FIN has not been received. * * RFC 793 shows that we can enter FIN_WAIT_1 without have had SYN * acknowledged, i.e. if the application closes the connection after * sending and receiving SYN, but before having had SYN acknowledged. * However, we have to *pretend* that SYN has been acknowledged * anyway, otherwise we end up sending SYN and FIN in the same * sequence number slot. Therefore, when we transition from SYN_RCVD * to FIN_WAIT_1, we have to remember to set TCP_STATE_ACKED(TCP_SYN) * and increment our sequence number. */ #define TCP_FIN_WAIT_1 ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) | \ TCP_STATE_ACKED ( TCP_SYN ) | \ TCP_STATE_RCVD ( TCP_SYN ) ) /** FIN_WAIT_2 * * SYN has been sent and acknowledged, SYN has been received, FIN has * been sent and acknowledged, FIN ha not been received. */ #define TCP_FIN_WAIT_2 ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) | \ TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) | \ TCP_STATE_RCVD ( TCP_SYN ) ) /** CLOSING / LAST_ACK * * SYN has been sent and acknowledged, SYN has been received, FIN has * been sent but not acknowledged, FIN has been received. * * This state actually encompasses both CLOSING and LAST_ACK; they are * identical with the definition of state that we use. I don't * *believe* that they need to be distinguished. */ #define TCP_CLOSING_OR_LAST_ACK \ ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) | \ TCP_STATE_ACKED ( TCP_SYN ) | \ TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) ) /** TIME_WAIT * * SYN has been sent and acknowledged, SYN has been received, FIN has * been sent and acknowledged, FIN has been received. */ #define TCP_TIME_WAIT ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) | \ TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) | \ TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) ) /** CLOSE_WAIT * * SYN has been sent and acknowledged, SYN has been received, FIN has * been received. */ #define TCP_CLOSE_WAIT ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK ) | \ TCP_STATE_ACKED ( TCP_SYN ) | \ TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) ) /** Can send data in current state * * We can send data if and only if we have had our SYN acked and we * have not yet sent our FIN. */ #define TCP_CAN_SEND_DATA(state) \ ( ( (state) & ( TCP_STATE_ACKED ( TCP_SYN ) | \ TCP_STATE_SENT ( TCP_FIN ) ) ) \ == TCP_STATE_ACKED ( TCP_SYN ) ) /** Have ever been fully established * * We have been fully established if we have both received a SYN and * had our own SYN acked. */ #define TCP_HAS_BEEN_ESTABLISHED(state) \ ( ( (state) & ( TCP_STATE_ACKED ( TCP_SYN ) | \ TCP_STATE_RCVD ( TCP_SYN ) ) ) \ == ( TCP_STATE_ACKED ( TCP_SYN ) | TCP_STATE_RCVD ( TCP_SYN ) ) ) /** Have closed gracefully * * We have closed gracefully if we have both received a FIN and had * our own FIN acked. */ #define TCP_CLOSED_GRACEFULLY(state) \ ( ( (state) & ( TCP_STATE_ACKED ( TCP_FIN ) | \ TCP_STATE_RCVD ( TCP_FIN ) ) ) \ == ( TCP_STATE_ACKED ( TCP_FIN ) | TCP_STATE_RCVD ( TCP_FIN ) ) ) /** @} */ /** Mask for TCP header length field */ #define TCP_MASK_HLEN 0xf0 /** Smallest port number on which a TCP connection can listen */ #define TCP_MIN_PORT 1 /* Some IOB constants */ #define MAX_HDR_LEN 100 #define MAX_IOB_LEN 1500 #define MIN_IOB_LEN MAX_HDR_LEN + 100 /* To account for padding by LL */ /** * Maxmimum advertised TCP window size * * We estimate the TCP window size as the amount of free memory we * have. This is not strictly accurate (since it ignores any space * already allocated as RX buffers), but it will do for now. * * Since we don't store out-of-order received packets, the * retransmission penalty is that the whole window contents must be * resent. This suggests keeping the window size small, but bear in * mind that the maximum bandwidth on any link is limited to * * max_bandwidth = ( tcp_window / round_trip_time ) * * With a 48kB window, which probably accurately reflects our amount * of free memory, and a WAN RTT of say 200ms, this gives a maximum * bandwidth of 240kB/s. This is sufficiently close to realistic that * we will need to be careful that our advertised window doesn't end * up limiting WAN download speeds. * * Finally, since the window goes into a 16-bit field and we cannot * actually use 65536, we use a window size of (65536-4) to ensure * that payloads remain dword-aligned. */ //#define TCP_MAX_WINDOW_SIZE ( 65536 - 4 ) #define TCP_MAX_WINDOW_SIZE 4096 /** * Path MTU * * We really ought to implement Path MTU discovery. Until we do, * anything with a path MTU greater than this may fail. */ #define TCP_PATH_MTU 1460 /** * Advertised TCP MSS * * We currently hardcode this to a reasonable value and hope that the * sender uses path MTU discovery. The alternative is breaking the * abstraction layer so that we can find out the MTU from the IP layer * (which would have to find out from the net device layer). */ #define TCP_MSS 1460 /** TCP maximum segment lifetime * * Currently set to 2 minutes, as per RFC 793. */ #define TCP_MSL ( 2 * 60 * TICKS_PER_SEC ) extern struct tcpip_protocol tcp_protocol; #endif /* _GPXE_TCP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ata.h0000664000000000000000000001157012524662415020253 0ustar #ifndef _GPXE_ATA_H #define _GPXE_ATA_H #include #include #include #include /** @file * * ATA devices * */ FILE_LICENCE ( GPL2_OR_LATER ); /** * An ATA Logical Block Address * * ATA controllers have three byte-wide registers for specifying the * block address: LBA Low, LBA Mid and LBA High. This allows for a * 24-bit address. Some devices support the "48-bit address feature * set" (LBA48), in which case each of these byte-wide registers is * actually a two-entry FIFO, and the "previous" byte pushed into the * FIFO is used as the corresponding high-order byte. So, to set up * the 48-bit address 0x123456abcdef, you would issue * * 0x56 -> LBA Low register * 0xef -> LBA Low register * 0x34 -> LBA Mid register * 0xcd -> LBA Mid register * 0x12 -> LBA High register * 0xab -> LBA High register * * This structure encapsulates this information by providing a single * 64-bit integer in native byte order, unioned with bytes named so * that the sequence becomes * * low_prev -> LBA Low register * low_cur -> LBA Low register * mid_prev -> LBA Mid register * mid_cur -> LBA Mid register * high_prev -> LBA High register * high_cur -> LBA High register * * Just to complicate matters further, in non-LBA48 mode it is * possible to have a 28-bit address, in which case bits 27:24 must be * written into the low four bits of the Device register. */ union ata_lba { /** LBA as a 64-bit integer in native-endian order */ uint64_t native; /** ATA registers */ struct { #if __BYTE_ORDER == __LITTLE_ENDIAN uint8_t low_cur; uint8_t mid_cur; uint8_t high_cur; uint8_t low_prev; uint8_t mid_prev; uint8_t high_prev; uint16_t pad; #elif __BYTE_ORDER == __BIG_ENDIAN uint16_t pad; uint8_t high_prev; uint8_t mid_prev; uint8_t low_prev; uint8_t high_cur; uint8_t mid_cur; uint8_t low_cur; #else #error "I need a byte order" #endif } bytes; }; /** An ATA 2-byte FIFO register */ union ata_fifo { /** Value in native-endian order */ uint16_t native; /** ATA registers */ struct { #if __BYTE_ORDER == __LITTLE_ENDIAN uint8_t cur; uint8_t prev; #elif __BYTE_ORDER == __BIG_ENDIAN uint8_t prev; uint8_t cur; #else #error "I need a byte order" #endif } bytes; }; /** ATA command block */ struct ata_cb { /** Logical block address */ union ata_lba lba; /** Sector count */ union ata_fifo count; /** Error/feature register */ union ata_fifo err_feat; /** Device register */ uint8_t device; /** Command/status register */ uint8_t cmd_stat; /** LBA48 addressing flag */ int lba48; }; /** Obsolete bits in the ATA device register */ #define ATA_DEV_OBSOLETE 0xa0 /** LBA flag in the ATA device register */ #define ATA_DEV_LBA 0x40 /** Slave ("device 1") flag in the ATA device register */ #define ATA_DEV_SLAVE 0x10 /** Master ("device 0") flag in the ATA device register */ #define ATA_DEV_MASTER 0x00 /** Mask of non-LBA portion of device register */ #define ATA_DEV_MASK 0xf0 /** "Read sectors" command */ #define ATA_CMD_READ 0x20 /** "Read sectors (ext)" command */ #define ATA_CMD_READ_EXT 0x24 /** "Write sectors" command */ #define ATA_CMD_WRITE 0x30 /** "Write sectors (ext)" command */ #define ATA_CMD_WRITE_EXT 0x34 /** "Identify" command */ #define ATA_CMD_IDENTIFY 0xec /** An ATA command */ struct ata_command { /** ATA command block */ struct ata_cb cb; /** Data-out buffer (may be NULL) * * If non-NULL, this buffer must be ata_command::cb::count * sectors in size. */ userptr_t data_out; /** Data-in buffer (may be NULL) * * If non-NULL, this buffer must be ata_command::cb::count * sectors in size. */ userptr_t data_in; /** Command status code */ int rc; }; /** * Structure returned by ATA IDENTIFY command * * This is a huge structure with many fields that we don't care about, * so we implement only a few fields. */ struct ata_identity { uint16_t ignore_a[60]; /* words 0-59 */ uint32_t lba_sectors; /* words 60-61 */ uint16_t ignore_b[21]; /* words 62-82 */ uint16_t supports_lba48; /* word 83 */ uint16_t ignore_c[16]; /* words 84-99 */ uint64_t lba48_sectors; /* words 100-103 */ uint16_t ignore_d[152]; /* words 104-255 */ }; /** Supports LBA48 flag */ #define ATA_SUPPORTS_LBA48 ( 1 << 10 ) /** ATA sector size */ #define ATA_SECTOR_SIZE 512 /** An ATA device */ struct ata_device { /** Block device interface */ struct block_device blockdev; /** Device number * * Must be ATA_DEV_MASTER or ATA_DEV_SLAVE. */ int device; /** LBA48 extended addressing */ int lba48; /** * Issue ATA command * * @v ata ATA device * @v command ATA command * @ret rc Return status code */ int ( * command ) ( struct ata_device *ata, struct ata_command *command ); /** Backing device */ struct refcnt *backend; }; extern int init_atadev ( struct ata_device *ata ); #endif /* _GPXE_ATA_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/rsa.h0000664000000000000000000000031612524662415020267 0ustar #ifndef _GPXE_RSA_H #define _GPXE_RSA_H FILE_LICENCE ( GPL2_OR_LATER ); struct pubkey_algorithm; extern struct pubkey_algorithm rsa_algorithm; #include "crypto/axtls/crypto.h" #endif /* _GPXE_RSA_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/keys.h0000664000000000000000000000364012524662415020460 0ustar #ifndef _GPXE_KEYS_H #define _GPXE_KEYS_H /** @file * * Key definitions * */ FILE_LICENCE ( GPL2_OR_LATER ); /* * Symbolic names for some standard ASCII characters * */ #define NUL 0x00 #define CTRL_A 0x01 #define CTRL_B 0x02 #define CTRL_C 0x03 #define CTRL_D 0x04 #define CTRL_E 0x05 #define CTRL_F 0x06 #define CTRL_G 0x07 #define CTRL_H 0x08 #define CTRL_I 0x09 #define CTRL_J 0x0a #define CTRL_K 0x0b #define CTRL_L 0x0c #define CTRL_M 0x0d #define CTRL_N 0x0e #define CTRL_O 0x0f #define CTRL_P 0x10 #define CTRL_Q 0x11 #define CTRL_R 0x12 #define CTRL_S 0x13 #define CTRL_T 0x14 #define CTRL_U 0x15 #define CTRL_V 0x16 #define CTRL_W 0x17 #define CTRL_X 0x18 #define CTRL_Y 0x19 #define CTRL_Z 0x1a #define BACKSPACE CTRL_H #define TAB CTRL_I #define LF CTRL_J #define CR CTRL_M #define ESC 0x1b /* * Special keys outside the normal ASCII range * * * The names are chosen to match those used by curses. The values are * chosen to facilitate easy conversion from a received ANSI escape * sequence to a KEY_XXX constant. */ #define KEY_ANSI( n, terminator ) ( 0x100 * ( (n) + 1 ) + (terminator) ) #define KEY_MIN 0x101 #define KEY_UP KEY_ANSI ( 0, 'A' ) /**< Up arrow */ #define KEY_DOWN KEY_ANSI ( 0, 'B' ) /**< Down arrow */ #define KEY_RIGHT KEY_ANSI ( 0, 'C' ) /**< Right arrow */ #define KEY_LEFT KEY_ANSI ( 0, 'D' ) /**< Left arrow */ #define KEY_END KEY_ANSI ( 0, 'F' ) /**< End */ #define KEY_HOME KEY_ANSI ( 0, 'H' ) /**< Home */ #define KEY_IC KEY_ANSI ( 2, '~' ) /**< Insert */ #define KEY_DC KEY_ANSI ( 3, '~' ) /**< Delete */ #define KEY_PPAGE KEY_ANSI ( 5, '~' ) /**< Page up */ #define KEY_NPAGE KEY_ANSI ( 6, '~' ) /**< Page down */ #define KEY_F8 KEY_ANSI ( 19, '~' ) /**< F8 (for PXE) */ /* Not in the [KEY_MIN,KEY_MAX] range; terminals seem to send these as * normal ASCII values. */ #define KEY_BACKSPACE BACKSPACE #define KEY_ENTER LF #endif /* _GPXE_KEYS_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/in.h0000664000000000000000000000477112524662415020121 0ustar #ifndef _GPXE_IN_H #define _GPXE_IN_H FILE_LICENCE ( GPL2_OR_LATER ); #include #include /* Protocol numbers */ #define IP_ICMP 1 #define IP_IGMP 2 #define IP_TCP 6 #define IP_UDP 17 #define IP_ICMP6 58 /* IP address constants */ #define INADDR_NONE 0xffffffff #define INADDR_BROADCAST 0xffffffff #define IN_CLASSA(addr) ( ( (addr) & 0x80000000 ) == 0x00000000 ) #define IN_CLASSA_NET 0xff000000 #define IN_CLASSB(addr) ( ( (addr) & 0xc0000000 ) == 0x80000000 ) #define IN_CLASSB_NET 0xffff0000 #define IN_CLASSC(addr) ( ( (addr) & 0xe0000000 ) == 0xc0000000 ) #define IN_CLASSC_NET 0xffffff00 #define IN_MULTICAST(addr) ( ( (addr) & 0xf0000000 ) == 0xe0000000 ) /** * IP address structure */ struct in_addr { uint32_t s_addr; }; typedef struct in_addr in_addr; /** * IP6 address structure */ struct in6_addr { union { uint8_t u6_addr8[16]; uint16_t u6_addr16[8]; uint32_t u6_addr32[4]; } in6_u; #define s6_addr in6_u.u6_addr8 #define s6_addr16 in6_u.u6_addr16 #define s6_addr32 in6_u.u6_addr32 }; /** * IPv4 socket address */ struct sockaddr_in { /** Socket address family (part of struct @c sockaddr) * * Always set to @c AF_INET for IPv4 addresses */ sa_family_t sin_family; /** TCP/IP port (part of struct @c sockaddr_tcpip) */ uint16_t sin_port; /** IPv4 address */ struct in_addr sin_addr; /** Padding * * This ensures that a struct @c sockaddr_tcpip is large * enough to hold a socket address for any TCP/IP address * family. */ char pad[ sizeof ( struct sockaddr ) - sizeof ( sa_family_t ) - sizeof ( uint16_t ) - sizeof ( struct in_addr ) ]; } __attribute__ (( may_alias )); /** * IPv6 socket address */ struct sockaddr_in6 { /** Socket address family (part of struct @c sockaddr) * * Always set to @c AF_INET6 for IPv6 addresses */ sa_family_t sin_family; /** TCP/IP port (part of struct @c sockaddr_tcpip) */ uint16_t sin_port; uint32_t sin6_flowinfo; /* Flow number */ struct in6_addr sin6_addr; /* 128-bit destination address */ uint32_t sin6_scope_id; /* Scope ID */ } __attribute__ (( may_alias )); extern int inet_aton ( const char *cp, struct in_addr *inp ); extern char * inet_ntoa ( struct in_addr in ); /* Adding the following for IP6 support * extern int inet6_aton ( const char *cp, struct in6_addr *inp ); extern char * inet6_ntoa ( struct in_addr in ); */ #endif /* _GPXE_IN_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/icmp.h0000664000000000000000000000055312524662415020435 0ustar #ifndef _GPXE_ICMP_H #define _GPXE_ICMP_H /** @file * * ICMP protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); /** An ICMP header */ struct icmp_header { /** Type */ uint8_t type; /** Code */ uint8_t code; /** Checksum */ uint16_t chksum; } __attribute__ (( packed )); #define ICMP_ECHO_RESPONSE 0 #define ICMP_ECHO_REQUEST 8 #endif /* _GPXE_ICMP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/dhcp.h0000664000000000000000000004053612524662415020430 0ustar #ifndef _GPXE_DHCP_H #define _GPXE_DHCP_H /** @file * * Dynamic Host Configuration Protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include struct job_interface; struct dhcp_options; struct dhcp_packet; /** BOOTP/DHCP server port */ #define BOOTPS_PORT 67 /** BOOTP/DHCP client port */ #define BOOTPC_PORT 68 /** PXE server port */ #define PXE_PORT 4011 /** Construct a tag value for an encapsulated option * * This tag value can be passed to Etherboot functions when searching * for DHCP options in order to search for a tag within an * encapsulated options block. */ #define DHCP_ENCAP_OPT( encapsulator, encapsulated ) \ ( ( (encapsulator) << 8 ) | (encapsulated) ) /** Extract encapsulating option block tag from encapsulated tag value */ #define DHCP_ENCAPSULATOR( encap_opt ) ( (encap_opt) >> 8 ) /** Extract encapsulated option tag from encapsulated tag value */ #define DHCP_ENCAPSULATED( encap_opt ) ( (encap_opt) & 0xff ) /** Option is encapsulated */ #define DHCP_IS_ENCAP_OPT( opt ) DHCP_ENCAPSULATOR( opt ) /** * @defgroup dhcpopts DHCP option tags * @{ */ /** Padding * * This tag does not have a length field; it is always only a single * byte in length. */ #define DHCP_PAD 0 /** Minimum normal DHCP option */ #define DHCP_MIN_OPTION 1 /** Subnet mask */ #define DHCP_SUBNET_MASK 1 /** Routers */ #define DHCP_ROUTERS 3 /** DNS servers */ #define DHCP_DNS_SERVERS 6 /** Syslog servers */ #define DHCP_LOG_SERVERS 7 /** Host name */ #define DHCP_HOST_NAME 12 /** Domain name */ #define DHCP_DOMAIN_NAME 15 /** Root path */ #define DHCP_ROOT_PATH 17 /** Vendor encapsulated options */ #define DHCP_VENDOR_ENCAP 43 /** PXE boot server discovery control */ #define DHCP_PXE_DISCOVERY_CONTROL DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 6 ) /** PXE boot server discovery control bits */ enum dhcp_pxe_discovery_control { /** Inhibit broadcast discovery */ PXEBS_NO_BROADCAST = 1, /** Inhibit multicast discovery */ PXEBS_NO_MULTICAST = 2, /** Accept only servers in DHCP_PXE_BOOT_SERVERS list */ PXEBS_NO_UNKNOWN_SERVERS = 4, /** Skip discovery if filename present */ PXEBS_SKIP = 8, }; /** PXE boot server multicast address */ #define DHCP_PXE_BOOT_SERVER_MCAST DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 7 ) /** PXE boot servers */ #define DHCP_PXE_BOOT_SERVERS DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 8 ) /** PXE boot server */ struct dhcp_pxe_boot_server { /** "Type" */ uint16_t type; /** Number of IPv4 addresses */ uint8_t num_ip; /** IPv4 addresses */ struct in_addr ip[0]; } __attribute__ (( packed )); /** PXE boot menu */ #define DHCP_PXE_BOOT_MENU DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 9 ) /** PXE boot menu */ struct dhcp_pxe_boot_menu { /** "Type" */ uint16_t type; /** Description length */ uint8_t desc_len; /** Description */ char desc[0]; } __attribute__ (( packed )); /** PXE boot menu prompt */ #define DHCP_PXE_BOOT_MENU_PROMPT DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 10 ) /** PXE boot menu prompt */ struct dhcp_pxe_boot_menu_prompt { /** Timeout * * A value of 0 means "time out immediately and select first * boot item, without displaying the prompt". A value of 255 * means "display menu immediately with no timeout". Any * other value means "display prompt, wait this many seconds * for keypress, if key is F8, display menu, otherwise select * first boot item". */ uint8_t timeout; /** Prompt to press F8 */ char prompt[0]; } __attribute__ (( packed )); /** PXE boot menu item */ #define DHCP_PXE_BOOT_MENU_ITEM DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 71 ) /** PXE boot menu item */ struct dhcp_pxe_boot_menu_item { /** "Type" * * This field actually identifies the specific boot server (or * cluster of boot servers offering identical boot files). */ uint16_t type; /** "Layer" * * Just don't ask. */ uint16_t layer; } __attribute__ (( packed )); /** Requested IP address */ #define DHCP_REQUESTED_ADDRESS 50 /** Lease time */ #define DHCP_LEASE_TIME 51 /** Option overloading * * The value of this option is the bitwise-OR of zero or more * DHCP_OPTION_OVERLOAD_XXX constants. */ #define DHCP_OPTION_OVERLOAD 52 /** The "file" field is overloaded to contain extra DHCP options */ #define DHCP_OPTION_OVERLOAD_FILE 1 /** The "sname" field is overloaded to contain extra DHCP options */ #define DHCP_OPTION_OVERLOAD_SNAME 2 /** DHCP message type */ #define DHCP_MESSAGE_TYPE 53 #define DHCPNONE 0 #define DHCPDISCOVER 1 #define DHCPOFFER 2 #define DHCPREQUEST 3 #define DHCPDECLINE 4 #define DHCPACK 5 #define DHCPNAK 6 #define DHCPRELEASE 7 #define DHCPINFORM 8 /** DHCP server identifier */ #define DHCP_SERVER_IDENTIFIER 54 /** Parameter request list */ #define DHCP_PARAMETER_REQUEST_LIST 55 /** Maximum DHCP message size */ #define DHCP_MAX_MESSAGE_SIZE 57 /** Vendor class identifier */ #define DHCP_VENDOR_CLASS_ID 60 /** Client identifier */ #define DHCP_CLIENT_ID 61 /** Client identifier */ struct dhcp_client_id { /** Link-layer protocol */ uint8_t ll_proto; /** Link-layer address */ uint8_t ll_addr[MAX_LL_ADDR_LEN]; } __attribute__ (( packed )); /** TFTP server name * * This option replaces the fixed "sname" field, when that field is * used to contain overloaded options. */ #define DHCP_TFTP_SERVER_NAME 66 /** Bootfile name * * This option replaces the fixed "file" field, when that field is * used to contain overloaded options. */ #define DHCP_BOOTFILE_NAME 67 /** User class identifier */ #define DHCP_USER_CLASS_ID 77 /** Client system architecture */ #define DHCP_CLIENT_ARCHITECTURE 93 /** Client network device interface */ #define DHCP_CLIENT_NDI 94 /** UUID client identifier */ #define DHCP_CLIENT_UUID 97 /** UUID client identifier */ struct dhcp_client_uuid { /** Identifier type */ uint8_t type; /** UUID */ union uuid uuid; } __attribute__ (( packed )); #define DHCP_CLIENT_UUID_TYPE 0 /** Etherboot-specific encapsulated options * * This encapsulated options field is used to contain all options * specific to Etherboot (i.e. not assigned by IANA or other standards * bodies). */ #define DHCP_EB_ENCAP 175 /** Priority of this options block * * This is a signed 8-bit integer field indicating the priority of * this block of options. It can be used to specify the relative * priority of multiple option blocks (e.g. options from non-volatile * storage versus options from a DHCP server). */ #define DHCP_EB_PRIORITY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x01 ) /** "Your" IP address * * This option is used internally to contain the value of the "yiaddr" * field, in order to provide a consistent approach to storing and * processing options. It should never be present in a DHCP packet. */ #define DHCP_EB_YIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x02 ) /** "Server" IP address * * This option is used internally to contain the value of the "siaddr" * field, in order to provide a consistent approach to storing and * processing options. It should never be present in a DHCP packet. */ #define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x03 ) /** Keep SAN drive registered * * If set to a non-zero value, gPXE will not detach any SAN drive * after failing to boot from it. (This option is required in order * to perform a Windows Server 2008 installation direct to an iSCSI * target.) */ #define DHCP_EB_KEEP_SAN DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x08 ) /* * Tags in the range 0x10-0x7f are reserved for feature markers * */ /** Skip PXE DHCP protocol extensions such as ProxyDHCP * * If set to a non-zero value, gPXE will not wait for ProxyDHCP offers * and will ignore any PXE-specific DHCP options that it receives. */ #define DHCP_EB_NO_PXEDHCP DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb0 ) /** Network device descriptor * * Byte 0 is the bus type ID; remaining bytes depend on the bus type. * * PCI devices: * Byte 0 : 1 (PCI) * Byte 1 : PCI vendor ID MSB * Byte 2 : PCI vendor ID LSB * Byte 3 : PCI device ID MSB * Byte 4 : PCI device ID LSB */ #define DHCP_EB_BUS_ID DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb1 ) /** Network device descriptor */ struct dhcp_netdev_desc { /** Bus type ID */ uint8_t type; /** Vendor ID */ uint16_t vendor; /** Device ID */ uint16_t device; } __attribute__ (( packed )); /** BIOS drive number * * This is the drive number for a drive emulated via INT 13. 0x80 is * the first hard disk, 0x81 is the second hard disk, etc. */ #define DHCP_EB_BIOS_DRIVE DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbd ) /** Username * * This will be used as the username for any required authentication. * It is expected that this option's value will be held in * non-volatile storage, rather than transmitted as part of a DHCP * packet. */ #define DHCP_EB_USERNAME DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbe ) /** Password * * This will be used as the password for any required authentication. * It is expected that this option's value will be held in * non-volatile storage, rather than transmitted as part of a DHCP * packet. */ #define DHCP_EB_PASSWORD DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbf ) /** Reverse username * * This will be used as the reverse username (i.e. the username * provided by the server) for any required authentication. It is * expected that this option's value will be held in non-volatile * storage, rather than transmitted as part of a DHCP packet. */ #define DHCP_EB_REVERSE_USERNAME DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc0 ) /** Reverse password * * This will be used as the reverse password (i.e. the password * provided by the server) for any required authentication. It is * expected that this option's value will be held in non-volatile * storage, rather than transmitted as part of a DHCP packet. */ #define DHCP_EB_REVERSE_PASSWORD DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc1 ) /** gPXE version number */ #define DHCP_EB_VERSION DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xeb ) /** iSCSI primary target IQN */ #define DHCP_ISCSI_PRIMARY_TARGET_IQN 201 /** iSCSI secondary target IQN */ #define DHCP_ISCSI_SECONDARY_TARGET_IQN 202 /** iSCSI initiator IQN */ #define DHCP_ISCSI_INITIATOR_IQN 203 /** Maximum normal DHCP option */ #define DHCP_MAX_OPTION 254 /** End of options * * This tag does not have a length field; it is always only a single * byte in length. */ #define DHCP_END 255 /** @} */ /** * Count number of arguments to a variadic macro * * This rather neat, non-iterative solution is courtesy of Laurent * Deniau. * */ #define _VA_ARG_COUNT( _1, _2, _3, _4, _5, _6, _7, _8, \ _9, _10, _11, _12, _13, _14, _15, _16, \ _17, _18, _19, _20, _21, _22, _23, _24, \ _25, _26, _27, _28, _29, _30, _31, _32, \ _33, _34, _35, _36, _37, _38, _39, _40, \ _41, _42, _43, _44, _45, _46, _47, _48, \ _49, _50, _51, _52, _53, _54, _55, _56, \ _57, _58, _59, _60, _61, _62, _63, N, ... ) N #define VA_ARG_COUNT( ... ) \ _VA_ARG_COUNT ( __VA_ARGS__, \ 63, 62, 61, 60, 59, 58, 57, 56, \ 55, 54, 53, 52, 51, 50, 49, 48, \ 47, 46, 45, 44, 43, 42, 41, 40, \ 39, 38, 37, 36, 35, 34, 33, 32, \ 31, 30, 29, 28, 27, 26, 25, 24, \ 23, 22, 21, 20, 19, 18, 17, 16, \ 15, 14, 13, 12, 11, 10, 9, 8, \ 7, 6, 5, 4, 3, 2, 1, 0 ) /** Construct a DHCP option from a list of bytes */ #define DHCP_OPTION( ... ) VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__ /** Construct a DHCP option from a list of characters */ #define DHCP_STRING( ... ) DHCP_OPTION ( __VA_ARGS__ ) /** Construct a byte-valued DHCP option */ #define DHCP_BYTE( value ) DHCP_OPTION ( value ) /** Construct a word-valued DHCP option */ #define DHCP_WORD( value ) DHCP_OPTION ( ( ( (value) >> 8 ) & 0xff ), \ ( ( (value) >> 0 ) & 0xff ) ) /** Construct a dword-valued DHCP option */ #define DHCP_DWORD( value ) DHCP_OPTION ( ( ( (value) >> 24 ) & 0xff ), \ ( ( (value) >> 16 ) & 0xff ), \ ( ( (value) >> 8 ) & 0xff ), \ ( ( (value) >> 0 ) & 0xff ) ) /** Construct a DHCP encapsulated options field */ #define DHCP_ENCAP( ... ) DHCP_OPTION ( __VA_ARGS__, DHCP_END ) /** * A DHCP option * * DHCP options consist of a mandatory tag, a length field that is * mandatory for all options except @c DHCP_PAD and @c DHCP_END, and a * payload. */ struct dhcp_option { /** Tag * * Must be a @c DHCP_XXX value. */ uint8_t tag; /** Length * * This is the length of the data field (i.e. excluding the * tag and length fields). For the two tags @c DHCP_PAD and * @c DHCP_END, the length field is implicitly zero and is * also missing, i.e. these DHCP options are only a single * byte in length. */ uint8_t len; /** Option data */ uint8_t data[0]; } __attribute__ (( packed )); /** * Length of a DHCP option header * * The header is the portion excluding the data, i.e. the tag and the * length. */ #define DHCP_OPTION_HEADER_LEN ( offsetof ( struct dhcp_option, data ) ) /** Maximum length for a single DHCP option */ #define DHCP_MAX_LEN 0xff /** * A DHCP header * */ struct dhcphdr { /** Operation * * This must be either @c BOOTP_REQUEST or @c BOOTP_REPLY. */ uint8_t op; /** Hardware address type * * This is an ARPHRD_XXX constant. Note that ARPHRD_XXX * constants are nominally 16 bits wide; this could be * considered to be a bug in the BOOTP/DHCP specification. */ uint8_t htype; /** Hardware address length */ uint8_t hlen; /** Number of hops from server */ uint8_t hops; /** Transaction ID */ uint32_t xid; /** Seconds since start of acquisition */ uint16_t secs; /** Flags */ uint16_t flags; /** "Client" IP address * * This is filled in if the client already has an IP address * assigned and can respond to ARP requests. */ struct in_addr ciaddr; /** "Your" IP address * * This is the IP address assigned by the server to the client. */ struct in_addr yiaddr; /** "Server" IP address * * This is the IP address of the next server to be used in the * boot process. */ struct in_addr siaddr; /** "Gateway" IP address * * This is the IP address of the DHCP relay agent, if any. */ struct in_addr giaddr; /** Client hardware address */ uint8_t chaddr[16]; /** Server host name (null terminated) * * This field may be overridden and contain DHCP options */ char sname[64]; /** Boot file name (null terminated) * * This field may be overridden and contain DHCP options */ char file[128]; /** DHCP magic cookie * * Must have the value @c DHCP_MAGIC_COOKIE. */ uint32_t magic; /** DHCP options * * Variable length; extends to the end of the packet. Minimum * length (for the sake of sanity) is 1, to allow for a single * @c DHCP_END tag. */ uint8_t options[0]; }; /** Opcode for a request from client to server */ #define BOOTP_REQUEST 1 /** Opcode for a reply from server to client */ #define BOOTP_REPLY 2 /** BOOTP reply must be broadcast * * Clients that cannot accept unicast BOOTP replies must set this * flag. */ #define BOOTP_FL_BROADCAST 0x8000 /** DHCP magic cookie */ #define DHCP_MAGIC_COOKIE 0x63825363UL /** DHCP minimum packet length * * This is the mandated minimum packet length that a DHCP participant * must be prepared to receive. */ #define DHCP_MIN_LEN 552 /** Timeouts for sending DHCP packets */ #define DHCP_MIN_TIMEOUT ( 1 * TICKS_PER_SEC ) #define DHCP_MAX_TIMEOUT ( 10 * TICKS_PER_SEC ) /** Maximum time that we will wait for ProxyDHCP responses */ #define PROXYDHCP_MAX_TIMEOUT ( 2 * TICKS_PER_SEC ) /** Maximum time that we will wait for Boot Server responses */ #define PXEBS_MAX_TIMEOUT ( 3 * TICKS_PER_SEC ) /** Settings block name used for DHCP responses */ #define DHCP_SETTINGS_NAME "dhcp" /** Settings block name used for ProxyDHCP responses */ #define PROXYDHCP_SETTINGS_NAME "proxydhcp" /** Setting block name used for BootServerDHCP responses */ #define PXEBS_SETTINGS_NAME "pxebs" extern void * dhcp_chaddr ( struct net_device *netdev, uint8_t *hlen, uint16_t *flags ); extern int dhcp_create_packet ( struct dhcp_packet *dhcppkt, struct net_device *netdev, uint8_t msgtype, const void *options, size_t options_len, void *data, size_t max_len ); extern int dhcp_create_request ( struct dhcp_packet *dhcppkt, struct net_device *netdev, unsigned int msgtype, struct in_addr ciaddr, void *data, size_t max_len ); extern int start_dhcp ( struct job_interface *job, struct net_device *netdev ); extern int start_pxebs ( struct job_interface *job, struct net_device *netdev, unsigned int pxe_type ); #endif /* _GPXE_DHCP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/editbox.h0000664000000000000000000000261512524662415021144 0ustar #ifndef _GPXE_EDITBOX_H #define _GPXE_EDITBOX_H /** @file * * Editable text box widget * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** An editable text box widget */ struct edit_box { /** Editable string */ struct edit_string string; /** Containing window */ WINDOW *win; /** Row */ unsigned int row; /** Starting column */ unsigned int col; /** Width */ unsigned int width; /** First displayed character */ unsigned int first; /** Flags */ unsigned int flags; }; /** Editable text box widget flags */ enum edit_box_flags { /** Show stars instead of contents (for password widgets) */ EDITBOX_STARS = 0x0001, }; extern void init_editbox ( struct edit_box *box, char *buf, size_t len, WINDOW *win, unsigned int row, unsigned int col, unsigned int width, unsigned int flags ) __attribute__ (( nonnull (1, 2) )); extern void draw_editbox ( struct edit_box *box ) __nonnull; static inline int edit_editbox ( struct edit_box *box, int key ) __nonnull; /** * Edit text box widget * * @v box Editable text box widget * @v key Key pressed by user * @ret key Key returned to application, or zero * * You must call draw_editbox() to update the display after calling * edit_editbox(). * */ static inline int edit_editbox ( struct edit_box *box, int key ) { return edit_string ( &box->string, key ); } #endif /* _GPXE_EDITBOX_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ib_mcast.h0000664000000000000000000000240212524662415021261 0ustar #ifndef _GPXE_IB_MCAST_H #define _GPXE_IB_MCAST_H /** @file * * Infiniband multicast groups * */ FILE_LICENCE ( GPL2_OR_LATER ); #include struct ib_mad_transaction; /** An Infiniband multicast group membership */ struct ib_mc_membership { /** Queue pair */ struct ib_queue_pair *qp; /** Multicast GID */ struct ib_gid gid; /** Multicast group join transaction */ struct ib_mad_transaction *madx; /** Handle join success/failure * * @v ibdev Infiniband device * @v qp Queue pair * @v membership Multicast group membership * @v rc Status code * @v mad Response MAD (or NULL on error) */ void ( * complete ) ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_mc_membership *membership, int rc, union ib_mad *mad ); }; extern int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_mc_membership *membership, struct ib_gid *gid, void ( * joined ) ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_mc_membership *memb, int rc, union ib_mad *mad ) ); extern void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_mc_membership *membership ); #endif /* _GPXE_IB_MCAST_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/hmac.h0000664000000000000000000000134412524662415020414 0ustar #ifndef _GPXE_HMAC_H #define _GPXE_HMAC_H /** @file * * Keyed-Hashing for Message Authentication */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** * Update HMAC * * @v digest Digest algorithm to use * @v digest_ctx Digest context * @v data Data * @v len Length of data */ static inline void hmac_update ( struct digest_algorithm *digest, void *digest_ctx, const void *data, size_t len ) { digest_update ( digest, digest_ctx, data, len ); } extern void hmac_init ( struct digest_algorithm *digest, void *digest_ctx, void *key, size_t *key_len ); extern void hmac_final ( struct digest_algorithm *digest, void *digest_ctx, void *key, size_t *key_len, void *hmac ); #endif /* _GPXE_HMAC_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/downloader.h0000664000000000000000000000055512524662415021645 0ustar #ifndef _GPXE_DOWNLOADER_H #define _GPXE_DOWNLOADER_H /** @file * * Image downloader * */ FILE_LICENCE ( GPL2_OR_LATER ); struct job_interface; struct image; extern int create_downloader ( struct job_interface *job, struct image *image, int ( * register_image ) ( struct image *image ), int type, ... ); #endif /* _GPXE_DOWNLOADER_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/fakedhcp.h0000664000000000000000000000075112524662415021252 0ustar #ifndef _GPXE_FAKEDHCP_H #define _GPXE_FAKEDHCP_H /** @file * * Fake DHCP packets * */ FILE_LICENCE ( GPL2_OR_LATER ); #include struct net_device; extern int create_fakedhcpdiscover ( struct net_device *netdev, void *data, size_t max_len ); extern int create_fakedhcpack ( struct net_device *netdev, void *data, size_t max_len ); extern int create_fakepxebsack ( struct net_device *netdev, void *data, size_t max_len ); #endif /* _GPXE_FAKEDHCP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ramdisk.h0000664000000000000000000000057412524662415021142 0ustar #ifndef _GPXE_RAMDISK_H #define _GPXE_RAMDISK_H /** * @file * * RAM disks * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include struct ramdisk { struct block_device blockdev; userptr_t data; }; extern int init_ramdisk ( struct ramdisk *ramdisk, userptr_t data, size_t len, unsigned int blksize ); #endif /* _GPXE_RAMDISK_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/iscsi.h0000664000000000000000000004176412524662415020630 0ustar #ifndef _GPXE_ISCSI_H #define _GPXE_ISCSI_H /** @file * * iSCSI protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include /** Default iSCSI port */ #define ISCSI_PORT 3260 /** * iSCSI segment lengths * * iSCSI uses an icky structure with one one-byte field (a dword * count) and one three-byte field (a byte count). This structure, * and the accompanying macros, relieve some of the pain. */ union iscsi_segment_lengths { struct { /** The AHS length (measured in dwords) */ uint8_t ahs_len; /** The data length (measured in bytes), in network * byte order */ uint8_t data_len[3]; } bytes; /** Ths data length (measured in bytes), in network byte * order, with ahs_len as the first byte. */ uint32_t ahs_and_data_len; }; /** The length of the additional header segment, in dwords */ #define ISCSI_AHS_LEN( segment_lengths ) \ ( (segment_lengths).bytes.ahs_len ) /** The length of the data segment, in bytes, excluding any padding */ #define ISCSI_DATA_LEN( segment_lengths ) \ ( ntohl ( (segment_lengths).ahs_and_data_len ) & 0xffffff ) /** The padding of the data segment, in bytes */ #define ISCSI_DATA_PAD_LEN( segment_lengths ) \ ( ( 0 - (segment_lengths).bytes.data_len[2] ) & 0x03 ) /** Set additional header and data segment lengths */ #define ISCSI_SET_LENGTHS( segment_lengths, ahs_len, data_len ) do { \ (segment_lengths).ahs_and_data_len = \ htonl ( data_len | ( ahs_len << 24 ) ); \ } while ( 0 ) /** * iSCSI basic header segment common fields * */ struct iscsi_bhs_common { /** Opcode */ uint8_t opcode; /** Flags */ uint8_t flags; /** Fields specific to the PDU type */ uint8_t other_a[2]; /** Segment lengths */ union iscsi_segment_lengths lengths; /** Fields specific to the PDU type */ uint8_t other_b[8]; /** Initiator Task Tag */ uint32_t itt; /** Fields specific to the PDU type */ uint8_t other_c[28]; }; /** Opcode mask */ #define ISCSI_OPCODE_MASK 0x3f /** Immediate delivery */ #define ISCSI_FLAG_IMMEDIATE 0x40 /** Final PDU of a sequence */ #define ISCSI_FLAG_FINAL 0x80 /** * iSCSI basic header segment common request fields * */ struct iscsi_bhs_common_response { /** Opcode */ uint8_t opcode; /** Flags */ uint8_t flags; /** Fields specific to the PDU type */ uint8_t other_a[2]; /** Segment lengths */ union iscsi_segment_lengths lengths; /** Fields specific to the PDU type */ uint8_t other_b[8]; /** Initiator Task Tag */ uint32_t itt; /** Fields specific to the PDU type */ uint8_t other_c[4]; /** Status sequence number */ uint32_t statsn; /** Expected command sequence number */ uint32_t expcmdsn; /** Fields specific to the PDU type */ uint8_t other_d[16]; }; /** * iSCSI login request basic header segment * */ struct iscsi_bhs_login_request { /** Opcode */ uint8_t opcode; /** Flags */ uint8_t flags; /** Maximum supported version number */ uint8_t version_max; /** Minimum supported version number */ uint8_t version_min; /** Segment lengths */ union iscsi_segment_lengths lengths; /** Initiator session ID (IANA format) enterprise number and flags */ uint32_t isid_iana_en; /** Initiator session ID (IANA format) qualifier */ uint16_t isid_iana_qual; /** Target session identifying handle */ uint16_t tsih; /** Initiator Task Tag */ uint32_t itt; /** Connection ID */ uint16_t cid; /** Reserved */ uint16_t reserved_a; /** Command sequence number */ uint32_t cmdsn; /** Expected status sequence number */ uint32_t expstatsn; /** Reserved */ uint8_t reserved_b[16]; }; /** Login request opcode */ #define ISCSI_OPCODE_LOGIN_REQUEST 0x03 /** Willingness to transition to next stage */ #define ISCSI_LOGIN_FLAG_TRANSITION 0x80 /** Key=value pairs continued in subsequent request */ #define ISCSI_LOGIN_FLAG_CONTINUE 0x40 /* Current stage values and mask */ #define ISCSI_LOGIN_CSG_MASK 0x0c #define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION 0x00 #define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION 0x04 #define ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE 0x0c /* Next stage values and mask */ #define ISCSI_LOGIN_NSG_MASK 0x03 #define ISCSI_LOGIN_NSG_SECURITY_NEGOTIATION 0x00 #define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION 0x01 #define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE 0x03 /** ISID IANA format marker */ #define ISCSI_ISID_IANA 0x40000000 /** Fen Systems Ltd. IANA enterprise number * * Permission is hereby granted to use Fen Systems Ltd.'s IANA * enterprise number with this iSCSI implementation. */ #define IANA_EN_FEN_SYSTEMS 10019 /** * iSCSI login response basic header segment * */ struct iscsi_bhs_login_response { /** Opcode */ uint8_t opcode; /** Flags */ uint8_t flags; /** Maximum supported version number */ uint8_t version_max; /** Minimum supported version number */ uint8_t version_min; /** Segment lengths */ union iscsi_segment_lengths lengths; /** Initiator session ID (IANA format) enterprise number and flags */ uint32_t isid_iana_en; /** Initiator session ID (IANA format) qualifier */ uint16_t isid_iana_qual; /** Target session identifying handle */ uint16_t tsih; /** Initiator Task Tag */ uint32_t itt; /** Reserved */ uint32_t reserved_a; /** Status sequence number */ uint32_t statsn; /** Expected command sequence number */ uint32_t expcmdsn; /** Maximum command sequence number */ uint32_t maxcmdsn; /** Status class */ uint8_t status_class; /** Status detail */ uint8_t status_detail; /** Reserved */ uint8_t reserved_b[10]; }; /** Login response opcode */ #define ISCSI_OPCODE_LOGIN_RESPONSE 0x23 /* Login response status codes */ #define ISCSI_STATUS_SUCCESS 0x00 #define ISCSI_STATUS_REDIRECT 0x01 #define ISCSI_STATUS_INITIATOR_ERROR 0x02 #define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION 0x01 #define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION 0x02 #define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND 0x03 #define ISCSI_STATUS_INITIATOR_ERROR_REMOVED 0x04 #define ISCSI_STATUS_TARGET_ERROR 0x03 /** * iSCSI SCSI command basic header segment * */ struct iscsi_bhs_scsi_command { /** Opcode */ uint8_t opcode; /** Flags */ uint8_t flags; /** Reserved */ uint16_t reserved_a; /** Segment lengths */ union iscsi_segment_lengths lengths; /** SCSI Logical Unit Number */ struct scsi_lun lun; /** Initiator Task Tag */ uint32_t itt; /** Expected data transfer length */ uint32_t exp_len; /** Command sequence number */ uint32_t cmdsn; /** Expected status sequence number */ uint32_t expstatsn; /** SCSI Command Descriptor Block (CDB) */ union scsi_cdb cdb; }; /** SCSI command opcode */ #define ISCSI_OPCODE_SCSI_COMMAND 0x01 /** Command will read data */ #define ISCSI_COMMAND_FLAG_READ 0x40 /** Command will write data */ #define ISCSI_COMMAND_FLAG_WRITE 0x20 /* Task attributes */ #define ISCSI_COMMAND_ATTR_UNTAGGED 0x00 #define ISCSI_COMMAND_ATTR_SIMPLE 0x01 #define ISCSI_COMMAND_ATTR_ORDERED 0x02 #define ISCSI_COMMAND_ATTR_HEAD_OF_QUEUE 0x03 #define ISCSI_COMMAND_ATTR_ACA 0x04 /** * iSCSI SCSI response basic header segment * */ struct iscsi_bhs_scsi_response { /** Opcode */ uint8_t opcode; /** Flags */ uint8_t flags; /** Response code */ uint8_t response; /** SCSI status code */ uint8_t status; /** Segment lengths */ union iscsi_segment_lengths lengths; /** Reserved */ uint8_t reserved_a[8]; /** Initiator Task Tag */ uint32_t itt; /** SNACK tag */ uint32_t snack; /** Status sequence number */ uint32_t statsn; /** Expected command sequence number */ uint32_t expcmdsn; /** Maximum command sequence number */ uint32_t maxcmdsn; /** Expected data sequence number */ uint32_t expdatasn; /** Reserved */ uint8_t reserved_b[8]; }; /** SCSI response opcode */ #define ISCSI_OPCODE_SCSI_RESPONSE 0x21 /** SCSI command completed at target */ #define ISCSI_RESPONSE_COMMAND_COMPLETE 0x00 /** SCSI target failure */ #define ISCSI_RESPONSE_TARGET_FAILURE 0x01 /** SCSI sense response code offset * * The SCSI response may contain unsolicited sense data in the data * segment. If it does, this is the offset to the sense response code * byte, which is the only byte we care about. */ #define ISCSI_SENSE_RESPONSE_CODE_OFFSET 2 /** * iSCSI data-in basic header segment * */ struct iscsi_bhs_data_in { /** Opcode */ uint8_t opcode; /** Flags */ uint8_t flags; /** Reserved */ uint8_t reserved_a; /** SCSI status code */ uint8_t status; /** Segment lengths */ union iscsi_segment_lengths lengths; /** Logical Unit Number */ struct scsi_lun lun; /** Initiator Task Tag */ uint32_t itt; /** Target Transfer Tag */ uint32_t ttt; /** Status sequence number */ uint32_t statsn; /** Expected command sequence number */ uint32_t expcmdsn; /** Maximum command sequence number */ uint32_t maxcmdsn; /** Data sequence number */ uint32_t datasn; /** Buffer offset */ uint32_t offset; /** Residual count */ uint32_t residual_count; }; /** Data-in opcode */ #define ISCSI_OPCODE_DATA_IN 0x25 /** Data requires acknowledgement */ #define ISCSI_DATA_FLAG_ACKNOWLEDGE 0x40 /** Data overflow occurred */ #define ISCSI_DATA_FLAG_OVERFLOW 0x04 /** Data underflow occurred */ #define ISCSI_DATA_FLAG_UNDERFLOW 0x02 /** SCSI status code and overflow/underflow flags are valid */ #define ISCSI_DATA_FLAG_STATUS 0x01 /** * iSCSI data-out basic header segment * */ struct iscsi_bhs_data_out { /** Opcode */ uint8_t opcode; /** Flags */ uint8_t flags; /** Reserved */ uint16_t reserved_a; /** Segment lengths */ union iscsi_segment_lengths lengths; /** Logical Unit Number */ struct scsi_lun lun; /** Initiator Task Tag */ uint32_t itt; /** Target Transfer Tag */ uint32_t ttt; /** Reserved */ uint32_t reserved_b; /** Expected status sequence number */ uint32_t expstatsn; /** Reserved */ uint32_t reserved_c; /** Data sequence number */ uint32_t datasn; /** Buffer offset */ uint32_t offset; /** Reserved */ uint32_t reserved_d; }; /** Data-out opcode */ #define ISCSI_OPCODE_DATA_OUT 0x05 /** * iSCSI request to transfer basic header segment * */ struct iscsi_bhs_r2t { /** Opcode */ uint8_t opcode; /** Flags */ uint8_t flags; /** Reserved */ uint16_t reserved_a; /** Segment lengths */ union iscsi_segment_lengths lengths; /** Logical Unit Number */ struct scsi_lun lun; /** Initiator Task Tag */ uint32_t itt; /** Target Transfer Tag */ uint32_t ttt; /** Status sequence number */ uint32_t statsn; /** Expected command sequence number */ uint32_t expcmdsn; /** Maximum command sequence number */ uint32_t maxcmdsn; /** R2T sequence number */ uint32_t r2tsn; /** Buffer offset */ uint32_t offset; /** Desired data transfer length */ uint32_t len; }; /** R2T opcode */ #define ISCSI_OPCODE_R2T 0x31 /** * An iSCSI basic header segment */ union iscsi_bhs { struct iscsi_bhs_common common; struct iscsi_bhs_common_response common_response; struct iscsi_bhs_login_request login_request; struct iscsi_bhs_login_response login_response; struct iscsi_bhs_scsi_command scsi_command; struct iscsi_bhs_scsi_response scsi_response; struct iscsi_bhs_data_in data_in; struct iscsi_bhs_data_out data_out; struct iscsi_bhs_r2t r2t; unsigned char bytes[ sizeof ( struct iscsi_bhs_common ) ]; }; /** State of an iSCSI TX engine */ enum iscsi_tx_state { /** Nothing to send */ ISCSI_TX_IDLE = 0, /** Sending the basic header segment */ ISCSI_TX_BHS, /** Sending the additional header segment */ ISCSI_TX_AHS, /** Sending the data segment */ ISCSI_TX_DATA, /** Sending the data segment padding */ ISCSI_TX_DATA_PADDING, }; /** State of an iSCSI RX engine */ enum iscsi_rx_state { /** Receiving the basic header segment */ ISCSI_RX_BHS = 0, /** Receiving the additional header segment */ ISCSI_RX_AHS, /** Receiving the data segment */ ISCSI_RX_DATA, /** Receiving the data segment padding */ ISCSI_RX_DATA_PADDING, }; /** An iSCSI session */ struct iscsi_session { /** Reference counter */ struct refcnt refcnt; /** Transport-layer socket */ struct xfer_interface socket; /** Target address */ char *target_address; /** Target port */ unsigned int target_port; /** Target IQN */ char *target_iqn; /** Logical Unit Number (LUN) */ struct scsi_lun lun; /** Target socket address (recorded only for iBFT) */ struct sockaddr target_sockaddr; /** Session status * * This is the bitwise-OR of zero or more ISCSI_STATUS_XXX * constants. */ int status; /** Retry count * * Number of times that the connection has been retried. * Reset upon a successful connection. */ int retry_count; /** Initiator username (if any) */ char *initiator_username; /** Initiator password (if any) */ char *initiator_password; /** Target username (if any) */ char *target_username; /** Target password (if any) */ char *target_password; /** CHAP challenge (for target auth only) * * This is a block of random data; the first byte is used as * the CHAP identifier (CHAP_I) and the remainder as the CHAP * challenge (CHAP_C). */ unsigned char chap_challenge[17]; /** CHAP response (used for both initiator and target auth) */ struct chap_response chap; /** Target session identifying handle * * This is assigned by the target when we first log in, and * must be reused on subsequent login attempts. */ uint16_t tsih; /** Initiator task tag * * This is the tag of the current command. It is incremented * whenever a new command is started. */ uint32_t itt; /** Target transfer tag * * This is the tag attached to a sequence of data-out PDUs in * response to an R2T. */ uint32_t ttt; /** * Transfer offset * * This is the offset for an in-progress sequence of data-out * PDUs in response to an R2T. */ uint32_t transfer_offset; /** * Transfer length * * This is the length for an in-progress sequence of data-out * PDUs in response to an R2T. */ uint32_t transfer_len; /** Command sequence number * * This is the sequence number of the current command, used to * fill out the CmdSN field in iSCSI request PDUs. It is * updated with the value of the ExpCmdSN field whenever we * receive an iSCSI response PDU containing such a field. */ uint32_t cmdsn; /** Status sequence number * * This is the most recent status sequence number present in * the StatSN field of an iSCSI response PDU containing such a * field. Whenever we send an iSCSI request PDU, we fill out * the ExpStatSN field with this value plus one. */ uint32_t statsn; /** Basic header segment for current TX PDU */ union iscsi_bhs tx_bhs; /** State of the TX engine */ enum iscsi_tx_state tx_state; /** TX process */ struct process process; /** Basic header segment for current RX PDU */ union iscsi_bhs rx_bhs; /** State of the RX engine */ enum iscsi_rx_state rx_state; /** Byte offset within the current RX state */ size_t rx_offset; /** Length of the current RX state */ size_t rx_len; /** Buffer for received data (not always used) */ void *rx_buffer; /** Current SCSI command * * Set to NULL when command is complete. */ struct scsi_command *command; /** Instant return code * * Set to a non-zero value if all requests should return * immediately. This can be used to e.g. avoid retrying * logins that are doomed to fail authentication. */ int instant_rc; }; /** iSCSI session is currently in the security negotiation phase */ #define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE \ ( ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION | \ ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION ) /** iSCSI session is currently in the operational parameter * negotiation phase */ #define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE \ ( ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION | \ ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE ) /** iSCSI session is currently in the full feature phase */ #define ISCSI_STATUS_FULL_FEATURE_PHASE ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE /** Mask for all iSCSI session phases */ #define ISCSI_STATUS_PHASE_MASK ( ISCSI_LOGIN_CSG_MASK | ISCSI_LOGIN_NSG_MASK ) /** iSCSI session needs to send the initial security negotiation strings */ #define ISCSI_STATUS_STRINGS_SECURITY 0x0100 /** iSCSI session needs to send the CHAP_A string */ #define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM 0x0200 /** iSCSI session needs to send the CHAP response */ #define ISCSI_STATUS_STRINGS_CHAP_RESPONSE 0x0400 /** iSCSI session needs to send the mutual CHAP challenge */ #define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE 0x0800 /** iSCSI session needs to send the operational negotiation strings */ #define ISCSI_STATUS_STRINGS_OPERATIONAL 0x1000 /** Mask for all iSCSI "needs to send" flags */ #define ISCSI_STATUS_STRINGS_MASK 0xff00 /** Target has requested forward (initiator) authentication */ #define ISCSI_STATUS_AUTH_FORWARD_REQUIRED 0x00010000 /** Initiator requires target (reverse) authentication */ #define ISCSI_STATUS_AUTH_REVERSE_REQUIRED 0x00020000 /** Target authenticated itself correctly */ #define ISCSI_STATUS_AUTH_REVERSE_OK 0x00040000 /** Maximum number of retries at connecting */ #define ISCSI_MAX_RETRIES 2 extern int iscsi_attach ( struct scsi_device *scsi, const char *root_path ); extern void iscsi_detach ( struct scsi_device *scsi ); extern const char * iscsi_initiator_iqn ( void ); #endif /* _GPXE_ISCSI_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/dhcpopts.h0000664000000000000000000000145712524662415021335 0ustar #ifndef _GPXE_DHCPOPTS_H #define _GPXE_DHCPOPTS_H /** @file * * DHCP options * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** A DHCP options block */ struct dhcp_options { /** Option block raw data */ void *data; /** Option block length */ size_t len; /** Option block maximum length */ size_t max_len; }; extern int dhcpopt_store ( struct dhcp_options *options, unsigned int tag, const void *data, size_t len ); extern int dhcpopt_extensible_store ( struct dhcp_options *options, unsigned int tag, const void *data, size_t len ); extern int dhcpopt_fetch ( struct dhcp_options *options, unsigned int tag, void *data, size_t len ); extern void dhcpopt_init ( struct dhcp_options *options, void *data, size_t max_len ); #endif /* _GPXE_DHCPOPTS_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/if_ether.h0000664000000000000000000000215412524662415021271 0ustar #ifndef _GPXE_IF_ETHER_H #define _GPXE_IF_ETHER_H FILE_LICENCE ( GPL2_OR_LATER ); #include #define ETH_ALEN 6 /* Size of Ethernet address */ #define ETH_HLEN 14 /* Size of ethernet header */ #define ETH_ZLEN 60 /* Minimum packet */ #define ETH_FRAME_LEN 1514 /* Maximum packet */ #define ETH_DATA_ALIGN 2 /* Amount needed to align the data after an ethernet header */ #ifndef ETH_MAX_MTU #define ETH_MAX_MTU (ETH_FRAME_LEN-ETH_HLEN) #endif #define ETH_P_RAW 0x0000 /* Raw packet */ #define ETH_P_IP 0x0800 /* Internet Protocl Packet */ #define ETH_P_ARP 0x0806 /* Address Resolution Protocol */ #define ETH_P_RARP 0x8035 /* Reverse Address resolution Protocol */ #define ETH_P_IPV6 0x86DD /* IPv6 over blueblook */ #define ETH_P_SLOW 0x8809 /* Ethernet slow protocols */ #define ETH_P_AOE 0x88A2 /* ATA over Ethernet */ /** An Ethernet link-layer header */ struct ethhdr { /** Destination MAC address */ uint8_t h_dest[ETH_ALEN]; /** Source MAC address */ uint8_t h_source[ETH_ALEN]; /** Protocol ID */ uint16_t h_protocol; } __attribute__ ((packed)); #endif /* _GPXE_IF_ETHER_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/aoe.h0000664000000000000000000000710112524662415020245 0ustar #ifndef _GPXE_AOE_H #define _GPXE_AOE_H /** @file * * AoE protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include /** An AoE config command */ struct aoecfg { /** AoE Queue depth */ uint16_t bufcnt; /** ATA target firmware version */ uint16_t fwver; /** ATA target sector count */ uint8_t scnt; /** AoE config string subcommand */ uint8_t aoeccmd; /** AoE config string length */ uint16_t cfglen; /** AoE config string */ uint8_t data[0]; } __attribute__ (( packed )); /** An AoE ATA command */ struct aoeata { /** AoE command flags */ uint8_t aflags; /** ATA error/feature register */ uint8_t err_feat; /** ATA sector count register */ uint8_t count; /** ATA command/status register */ uint8_t cmd_stat; /** Logical block address, in little-endian order */ union { uint64_t u64; uint8_t bytes[6]; } lba; /** Data payload */ uint8_t data[0]; } __attribute__ (( packed )); #define AOE_FL_EXTENDED 0x40 /**< LBA48 extended addressing */ #define AOE_FL_DEV_HEAD 0x10 /**< Device/head flag */ #define AOE_FL_ASYNC 0x02 /**< Asynchronous write */ #define AOE_FL_WRITE 0x01 /**< Write command */ /** An AoE command */ union aoecmd { /** Config command */ struct aoecfg cfg; /** ATA command */ struct aoeata ata; }; /** An AoE header */ struct aoehdr { /** Protocol version number and flags */ uint8_t ver_flags; /** Error code */ uint8_t error; /** Major device number, in network byte order */ uint16_t major; /** Minor device number */ uint8_t minor; /** Command number */ uint8_t command; /** Tag, in network byte order */ uint32_t tag; /** Payload */ union aoecmd cmd[0]; } __attribute__ (( packed )); #define AOE_VERSION 0x10 /**< Version 1 */ #define AOE_VERSION_MASK 0xf0 /**< Version part of ver_flags field */ #define AOE_FL_RESPONSE 0x08 /**< Message is a response */ #define AOE_FL_ERROR 0x04 /**< Command generated an error */ #define AOE_MAJOR_BROADCAST 0xffff #define AOE_MINOR_BROADCAST 0xff #define AOE_CMD_ATA 0x00 /**< Issue ATA command */ #define AOE_CMD_CONFIG 0x01 /**< Query Config Information */ #define AOE_TAG_MAGIC 0xebeb0000 #define AOE_ERR_BAD_COMMAND 1 /**< Unrecognised command code */ #define AOE_ERR_BAD_PARAMETER 2 /**< Bad argument parameter */ #define AOE_ERR_UNAVAILABLE 3 /**< Device unavailable */ #define AOE_ERR_CONFIG_EXISTS 4 /**< Config string present */ #define AOE_ERR_BAD_VERSION 5 /**< Unsupported version */ /** An AoE session */ struct aoe_session { /** Reference counter */ struct refcnt refcnt; /** List of all AoE sessions */ struct list_head list; /** Network device */ struct net_device *netdev; /** Major number */ uint16_t major; /** Minor number */ uint8_t minor; /** Target MAC address */ uint8_t target[ETH_ALEN]; /** Tag for current AoE command */ uint32_t tag; /** Current AOE command */ uint8_t aoe_cmd_type; /** Current ATA command */ struct ata_command *command; /** Overall status of current ATA command */ unsigned int status; /** Byte offset within command's data buffer */ unsigned int command_offset; /** Return status code for command */ int rc; /** Retransmission timer */ struct retry_timer timer; }; #define AOE_STATUS_ERR_MASK 0x0f /**< Error portion of status code */ #define AOE_STATUS_PENDING 0x80 /**< Command pending */ /** Maximum number of sectors per packet */ #define AOE_MAX_COUNT 2 extern void aoe_detach ( struct ata_device *ata ); extern int aoe_attach ( struct ata_device *ata, struct net_device *netdev, const char *root_path ); #endif /* _GPXE_AOE_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ib_mi.h0000664000000000000000000000721212524662415020563 0ustar #ifndef _GPXE_IB_MI_H #define _GPXE_IB_MI_H /** @file * * Infiniband management interfaces * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include struct ib_mad_interface; struct ib_mad_transaction; /** An Infiniband management agent */ struct ib_mad_agent { /** Management class */ uint8_t mgmt_class; /** Class version */ uint8_t class_version; /** Attribute (in network byte order) */ uint16_t attr_id; /** Handle MAD * * @v ibdev Infiniband device * @v mi Management interface * @v mad Received MAD * @v av Source address vector * @ret rc Return status code */ void ( * handle ) ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av ); }; /** Infiniband management agents */ #define IB_MAD_AGENTS __table ( struct ib_mad_agent, "ib_mad_agents" ) /** Declare an Infiniband management agent */ #define __ib_mad_agent __table_entry ( IB_MAD_AGENTS, 01 ) /** Infiniband management transaction operations */ struct ib_mad_transaction_operations { /** Handle transaction completion * * @v ibdev Infiniband device * @v mi Management interface * @v madx Management transaction * @v rc Status code * @v mad Received MAD (or NULL on error) * @v av Source address vector (or NULL on error) * * The completion handler should in most cases call * ib_destroy_madx() to free up the completed transaction. */ void ( * complete ) ( struct ib_device *ibdev, struct ib_mad_interface *mi, struct ib_mad_transaction *madx, int rc, union ib_mad *mad, struct ib_address_vector *av ); }; /** An Infiniband management transaction */ struct ib_mad_transaction { /** Associated management interface */ struct ib_mad_interface *mi; /** List of transactions */ struct list_head list; /** Retry timer */ struct retry_timer timer; /** Destination address vector */ struct ib_address_vector av; /** MAD being sent */ union ib_mad mad; /** Transaction operations */ struct ib_mad_transaction_operations *op; /** Owner private data */ void *owner_priv; }; /** An Infiniband management interface */ struct ib_mad_interface { /** Infiniband device */ struct ib_device *ibdev; /** Completion queue */ struct ib_completion_queue *cq; /** Queue pair */ struct ib_queue_pair *qp; /** List of management transactions */ struct list_head madx; }; /** * Set Infiniband management transaction owner-private data * * @v madx Management transaction * @v priv Private data */ static inline __always_inline void ib_madx_set_ownerdata ( struct ib_mad_transaction *madx, void *priv ) { madx->owner_priv = priv; } /** * Get Infiniband management transaction owner-private data * * @v madx Management transaction * @ret priv Private data */ static inline __always_inline void * ib_madx_get_ownerdata ( struct ib_mad_transaction *madx ) { return madx->owner_priv; } extern int ib_mi_send ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av ); extern struct ib_mad_transaction * ib_create_madx ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av, struct ib_mad_transaction_operations *op ); extern void ib_destroy_madx ( struct ib_device *ibdev, struct ib_mad_interface *mi, struct ib_mad_transaction *madx ); extern struct ib_mad_interface * ib_create_mi ( struct ib_device *ibdev, enum ib_queue_pair_type type ); extern void ib_destroy_mi ( struct ib_device *ibdev, struct ib_mad_interface *mi ); #endif /* _GPXE_IB_MI_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/netdevice.h0000664000000000000000000003401112524662415021447 0ustar #ifndef _GPXE_NETDEVICE_H #define _GPXE_NETDEVICE_H /** @file * * Network device management * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include struct io_buffer; struct net_device; struct net_protocol; struct ll_protocol; struct device; /** Maximum length of a hardware address * * The longest currently-supported link-layer address is for IPoIB. */ #define MAX_HW_ADDR_LEN 8 /** Maximum length of a link-layer address * * The longest currently-supported link-layer address is for IPoIB. */ #define MAX_LL_ADDR_LEN 20 /** Maximum length of a link-layer header * * The longest currently-supported link-layer header is for 802.11: a * 24-byte frame header plus an 8-byte 802.3 LLC/SNAP header. (The * IPoIB link-layer pseudo-header doesn't actually include link-layer * addresses; see ipoib.c for details). */ #define MAX_LL_HEADER_LEN 32 /** Maximum length of a network-layer address */ #define MAX_NET_ADDR_LEN 4 /** * A network-layer protocol * */ struct net_protocol { /** Protocol name */ const char *name; /** * Process received packet * * @v iobuf I/O buffer * @v netdev Network device * @v ll_source Link-layer source address * * This method takes ownership of the I/O buffer. */ int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev, const void *ll_source ); /** * Transcribe network-layer address * * @v net_addr Network-layer address * @ret string Human-readable transcription of address * * This method should convert the network-layer address into a * human-readable format (e.g. dotted quad notation for IPv4). * * The buffer used to hold the transcription is statically * allocated. */ const char * ( *ntoa ) ( const void * net_addr ); /** Network-layer protocol * * This is an ETH_P_XXX constant, in network-byte order */ uint16_t net_proto; /** Network-layer address length */ uint8_t net_addr_len; }; /** * A link-layer protocol * */ struct ll_protocol { /** Protocol name */ const char *name; /** * Add link-layer header * * @v netdev Network device * @v iobuf I/O buffer * @v ll_dest Link-layer destination address * @v ll_source Source link-layer address * @v net_proto Network-layer protocol, in network-byte order * @ret rc Return status code */ int ( * push ) ( struct net_device *netdev, struct io_buffer *iobuf, const void *ll_dest, const void *ll_source, uint16_t net_proto ); /** * Remove link-layer header * * @v netdev Network device * @v iobuf I/O buffer * @ret ll_dest Link-layer destination address * @ret ll_source Source link-layer address * @ret net_proto Network-layer protocol, in network-byte order * @ret rc Return status code */ int ( * pull ) ( struct net_device *netdev, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t *net_proto ); /** * Initialise link-layer address * * @v hw_addr Hardware address * @v ll_addr Link-layer address to fill in */ void ( * init_addr ) ( const void *hw_addr, void *ll_addr ); /** * Transcribe link-layer address * * @v ll_addr Link-layer address * @ret string Human-readable transcription of address * * This method should convert the link-layer address into a * human-readable format. * * The buffer used to hold the transcription is statically * allocated. */ const char * ( * ntoa ) ( const void *ll_addr ); /** * Hash multicast address * * @v af Address family * @v net_addr Network-layer address * @v ll_addr Link-layer address to fill in * @ret rc Return status code */ int ( * mc_hash ) ( unsigned int af, const void *net_addr, void *ll_addr ); /** Link-layer protocol * * This is an ARPHRD_XXX constant, in network byte order. */ uint16_t ll_proto; /** Hardware address length */ uint8_t hw_addr_len; /** Link-layer address length */ uint8_t ll_addr_len; /** Link-layer header length */ uint8_t ll_header_len; }; /** Network device operations */ struct net_device_operations { /** Open network device * * @v netdev Network device * @ret rc Return status code * * This method should allocate RX I/O buffers and enable * the hardware to start transmitting and receiving packets. */ int ( * open ) ( struct net_device *netdev ); /** Close network device * * @v netdev Network device * * This method should stop the flow of packets, and free up * any packets that are currently in the device's TX queue. */ void ( * close ) ( struct net_device *netdev ); /** Transmit packet * * @v netdev Network device * @v iobuf I/O buffer * @ret rc Return status code * * This method should cause the hardware to initiate * transmission of the I/O buffer. * * If this method returns success, the I/O buffer remains * owned by the net device's TX queue, and the net device must * eventually call netdev_tx_complete() to free the buffer. * If this method returns failure, the I/O buffer is * immediately released; the failure is interpreted as * "failure to enqueue buffer". * * This method is guaranteed to be called only when the device * is open. */ int ( * transmit ) ( struct net_device *netdev, struct io_buffer *iobuf ); /** Poll for completed and received packets * * @v netdev Network device * * This method should cause the hardware to check for * completed transmissions and received packets. Any received * packets should be delivered via netdev_rx(). * * This method is guaranteed to be called only when the device * is open. */ void ( * poll ) ( struct net_device *netdev ); /** Enable or disable interrupts * * @v netdev Network device * @v enable Interrupts should be enabled */ void ( * irq ) ( struct net_device *netdev, int enable ); }; /** Network device error */ struct net_device_error { /** Error status code */ int rc; /** Error count */ unsigned int count; }; /** Maximum number of unique errors that we will keep track of */ #define NETDEV_MAX_UNIQUE_ERRORS 4 /** Network device statistics */ struct net_device_stats { /** Count of successful completions */ unsigned int good; /** Count of error completions */ unsigned int bad; /** Error breakdowns */ struct net_device_error errors[NETDEV_MAX_UNIQUE_ERRORS]; }; /** * A network device * * This structure represents a piece of networking hardware. It has * properties such as a link-layer address and methods for * transmitting and receiving raw packets. * * Note that this structure must represent a generic network device, * not just an Ethernet device. */ struct net_device { /** Reference counter */ struct refcnt refcnt; /** List of network devices */ struct list_head list; /** List of open network devices */ struct list_head open_list; /** Name of this network device */ char name[8]; /** Underlying hardware device */ struct device *dev; /** Network device operations */ struct net_device_operations *op; /** Link-layer protocol */ struct ll_protocol *ll_protocol; /** Hardware address * * This is an address which is an intrinsic property of the * hardware, e.g. an address held in EEPROM. * * Note that the hardware address may not be the same length * as the link-layer address. */ uint8_t hw_addr[MAX_HW_ADDR_LEN]; /** Link-layer address * * This is the current link-layer address assigned to the * device. It can be changed at runtime. */ uint8_t ll_addr[MAX_LL_ADDR_LEN]; /** Link-layer broadcast address */ const uint8_t *ll_broadcast; /** Current device state * * This is the bitwise-OR of zero or more NETDEV_XXX constants. */ unsigned int state; /** Link status code * * Zero indicates that the link is up; any other value * indicates the error preventing link-up. */ int link_rc; /** Maximum packet length * * This length includes any link-layer headers. */ size_t max_pkt_len; /** TX packet queue */ struct list_head tx_queue; /** RX packet queue */ struct list_head rx_queue; /** TX statistics */ struct net_device_stats tx_stats; /** RX statistics */ struct net_device_stats rx_stats; /** Configuration settings applicable to this device */ struct generic_settings settings; /** Driver private data */ void *priv; }; /** Network device is open */ #define NETDEV_OPEN 0x0001 /** Link-layer protocol table */ #define LL_PROTOCOLS __table ( struct ll_protocol, "ll_protocols" ) /** Declare a link-layer protocol */ #define __ll_protocol __table_entry ( LL_PROTOCOLS, 01 ) /** Network-layer protocol table */ #define NET_PROTOCOLS __table ( struct net_protocol, "net_protocols" ) /** Declare a network-layer protocol */ #define __net_protocol __table_entry ( NET_PROTOCOLS, 01 ) extern struct list_head net_devices; extern struct net_device_operations null_netdev_operations; extern struct settings_operations netdev_settings_operations; /** * Initialise a network device * * @v netdev Network device * @v op Network device operations */ static inline void netdev_init ( struct net_device *netdev, struct net_device_operations *op ) { netdev->op = op; } /** * Stop using a network device * * @v netdev Network device * * Drivers should call this method immediately before the final call * to netdev_put(). */ static inline void netdev_nullify ( struct net_device *netdev ) { netdev->op = &null_netdev_operations; } /** * Get printable network device link-layer address * * @v netdev Network device * @ret name Link-layer address */ static inline const char * netdev_addr ( struct net_device *netdev ) { return netdev->ll_protocol->ntoa ( netdev->ll_addr ); } /** Iterate over all network devices */ #define for_each_netdev( netdev ) \ list_for_each_entry ( (netdev), &net_devices, list ) /** There exist some network devices * * @ret existence Existence of network devices */ static inline int have_netdevs ( void ) { return ( ! list_empty ( &net_devices ) ); } /** * Get reference to network device * * @v netdev Network device * @ret netdev Network device */ static inline __attribute__ (( always_inline )) struct net_device * netdev_get ( struct net_device *netdev ) { ref_get ( &netdev->refcnt ); return netdev; } /** * Drop reference to network device * * @v netdev Network device */ static inline __attribute__ (( always_inline )) void netdev_put ( struct net_device *netdev ) { ref_put ( &netdev->refcnt ); } /** * Get driver private area for this network device * * @v netdev Network device * @ret priv Driver private area for this network device */ static inline __attribute__ (( always_inline )) void * netdev_priv ( struct net_device *netdev ) { return netdev->priv; } /** * Get per-netdevice configuration settings block * * @v netdev Network device * @ret settings Settings block */ static inline __attribute__ (( always_inline )) struct settings * netdev_settings ( struct net_device *netdev ) { return &netdev->settings.settings; } /** * Initialise a per-netdevice configuration settings block * * @v generics Generic settings block * @v refcnt Containing object reference counter, or NULL * @v name Settings block name */ static inline __attribute__ (( always_inline )) void netdev_settings_init ( struct net_device *netdev ) { generic_settings_init ( &netdev->settings, &netdev->refcnt, netdev->name ); netdev->settings.settings.op = &netdev_settings_operations; } /** * Mark network device as having link up * * @v netdev Network device */ static inline __attribute__ (( always_inline )) void netdev_link_up ( struct net_device *netdev ) { netdev->link_rc = 0; } /** * Mark network device as having link down due to a specific error * * @v netdev Network device * @v rc Link status code */ static inline __attribute__ (( always_inline )) void netdev_link_err ( struct net_device *netdev, int rc ) { netdev->link_rc = rc; } /** * Check link state of network device * * @v netdev Network device * @ret link_up Link is up */ static inline __attribute__ (( always_inline )) int netdev_link_ok ( struct net_device *netdev ) { return ( netdev->link_rc == 0 ); } extern void netdev_link_down ( struct net_device *netdev ); extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ); extern void netdev_tx_complete_err ( struct net_device *netdev, struct io_buffer *iobuf, int rc ); extern void netdev_tx_complete_next_err ( struct net_device *netdev, int rc ); extern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ); extern void netdev_rx_err ( struct net_device *netdev, struct io_buffer *iobuf, int rc ); extern void netdev_poll ( struct net_device *netdev ); extern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev ); extern struct net_device * alloc_netdev ( size_t priv_size ); extern int register_netdev ( struct net_device *netdev ); extern int netdev_open ( struct net_device *netdev ); extern void netdev_close ( struct net_device *netdev ); extern void unregister_netdev ( struct net_device *netdev ); extern void netdev_irq ( struct net_device *netdev, int enable ); extern struct net_device * find_netdev ( const char *name ); extern struct net_device * find_netdev_by_location ( unsigned int bus_type, unsigned int location ); extern struct net_device * last_opened_netdev ( void ); extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev, struct net_protocol *net_protocol, const void *ll_dest ); extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev, uint16_t net_proto, const void *ll_source ); /** * Complete network transmission * * @v netdev Network device * @v iobuf I/O buffer * * The packet must currently be in the network device's TX queue. */ static inline void netdev_tx_complete ( struct net_device *netdev, struct io_buffer *iobuf ) { netdev_tx_complete_err ( netdev, iobuf, 0 ); } /** * Complete network transmission * * @v netdev Network device * * Completes the oldest outstanding packet in the TX queue. */ static inline void netdev_tx_complete_next ( struct net_device *netdev ) { netdev_tx_complete_next_err ( netdev, 0 ); } #endif /* _GPXE_NETDEVICE_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/spi.h0000664000000000000000000001423512524662415020302 0ustar #ifndef _GPXE_SPI_H #define _GPXE_SPI_H /** @file * * SPI interface * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** * @defgroup spicmds SPI commands * @{ */ /** Write status register */ #define SPI_WRSR 0x01 /** Write data to memory array */ #define SPI_WRITE 0x02 /** Read data from memory array */ #define SPI_READ 0x03 /** Reset write enable latch */ #define SPI_WRDI 0x04 /** Read status register */ #define SPI_RDSR 0x05 /** Set write enable latch */ #define SPI_WREN 0x06 /** * @defgroup atmelcmds Atmel-specific SPI commands * @{ */ /** Erase one sector in memory array (Not supported on all devices) */ #define ATMEL_SECTOR_ERASE 0x52 /** Erase all sections in memory array (Not supported on all devices) */ #define ATMEL_CHIP_ERASE 0x62 /** Read manufacturer and product ID (Not supported on all devices) */ #define ATMEL_RDID 0x15 /** @} */ /** @} */ /** * @defgroup spistatus SPI status register bits (not present on all devices) * @{ */ /** Write-protect pin enabled */ #define SPI_STATUS_WPEN 0x80 /** Block protection bit 2 */ #define SPI_STATUS_BP2 0x10 /** Block protection bit 1 */ #define SPI_STATUS_BP1 0x08 /** Block protection bit 0 */ #define SPI_STATUS_BP0 0x04 /** State of the write enable latch */ #define SPI_STATUS_WEN 0x02 /** Device busy flag */ #define SPI_STATUS_NRDY 0x01 /** @} */ /** * An SPI device * * This data structure represents a physical SPI device attached to an * SPI bus. */ struct spi_device { /** NVS device */ struct nvs_device nvs; /** SPI bus to which device is attached */ struct spi_bus *bus; /** Slave number */ unsigned int slave; /** Command length, in bits */ unsigned int command_len; /** Address length, in bits */ unsigned int address_len; /** Address is munged * * Some devices with 9-bit addresses (e.g. AT25040A EEPROM) * use bit 3 of the command byte as address bit A8, rather * than having a two-byte address. If this flag is set, then * commands should be munged in this way. */ unsigned int munge_address : 1; }; /** * SPI magic autodetection address length * * Set @c spi_device::address_len to @c SPI_AUTODETECT_ADDRESS_LEN if * the address length should be autodetected. */ #define SPI_AUTODETECT_ADDRESS_LEN 0 static inline __attribute__ (( always_inline )) struct spi_device * nvs_to_spi ( struct nvs_device *nvs ) { return container_of ( nvs, struct spi_device, nvs ); } /** * An SPI bus * * This data structure represents an SPI bus controller capable of * issuing commands to attached SPI devices. */ struct spi_bus { /** SPI interface mode * * This is the bitwise OR of zero or more of @c SPI_MODE_CPHA * and @c SPI_MODE_CPOL. It is also the number conventionally * used to describe the SPI interface mode. For example, SPI * mode 1 is the mode in which CPOL=0 and CPHA=1, which * therefore corresponds to a mode value of (0|SPI_MODE_CPHA) * which, happily, equals 1. */ unsigned int mode; /** * Read/write data via SPI bus * * @v bus SPI bus * @v device SPI device * @v command Command * @v address Address to read/write (<0 for no address) * @v data_out TX data buffer (or NULL) * @v data_in RX data buffer (or NULL) * @v len Length of data buffer(s) * * This issues the specified command and optional address to * the SPI device, then reads and/or writes data to/from the * data buffers. */ int ( * rw ) ( struct spi_bus *bus, struct spi_device *device, unsigned int command, int address, const void *data_out, void *data_in, size_t len ); }; /** Clock phase (CPHA) mode bit * * Phase 0 is sample on rising edge, shift data on falling edge. * * Phase 1 is shift data on rising edge, sample data on falling edge. */ #define SPI_MODE_CPHA 0x01 /** Clock polarity (CPOL) mode bit * * This bit reflects the idle state of the clock line (SCLK). */ #define SPI_MODE_CPOL 0x02 /** Slave select polarity mode bit * * This bit reflects that active state of the slave select lines. It * is not part of the normal SPI mode number (which covers only @c * SPI_MODE_CPOL and @c SPI_MODE_CPHA), but is included here for * convenience. */ #define SPI_MODE_SSPOL 0x10 /** Microwire-compatible mode * * This is SPI mode 1 (i.e. CPOL=0, CPHA=1), and is compatible with * the original Microwire protocol. */ #define SPI_MODE_MICROWIRE 1 /** Microwire/Plus-compatible mode * * This is SPI mode 0 (i.e. CPOL=0, CPHA=0), and is compatible with * the Microwire/Plus protocol */ #define SPI_MODE_MICROWIRE_PLUS 0 /** Threewire-compatible mode * * This mode is compatible with Atmel's series of "three-wire" * interfaces. */ #define SPI_MODE_THREEWIRE ( SPI_MODE_MICROWIRE_PLUS | SPI_MODE_SSPOL ) extern int spi_read ( struct nvs_device *nvs, unsigned int address, void *data, size_t len ); extern int spi_write ( struct nvs_device *nvs, unsigned int address, const void *data, size_t len ); /** * @defgroup spidevs SPI device types * @{ */ static inline __attribute__ (( always_inline )) void init_spi ( struct spi_device *device ) { device->nvs.word_len_log2 = 0; device->command_len = 8, device->nvs.read = spi_read; device->nvs.write = spi_write; } /** Atmel AT25F1024 serial flash */ static inline __attribute__ (( always_inline )) void init_at25f1024 ( struct spi_device *device ) { device->address_len = 24; device->nvs.size = ( 128 * 1024 ); device->nvs.block_size = 256; init_spi ( device ); } /** Atmel 25040 serial EEPROM */ static inline __attribute__ (( always_inline )) void init_at25040 ( struct spi_device *device ) { device->address_len = 8; device->munge_address = 1; device->nvs.size = 512; device->nvs.block_size = 8; init_spi ( device ); } /** ST M25P32 serial flash */ static inline __attribute__ (( always_inline )) void init_m25p32 ( struct spi_device *device ) { device->address_len = 24; device->nvs.size = ( 4 * 1024 * 1024 ); device->nvs.block_size = 256; init_spi ( device ); } /** Microchip 25XX640 serial EEPROM */ static inline __attribute__ (( always_inline )) void init_mc25xx640 ( struct spi_device *device ) { device->address_len = 16; device->nvs.size = ( 8 * 1024 ); device->nvs.block_size = 32; init_spi ( device ); } /** @} */ #endif /* _GPXE_SPI_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/pci_io.h0000664000000000000000000000571712524662415020756 0ustar #ifndef _GPXE_PCI_IO_H #define _GPXE_PCI_IO_H /** @file * * PCI I/O API * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include /** * Calculate static inline PCI I/O API function name * * @v _prefix Subsystem prefix * @v _api_func API function * @ret _subsys_func Subsystem API function */ #define PCIAPI_INLINE( _subsys, _api_func ) \ SINGLE_API_INLINE ( PCIAPI_PREFIX_ ## _subsys, _api_func ) /** * Provide a PCI I/O API implementation * * @v _prefix Subsystem prefix * @v _api_func API function * @v _func Implementing function */ #define PROVIDE_PCIAPI( _subsys, _api_func, _func ) \ PROVIDE_SINGLE_API ( PCIAPI_PREFIX_ ## _subsys, _api_func, _func ) /** * Provide a static inline PCI I/O API implementation * * @v _prefix Subsystem prefix * @v _api_func API function */ #define PROVIDE_PCIAPI_INLINE( _subsys, _api_func ) \ PROVIDE_SINGLE_API_INLINE ( PCIAPI_PREFIX_ ## _subsys, _api_func ) /* Include all architecture-independent I/O API headers */ #include /* Include all architecture-dependent I/O API headers */ #include /** * Determine maximum PCI bus number within system * * @ret max_bus Maximum bus number */ int pci_max_bus ( void ); /** * Read byte from PCI configuration space * * @v pci PCI device * @v where Location within PCI configuration space * @v value Value read * @ret rc Return status code */ int pci_read_config_byte ( struct pci_device *pci, unsigned int where, uint8_t *value ); /** * Read 16-bit word from PCI configuration space * * @v pci PCI device * @v where Location within PCI configuration space * @v value Value read * @ret rc Return status code */ int pci_read_config_word ( struct pci_device *pci, unsigned int where, uint16_t *value ); /** * Read 32-bit dword from PCI configuration space * * @v pci PCI device * @v where Location within PCI configuration space * @v value Value read * @ret rc Return status code */ int pci_read_config_dword ( struct pci_device *pci, unsigned int where, uint32_t *value ); /** * Write byte to PCI configuration space * * @v pci PCI device * @v where Location within PCI configuration space * @v value Value to be written * @ret rc Return status code */ int pci_write_config_byte ( struct pci_device *pci, unsigned int where, uint8_t value ); /** * Write 16-bit word to PCI configuration space * * @v pci PCI device * @v where Location within PCI configuration space * @v value Value to be written * @ret rc Return status code */ int pci_write_config_word ( struct pci_device *pci, unsigned int where, uint16_t value ); /** * Write 32-bit dword to PCI configuration space * * @v pci PCI device * @v where Location within PCI configuration space * @v value Value to be written * @ret rc Return status code */ int pci_write_config_dword ( struct pci_device *pci, unsigned int where, uint32_t value ); #endif /* _GPXE_PCI_IO_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/blockdev.h0000664000000000000000000000200512524662415021270 0ustar #ifndef _GPXE_BLOCKDEV_H #define _GPXE_BLOCKDEV_H /** * @file * * Block devices * */ FILE_LICENCE ( GPL2_OR_LATER ); #include struct block_device; /** Block device operations */ struct block_device_operations { /** * Read block * * @v blockdev Block device * @v block Block number * @v count Block count * @v buffer Data buffer * @ret rc Return status code */ int ( * read ) ( struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer ); /** * Write block * * @v blockdev Block device * @v block Block number * @v count Block count * @v buffer Data buffer * @ret rc Return status code */ int ( * write ) ( struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer ); }; /** A block device */ struct block_device { /** Block device operations */ struct block_device_operations *op; /** Block size */ size_t blksize; /** Total number of blocks */ uint64_t blocks; }; #endif /* _GPXE_BLOCKDEV_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/hidemem.h0000664000000000000000000000036512524662415021116 0ustar #ifndef _GPXE_HIDEMEM_H #define _GPXE_HIDEMEM_H /** * @file * * Hidden memory regions * */ FILE_LICENCE ( GPL2_OR_LATER ); #include extern void hide_umalloc ( physaddr_t start, physaddr_t end ); #endif /* _GPXE_HIDEMEM_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/crypto.h0000664000000000000000000000730312524662415021025 0ustar #ifndef _GPXE_CRYPTO_H #define _GPXE_CRYPTO_H /** @file * * Cryptographic API * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** A message digest algorithm */ struct digest_algorithm { /** Algorithm name */ const char *name; /** Context size */ size_t ctxsize; /** Block size */ size_t blocksize; /** Digest size */ size_t digestsize; /** Initialise digest * * @v ctx Context */ void ( * init ) ( void *ctx ); /** Update digest with new data * * @v ctx Context * @v src Data to digest * @v len Length of data * * @v len is not necessarily a multiple of @c blocksize. */ void ( * update ) ( void *ctx, const void *src, size_t len ); /** Finalise digest * * @v ctx Context * @v out Buffer for digest output */ void ( * final ) ( void *ctx, void *out ); }; /** A cipher algorithm */ struct cipher_algorithm { /** Algorithm name */ const char *name; /** Context size */ size_t ctxsize; /** Block size */ size_t blocksize; /** Set key * * @v ctx Context * @v key Key * @v keylen Key length * @ret rc Return status code */ int ( * setkey ) ( void *ctx, const void *key, size_t keylen ); /** Set initialisation vector * * @v ctx Context * @v iv Initialisation vector */ void ( * setiv ) ( void *ctx, const void *iv ); /** Encrypt data * * @v ctx Context * @v src Data to encrypt * @v dst Buffer for encrypted data * @v len Length of data * * @v len is guaranteed to be a multiple of @c blocksize. */ void ( * encrypt ) ( void *ctx, const void *src, void *dst, size_t len ); /** Decrypt data * * @v ctx Context * @v src Data to decrypt * @v dst Buffer for decrypted data * @v len Length of data * * @v len is guaranteed to be a multiple of @c blocksize. */ void ( * decrypt ) ( void *ctx, const void *src, void *dst, size_t len ); }; /** A public key algorithm */ struct pubkey_algorithm { /** Algorithm name */ const char *name; /** Context size */ size_t ctxsize; }; static inline void digest_init ( struct digest_algorithm *digest, void *ctx ) { digest->init ( ctx ); } static inline void digest_update ( struct digest_algorithm *digest, void *ctx, const void *data, size_t len ) { digest->update ( ctx, data, len ); } static inline void digest_final ( struct digest_algorithm *digest, void *ctx, void *out ) { digest->final ( ctx, out ); } static inline int cipher_setkey ( struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen ) { return cipher->setkey ( ctx, key, keylen ); } static inline void cipher_setiv ( struct cipher_algorithm *cipher, void *ctx, const void *iv ) { cipher->setiv ( ctx, iv ); } static inline void cipher_encrypt ( struct cipher_algorithm *cipher, void *ctx, const void *src, void *dst, size_t len ) { cipher->encrypt ( ctx, src, dst, len ); } #define cipher_encrypt( cipher, ctx, src, dst, len ) do { \ assert ( ( len & ( (cipher)->blocksize - 1 ) ) == 0 ); \ cipher_encrypt ( (cipher), (ctx), (src), (dst), (len) ); \ } while ( 0 ) static inline void cipher_decrypt ( struct cipher_algorithm *cipher, void *ctx, const void *src, void *dst, size_t len ) { cipher->decrypt ( ctx, src, dst, len ); } #define cipher_decrypt( cipher, ctx, src, dst, len ) do { \ assert ( ( len & ( (cipher)->blocksize - 1 ) ) == 0 ); \ cipher_decrypt ( (cipher), (ctx), (src), (dst), (len) ); \ } while ( 0 ) static inline int is_stream_cipher ( struct cipher_algorithm *cipher ) { return ( cipher->blocksize == 1 ); } extern struct digest_algorithm digest_null; extern struct cipher_algorithm cipher_null; extern struct pubkey_algorithm pubkey_null; #endif /* _GPXE_CRYPTO_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/scsi.h0000664000000000000000000001454312524662415020452 0ustar #ifndef _GPXE_SCSI_H #define _GPXE_SCSI_H #include #include #include #include /** @file * * SCSI devices * */ FILE_LICENCE ( GPL2_OR_LATER ); /** * @defgroup scsiops SCSI operation codes * @{ */ #define SCSI_OPCODE_READ_10 0x28 /**< READ (10) */ #define SCSI_OPCODE_READ_16 0x88 /**< READ (16) */ #define SCSI_OPCODE_WRITE_10 0x2a /**< WRITE (10) */ #define SCSI_OPCODE_WRITE_16 0x8a /**< WRITE (16) */ #define SCSI_OPCODE_READ_CAPACITY_10 0x25 /**< READ CAPACITY (10) */ #define SCSI_OPCODE_SERVICE_ACTION_IN 0x9e /**< SERVICE ACTION IN */ #define SCSI_SERVICE_ACTION_READ_CAPACITY_16 0x10 /**< READ CAPACITY (16) */ /** @} */ /** * @defgroup scsiflags SCSI flags * @{ */ #define SCSI_FL_FUA_NV 0x02 /**< Force unit access to NVS */ #define SCSI_FL_FUA 0x08 /**< Force unit access */ #define SCSI_FL_DPO 0x10 /**< Disable cache page out */ /** @} */ /** * @defgroup scsicdbs SCSI command data blocks * @{ */ /** A SCSI "READ (10)" CDB */ struct scsi_cdb_read_10 { /** Opcode (0x28) */ uint8_t opcode; /** Flags */ uint8_t flags; /** Start address * * This is a logical block number, in big-endian order. */ uint32_t lba; /** Group number */ uint8_t group; /** Transfer length * * This is a logical block count, in big-endian order. */ uint16_t len; /** Control byte */ uint8_t control; } __attribute__ (( packed )); /** A SCSI "READ (16)" CDB */ struct scsi_cdb_read_16 { /** Opcode (0x88) */ uint8_t opcode; /** Flags */ uint8_t flags; /** Start address * * This is a logical block number, in big-endian order. */ uint64_t lba; /** Transfer length * * This is a logical block count, in big-endian order. */ uint32_t len; /** Group number */ uint8_t group; /** Control byte */ uint8_t control; } __attribute__ (( packed )); /** A SCSI "WRITE (10)" CDB */ struct scsi_cdb_write_10 { /** Opcode (0x2a) */ uint8_t opcode; /** Flags */ uint8_t flags; /** Start address * * This is a logical block number, in big-endian order. */ uint32_t lba; /** Group number */ uint8_t group; /** Transfer length * * This is a logical block count, in big-endian order. */ uint16_t len; /** Control byte */ uint8_t control; } __attribute__ (( packed )); /** A SCSI "WRITE (16)" CDB */ struct scsi_cdb_write_16 { /** Opcode (0x8a) */ uint8_t opcode; /** Flags */ uint8_t flags; /** Start address * * This is a logical block number, in big-endian order. */ uint64_t lba; /** Transfer length * * This is a logical block count, in big-endian order. */ uint32_t len; /** Group number */ uint8_t group; /** Control byte */ uint8_t control; } __attribute__ (( packed )); /** A SCSI "READ CAPACITY (10)" CDB */ struct scsi_cdb_read_capacity_10 { /** Opcode (0x25) */ uint8_t opcode; /** Reserved */ uint8_t reserved_a; /** Logical block address * * Applicable only if the PMI bit is set. */ uint32_t lba; /** Reserved */ uint8_t reserved_b[3]; /** Control byte */ uint8_t control; } __attribute__ (( packed )); /** SCSI "READ CAPACITY (10)" parameter data */ struct scsi_capacity_10 { /** Maximum logical block number */ uint32_t lba; /** Block length in bytes */ uint32_t blksize; } __attribute__ (( packed )); /** A SCSI "READ CAPACITY (16)" CDB */ struct scsi_cdb_read_capacity_16 { /** Opcode (0x9e) */ uint8_t opcode; /** Service action */ uint8_t service_action; /** Logical block address * * Applicable only if the PMI bit is set. */ uint64_t lba; /** Transfer length * * This is the size of the data-in buffer, in bytes. */ uint32_t len; /** Reserved */ uint8_t reserved; /** Control byte */ uint8_t control; } __attribute__ (( packed )); /** SCSI "READ CAPACITY (16)" parameter data */ struct scsi_capacity_16 { /** Maximum logical block number */ uint64_t lba; /** Block length in bytes */ uint32_t blksize; /** Reserved */ uint8_t reserved[20]; } __attribute__ (( packed )); /** A SCSI Command Data Block */ union scsi_cdb { struct scsi_cdb_read_10 read10; struct scsi_cdb_read_16 read16; struct scsi_cdb_write_10 write10; struct scsi_cdb_write_16 write16; struct scsi_cdb_read_capacity_10 readcap10; struct scsi_cdb_read_capacity_16 readcap16; unsigned char bytes[16]; }; /** printf() format for dumping a scsi_cdb */ #define SCSI_CDB_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" \ "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" /** printf() parameters for dumping a scsi_cdb */ #define SCSI_CDB_DATA(cdb) \ (cdb).bytes[0], (cdb).bytes[1], (cdb).bytes[2], (cdb).bytes[3], \ (cdb).bytes[4], (cdb).bytes[5], (cdb).bytes[6], (cdb).bytes[7], \ (cdb).bytes[8], (cdb).bytes[9], (cdb).bytes[10], (cdb).bytes[11], \ (cdb).bytes[12], (cdb).bytes[13], (cdb).bytes[14], (cdb).bytes[15] /** @} */ /** A SCSI command */ struct scsi_command { /** CDB for this command */ union scsi_cdb cdb; /** Data-out buffer (may be NULL) */ userptr_t data_out; /** Data-out buffer length * * Must be zero if @c data_out is NULL */ size_t data_out_len; /** Data-in buffer (may be NULL) */ userptr_t data_in; /** Data-in buffer length * * Must be zero if @c data_in is NULL */ size_t data_in_len; /** SCSI status code */ uint8_t status; /** SCSI sense response code */ uint8_t sense_response; /** Command status code */ int rc; }; /** A SCSI LUN * * This is a four-level LUN as specified by SAM-2, in big-endian * order. */ struct scsi_lun { uint16_t u16[4]; } __attribute__ (( packed )); /** A SCSI device */ struct scsi_device { /** Block device interface */ struct block_device blockdev; /** * Issue SCSI command * * @v scsi SCSI device * @v command SCSI command * @ret rc Return status code * * Note that a successful return status code indicates only * that the SCSI command was issued. The caller must check * the status field in the command structure to see when the * command completes and whether, for example, the device * returned CHECK CONDITION or some other non-success status * code. */ int ( * command ) ( struct scsi_device *scsi, struct scsi_command *command ); /** Backing device */ struct refcnt *backend; }; extern int scsi_detached_command ( struct scsi_device *scsi, struct scsi_command *command ); extern int init_scsidev ( struct scsi_device *scsi ); extern int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun ); #endif /* _GPXE_SCSI_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ftp.h0000664000000000000000000000027712524662415020301 0ustar #ifndef _GPXE_FTP_H #define _GPXE_FTP_H /** @file * * File transfer protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); /** FTP default port */ #define FTP_PORT 21 #endif /* _GPXE_FTP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/elf.h0000664000000000000000000000031712524662415020251 0ustar #ifndef _GPXE_ELF_H #define _GPXE_ELF_H /** * @file * * ELF image format * */ FILE_LICENCE ( GPL2_OR_LATER ); #include extern int elf_load ( struct image *image ); #endif /* _GPXE_ELF_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ib_packet.h0000664000000000000000000000665312524662415021435 0ustar #ifndef _GPXE_IB_PACKET_H #define _GPXE_IB_PACKET_H /** @file * * Infiniband packet format * */ FILE_LICENCE ( GPL2_OR_LATER ); struct ib_device; struct ib_queue_pair; struct ib_address_vector; struct io_buffer; /** Half of an Infiniband Global Identifier */ struct ib_gid_half { union { uint8_t bytes[8]; uint16_t words[4]; uint32_t dwords[2]; } u; }; /** An Infiniband Global Identifier */ struct ib_gid { union { uint8_t bytes[16]; uint16_t words[8]; uint32_t dwords[4]; struct ib_gid_half half[2]; } u; }; /** An Infiniband Local Route Header */ struct ib_local_route_header { /** Virtual lane and link version */ uint8_t vl__lver; /** Service level and next link header */ uint8_t sl__lnh; /** Destination LID */ uint16_t dlid; /** Packet length */ uint16_t length; /** Source LID */ uint16_t slid; } __attribute__ (( packed )); /** Infiniband virtual lanes */ enum ib_vl { IB_VL_DEFAULT = 0, IB_VL_SMP = 15, }; /** An Infiniband Link Next Header value */ enum ib_lnh { IB_LNH_RAW = 0, IB_LNH_IPv6 = 1, IB_LNH_BTH = 2, IB_LNH_GRH = 3 }; /** Default Infiniband LID */ #define IB_LID_NONE 0xffff /** Test for multicast LID */ #define IB_LID_MULTICAST( lid ) ( ( (lid) >= 0xc000 ) && ( (lid) <= 0xfffe ) ) /** An Infiniband Global Route Header */ struct ib_global_route_header { /** IP version, traffic class, and flow label * * 4 bits : Version of the GRH * 8 bits : Traffic class * 20 bits : Flow label */ uint32_t ipver__tclass__flowlabel; /** Payload length */ uint16_t paylen; /** Next header */ uint8_t nxthdr; /** Hop limit */ uint8_t hoplmt; /** Source GID */ struct ib_gid sgid; /** Destiniation GID */ struct ib_gid dgid; } __attribute__ (( packed )); #define IB_GRH_IPVER_IPv6 0x06 #define IB_GRH_NXTHDR_IBA 0x1b /** An Infiniband Base Transport Header */ struct ib_base_transport_header { /** Opcode */ uint8_t opcode; /** Transport header version, pad count, migration and solicitation */ uint8_t se__m__padcnt__tver; /** Partition key */ uint16_t pkey; /** Destination queue pair */ uint32_t dest_qp; /** Packet sequence number and acknowledge request */ uint32_t ack__psn; } __attribute__ (( packed )); /** An Infiniband BTH opcode */ enum ib_bth_opcode { BTH_OPCODE_UD_SEND = 0x64, }; /** An Infiniband Datagram Extended Transport Header */ struct ib_datagram_extended_transport_header { /** Queue key */ uint32_t qkey; /** Source queue pair */ uint32_t src_qp; } __attribute__ (( packed )); /** All known IB header formats */ union ib_headers { struct ib_local_route_header lrh; struct { struct ib_local_route_header lrh; struct ib_global_route_header grh; struct ib_base_transport_header bth; struct ib_datagram_extended_transport_header deth; } __attribute__ (( packed )) lrh__grh__bth__deth; struct { struct ib_local_route_header lrh; struct ib_base_transport_header bth; struct ib_datagram_extended_transport_header deth; } __attribute__ (( packed )) lrh__bth__deth; } __attribute__ (( packed )); /** Maximum size required for IB headers */ #define IB_MAX_HEADER_SIZE sizeof ( union ib_headers ) extern int ib_push ( struct ib_device *ibdev, struct io_buffer *iobuf, struct ib_queue_pair *qp, size_t payload_len, const struct ib_address_vector *av ); extern int ib_pull ( struct ib_device *ibdev, struct io_buffer *iobuf, struct ib_queue_pair **qp, size_t *payload_len, struct ib_address_vector *av ); #endif /* _GPXE_IB_PACKET_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ip6.h0000664000000000000000000000355412524662415020207 0ustar #ifndef _GPXE_IP6_H #define _GPXE_IP6_H /** @file * * IP6 protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /* IP6 constants */ #define IP6_VERSION 0x6 #define IP6_HOP_LIMIT 255 /** * I/O buffer contents * This is duplicated in tcp.h and here. Ideally it should go into iobuf.h */ #define MAX_HDR_LEN 100 #define MAX_IOB_LEN 1500 #define MIN_IOB_LEN MAX_HDR_LEN + 100 /* To account for padding by LL */ #define IP6_EQUAL( in6_addr1, in6_addr2 ) \ ( memcmp ( ( char* ) &( in6_addr1 ), ( char* ) &( in6_addr2 ),\ sizeof ( struct in6_addr ) ) == 0 ) #define IS_UNSPECIFIED( addr ) \ ( ( (addr).in6_u.u6_addr32[0] == 0x00000000 ) && \ ( (addr).in6_u.u6_addr32[1] == 0x00000000 ) && \ ( (addr).in6_u.u6_addr32[2] == 0x00000000 ) && \ ( (addr).in6_u.u6_addr32[3] == 0x00000000 ) ) /* IP6 header */ struct ip6_header { uint32_t ver_traffic_class_flow_label; uint16_t payload_len; uint8_t nxt_hdr; uint8_t hop_limit; struct in6_addr src; struct in6_addr dest; }; /* IP6 pseudo header */ struct ipv6_pseudo_header { struct in6_addr src; struct in6_addr dest; uint8_t zero_padding; uint8_t nxt_hdr; uint16_t len; }; /* Next header numbers */ #define IP6_HOPBYHOP 0x00 #define IP6_ROUTING 0x43 #define IP6_FRAGMENT 0x44 #define IP6_AUTHENTICATION 0x51 #define IP6_DEST_OPTS 0x60 #define IP6_ESP 0x50 #define IP6_ICMP6 0x58 #define IP6_NO_HEADER 0x59 struct io_buffer; struct net_device; struct net_protocol; extern struct net_protocol ipv6_protocol; extern struct tcpip_net_protocol ipv6_tcpip_protocol; extern char * inet6_ntoa ( struct in6_addr in6 ); extern int add_ipv6_address ( struct net_device *netdev, struct in6_addr prefix, int prefix_len, struct in6_addr address, struct in6_addr gateway ); extern void del_ipv6_address ( struct net_device *netdev ); #endif /* _GPXE_IP6_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/gdbstub.h0000664000000000000000000000274312524662415021142 0ustar #ifndef _GPXE_GDBSTUB_H #define _GPXE_GDBSTUB_H /** @file * * GDB remote debugging * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include /** * A transport mechanism for the GDB protocol * */ struct gdb_transport { /** Transport name */ const char *name; /** * Set up the transport given a list of arguments * * @v argc Number of arguments * @v argv Argument list * @ret Return status code * * Note that arguments start at argv[0]. */ int ( * init ) ( int argc, char **argv ); /** * Perform a blocking read * * @v buf Buffer * @v len Size of buffer * @ret Number of bytes read into buffer */ size_t ( * recv ) ( char *buf, size_t len ); /** * Write, may block * * @v buf Buffer * @v len Size of buffer */ void ( * send ) ( const char *buf, size_t len ); }; #define GDB_TRANSPORTS __table ( struct gdb_transport, "gdb_transports" ) #define __gdb_transport __table_entry ( GDB_TRANSPORTS, 01 ) /** * Look up GDB transport by name * * @v name Name of transport * @ret GDB transport or NULL */ extern struct gdb_transport *find_gdb_transport ( const char *name ); /** * Break into the debugger using the given transport * * @v trans GDB transport */ extern void gdbstub_start ( struct gdb_transport *trans ); /** * Interrupt handler * * @signo POSIX signal number * @regs CPU register snapshot **/ extern void gdbstub_handler ( int signo, gdbreg_t *regs ); #endif /* _GPXE_GDBSTUB_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ipoib.h0000664000000000000000000000262512524662415020611 0ustar #ifndef _GPXE_IPOIB_H #define _GPXE_IPOIB_H /** @file * * IP over Infiniband */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** IPoIB MAC address length */ #define IPOIB_ALEN 20 /** An IPoIB MAC address */ struct ipoib_mac { /** Queue pair number * * MSB must be zero; QPNs are only 24-bit. */ uint32_t qpn; /** Port GID */ struct ib_gid gid; } __attribute__ (( packed )); /** IPoIB link-layer header length */ #define IPOIB_HLEN 4 /** IPoIB link-layer header */ struct ipoib_hdr { /** Network-layer protocol */ uint16_t proto; /** Reserved, must be zero */ union { /** Reserved, must be zero */ uint16_t reserved; /** Peer addresses * * We use these fields internally to represent the * peer addresses using a lookup key. There simply * isn't enough room in the IPoIB header to store * literal source or destination MAC addresses. */ struct { /** Destination address key */ uint8_t dest; /** Source address key */ uint8_t src; } __attribute__ (( packed )) peer; } __attribute__ (( packed )) u; } __attribute__ (( packed )); extern const char * ipoib_ntoa ( const void *ll_addr ); extern void ipoib_link_state_changed ( struct ib_device *ibdev ); extern int ipoib_probe ( struct ib_device *ibdev ); extern void ipoib_remove ( struct ib_device *ibdev ); extern struct net_device * alloc_ipoibdev ( size_t priv_size ); #endif /* _GPXE_IPOIB_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ip.h0000664000000000000000000000345712524662415020123 0ustar #ifndef _GPXE_IP_H #define _GPXE_IP_H /** @file * * IP protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include struct io_buffer; struct net_device; struct net_protocol; /* IP constants */ #define IP_VER 0x40U #define IP_MASK_VER 0xf0U #define IP_MASK_HLEN 0x0fU #define IP_MASK_OFFSET 0x1fffU #define IP_MASK_DONOTFRAG 0x4000U #define IP_MASK_MOREFRAGS 0x2000U #define IP_PSHLEN 12 /* IP header defaults */ #define IP_TOS 0 #define IP_TTL 64 #define IP_FRAG_IOB_SIZE 1500 #define IP_FRAG_TIMEOUT 50 /** An IPv4 packet header */ struct iphdr { uint8_t verhdrlen; uint8_t service; uint16_t len; uint16_t ident; uint16_t frags; uint8_t ttl; uint8_t protocol; uint16_t chksum; struct in_addr src; struct in_addr dest; } __attribute__ (( packed )); /** An IPv4 pseudo header */ struct ipv4_pseudo_header { struct in_addr src; struct in_addr dest; uint8_t zero_padding; uint8_t protocol; uint16_t len; }; /** An IPv4 address/routing table entry */ struct ipv4_miniroute { /** List of miniroutes */ struct list_head list; /** Network device */ struct net_device *netdev; /** IPv4 address */ struct in_addr address; /** Subnet mask */ struct in_addr netmask; /** Gateway address */ struct in_addr gateway; }; /* Fragment reassembly buffer */ struct frag_buffer { /* Identification number */ uint16_t ident; /* Source network address */ struct in_addr src; /* Destination network address */ struct in_addr dest; /* Reassembled I/O buffer */ struct io_buffer *frag_iob; /* Reassembly timer */ struct retry_timer frag_timer; /* List of fragment reassembly buffers */ struct list_head list; }; extern struct list_head ipv4_miniroutes; extern struct net_protocol ipv4_protocol; #endif /* _GPXE_IP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/nvs.h0000664000000000000000000000341012524662415020306 0ustar #ifndef _GPXE_NVS_H #define _GPXE_NVS_H /** @file * * Non-volatile storage * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** A non-volatile storage device */ struct nvs_device { /** Word length * * This is expressed as the base-2 logarithm of the word * length in bytes. A value of 0 therefore translates as * 8-bit words, and a value of 1 translates as 16-bit words. */ unsigned int word_len_log2; /** Device size (in words) */ unsigned int size; /** Data block size (in words) * * This is the block size used by the device. It must be a * power of two. Data reads and writes must not cross a block * boundary. * * Many devices allow reads to cross a block boundary, and * restrict only writes. For the sake of simplicity, we * assume that the same restriction applies to both reads and * writes. */ unsigned int block_size; /** Read data from device * * @v nvs NVS device * @v address Address from which to read * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code * * Reads may not cross a block boundary. */ int ( * read ) ( struct nvs_device *nvs, unsigned int address, void *data, size_t len ); /** Write data to device * * @v nvs NVS device * @v address Address to which to write * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code * * Writes may not cross a block boundary. */ int ( * write ) ( struct nvs_device *nvs, unsigned int address, const void *data, size_t len ); }; extern int nvs_read ( struct nvs_device *nvs, unsigned int address, void *data, size_t len ); extern int nvs_write ( struct nvs_device *nvs, unsigned int address, const void *data, size_t len ); #endif /* _GPXE_NVS_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/bitops.h0000664000000000000000000002014312524662415021002 0ustar #ifndef _GPXE_BITOPS_H #define _GPXE_BITOPS_H /* * Copyright (C) 2008 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); /** * @file * * Bit operations * */ #include #include /* Endianness selection. * * This is a property of the NIC, not a property of the host CPU. */ #ifdef BITOPS_LITTLE_ENDIAN #define cpu_to_BIT64 cpu_to_le64 #define cpu_to_BIT32 cpu_to_le32 #define BIT64_to_cpu le64_to_cpu #define BIT32_to_cpu le32_to_cpu #endif #ifdef BITOPS_BIG_ENDIAN #define cpu_to_BIT64 cpu_to_be64 #define cpu_to_BIT32 cpu_to_be32 #define BIT64_to_cpu be64_to_cpu #define BIT32_to_cpu be32_to_cpu #endif /** Datatype used to represent a bit in the pseudo-structures */ typedef unsigned char pseudo_bit_t; /** * Wrapper structure for pseudo_bit_t structures * * This structure provides a wrapper around pseudo_bit_t structures. * It has the correct size, and also encapsulates type information * about the underlying pseudo_bit_t-based structure, which allows the * BIT_FILL() etc. macros to work without requiring explicit type * information. */ #define PSEUDO_BIT_STRUCT( _structure ) \ union { \ uint8_t bytes[ sizeof ( _structure ) / 8 ]; \ uint32_t dwords[ sizeof ( _structure ) / 32 ]; \ uint64_t qwords[ sizeof ( _structure ) / 64 ]; \ _structure *dummy[0]; \ } u /** Get pseudo_bit_t structure type from wrapper structure pointer */ #define PSEUDO_BIT_STRUCT_TYPE( _ptr ) \ typeof ( *((_ptr)->u.dummy[0]) ) /** Bit offset of a field within a pseudo_bit_t structure */ #define BIT_OFFSET( _ptr, _field ) \ offsetof ( PSEUDO_BIT_STRUCT_TYPE ( _ptr ), _field ) /** Bit width of a field within a pseudo_bit_t structure */ #define BIT_WIDTH( _ptr, _field ) \ sizeof ( ( ( PSEUDO_BIT_STRUCT_TYPE ( _ptr ) * ) NULL )->_field ) /** Qword offset of a field within a pseudo_bit_t structure */ #define QWORD_OFFSET( _ptr, _field ) \ ( BIT_OFFSET ( _ptr, _field ) / 64 ) /** Qword bit offset of a field within a pseudo_bit_t structure */ #define QWORD_BIT_OFFSET( _ptr, _index, _field ) \ ( BIT_OFFSET ( _ptr, _field ) - ( 64 * (_index) ) ) /** Bit mask for a field within a pseudo_bit_t structure */ #define BIT_MASK( _ptr, _field ) \ ( ( ~( ( uint64_t ) 0 ) ) >> \ ( 64 - BIT_WIDTH ( _ptr, _field ) ) ) /* * Assemble native-endian qword from named fields and values * */ #define BIT_ASSEMBLE_1( _ptr, _index, _field, _value ) \ ( ( ( uint64_t) (_value) ) << \ QWORD_BIT_OFFSET ( _ptr, _index, _field ) ) #define BIT_ASSEMBLE_2( _ptr, _index, _field, _value, ... ) \ ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \ BIT_ASSEMBLE_1 ( _ptr, _index, __VA_ARGS__ ) ) #define BIT_ASSEMBLE_3( _ptr, _index, _field, _value, ... ) \ ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \ BIT_ASSEMBLE_2 ( _ptr, _index, __VA_ARGS__ ) ) #define BIT_ASSEMBLE_4( _ptr, _index, _field, _value, ... ) \ ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \ BIT_ASSEMBLE_3 ( _ptr, _index, __VA_ARGS__ ) ) #define BIT_ASSEMBLE_5( _ptr, _index, _field, _value, ... ) \ ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \ BIT_ASSEMBLE_4 ( _ptr, _index, __VA_ARGS__ ) ) #define BIT_ASSEMBLE_6( _ptr, _index, _field, _value, ... ) \ ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \ BIT_ASSEMBLE_5 ( _ptr, _index, __VA_ARGS__ ) ) #define BIT_ASSEMBLE_7( _ptr, _index, _field, _value, ... ) \ ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \ BIT_ASSEMBLE_6 ( _ptr, _index, __VA_ARGS__ ) ) /* * Build native-endian (positive) qword bitmasks from named fields * */ #define BIT_MASK_1( _ptr, _index, _field ) \ ( BIT_MASK ( _ptr, _field ) << \ QWORD_BIT_OFFSET ( _ptr, _index, _field ) ) #define BIT_MASK_2( _ptr, _index, _field, ... ) \ ( BIT_MASK_1 ( _ptr, _index, _field ) | \ BIT_MASK_1 ( _ptr, _index, __VA_ARGS__ ) ) #define BIT_MASK_3( _ptr, _index, _field, ... ) \ ( BIT_MASK_1 ( _ptr, _index, _field ) | \ BIT_MASK_2 ( _ptr, _index, __VA_ARGS__ ) ) #define BIT_MASK_4( _ptr, _index, _field, ... ) \ ( BIT_MASK_1 ( _ptr, _index, _field ) | \ BIT_MASK_3 ( _ptr, _index, __VA_ARGS__ ) ) #define BIT_MASK_5( _ptr, _index, _field, ... ) \ ( BIT_MASK_1 ( _ptr, _index, _field ) | \ BIT_MASK_4 ( _ptr, _index, __VA_ARGS__ ) ) #define BIT_MASK_6( _ptr, _index, _field, ... ) \ ( BIT_MASK_1 ( _ptr, _index, _field ) | \ BIT_MASK_5 ( _ptr, _index, __VA_ARGS__ ) ) #define BIT_MASK_7( _ptr, _index, _field, ... ) \ ( BIT_MASK_1 ( _ptr, _index, _field ) | \ BIT_MASK_6 ( _ptr, _index, __VA_ARGS__ ) ) /* * Populate little-endian qwords from named fields and values * */ #define BIT_FILL( _ptr, _index, _assembled ) do { \ uint64_t *__ptr = &(_ptr)->u.qwords[(_index)]; \ uint64_t __assembled = (_assembled); \ *__ptr = cpu_to_BIT64 ( __assembled ); \ } while ( 0 ) #define BIT_FILL_1( _ptr, _field1, ... ) \ BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ BIT_ASSEMBLE_1 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ _field1, __VA_ARGS__ ) ) #define BIT_FILL_2( _ptr, _field1, ... ) \ BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ BIT_ASSEMBLE_2 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ _field1, __VA_ARGS__ ) ) #define BIT_FILL_3( _ptr, _field1, ... ) \ BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ BIT_ASSEMBLE_3 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ _field1, __VA_ARGS__ ) ) #define BIT_FILL_4( _ptr, _field1, ... ) \ BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ BIT_ASSEMBLE_4 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ _field1, __VA_ARGS__ ) ) #define BIT_FILL_5( _ptr, _field1, ... ) \ BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ BIT_ASSEMBLE_5 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ _field1, __VA_ARGS__ ) ) #define BIT_FILL_6( _ptr, _field1, ... ) \ BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ BIT_ASSEMBLE_6 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \ _field1, __VA_ARGS__ ) ) /** Extract value of named field */ #define BIT_GET64( _ptr, _field ) \ ( { \ unsigned int __index = QWORD_OFFSET ( _ptr, _field ); \ uint64_t *__ptr = &(_ptr)->u.qwords[__index]; \ uint64_t __value = BIT64_to_cpu ( *__ptr ); \ __value >>= \ QWORD_BIT_OFFSET ( _ptr, __index, _field ); \ __value &= BIT_MASK ( _ptr, _field ); \ __value; \ } ) /** Extract value of named field (for fields up to the size of a long) */ #define BIT_GET( _ptr, _field ) \ ( ( unsigned long ) BIT_GET64 ( _ptr, _field ) ) #define BIT_SET( _ptr, _field, _value ) do { \ unsigned int __index = QWORD_OFFSET ( _ptr, _field ); \ uint64_t *__ptr = &(_ptr)->u.qwords[__index]; \ unsigned int __shift = \ QWORD_BIT_OFFSET ( _ptr, __index, _field ); \ uint64_t __value = (_value); \ *__ptr &= cpu_to_BIT64 ( ~( BIT_MASK ( _ptr, _field ) << \ __shift ) ); \ *__ptr |= cpu_to_BIT64 ( __value << __shift ); \ } while ( 0 ) #endif /* _GPXE_BITOPS_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/gdbserial.h0000664000000000000000000000055212524662415021440 0ustar #ifndef _GPXE_GDBSERIAL_H #define _GPXE_GDBSERIAL_H /** @file * * GDB remote debugging over serial * */ FILE_LICENCE ( GPL2_OR_LATER ); struct gdb_transport; /** * Set up the serial transport * * @ret transport suitable for starting the GDB stub or NULL on error */ struct gdb_transport *gdbserial_configure ( void ); #endif /* _GPXE_GDBSERIAL_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/tls.h0000664000000000000000000001041412524662415020304 0ustar #ifndef _GPXE_TLS_H #define _GPXE_TLS_H /** * @file * * Transport Layer Security Protocol */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include /** A TLS header */ struct tls_header { /** Content type * * This is a TLS_TYPE_XXX constant */ uint8_t type; /** Protocol version * * This is a TLS_VERSION_XXX constant */ uint16_t version; /** Length of payload */ uint16_t length; } __attribute__ (( packed )); /** TLS version 1.0 */ #define TLS_VERSION_TLS_1_0 0x0301 /** TLS version 1.1 */ #define TLS_VERSION_TLS_1_1 0x0302 /** Change cipher content type */ #define TLS_TYPE_CHANGE_CIPHER 20 /** Alert content type */ #define TLS_TYPE_ALERT 21 /** Handshake content type */ #define TLS_TYPE_HANDSHAKE 22 /** Application data content type */ #define TLS_TYPE_DATA 23 /* Handshake message types */ #define TLS_HELLO_REQUEST 0 #define TLS_CLIENT_HELLO 1 #define TLS_SERVER_HELLO 2 #define TLS_CERTIFICATE 11 #define TLS_SERVER_KEY_EXCHANGE 12 #define TLS_CERTIFICATE_REQUEST 13 #define TLS_SERVER_HELLO_DONE 14 #define TLS_CERTIFICATE_VERIFY 15 #define TLS_CLIENT_KEY_EXCHANGE 16 #define TLS_FINISHED 20 /* TLS alert levels */ #define TLS_ALERT_WARNING 1 #define TLS_ALERT_FATAL 2 /* TLS cipher specifications */ #define TLS_RSA_WITH_NULL_MD5 0x0001 #define TLS_RSA_WITH_NULL_SHA 0x0002 #define TLS_RSA_WITH_AES_128_CBC_SHA 0x002f #define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 /** TLS RX state machine state */ enum tls_rx_state { TLS_RX_HEADER = 0, TLS_RX_DATA, }; /** TLS TX state machine state */ enum tls_tx_state { TLS_TX_NONE = 0, TLS_TX_CLIENT_HELLO, TLS_TX_CLIENT_KEY_EXCHANGE, TLS_TX_CHANGE_CIPHER, TLS_TX_FINISHED, TLS_TX_DATA }; /** A TLS cipher specification */ struct tls_cipherspec { /** Public-key encryption algorithm */ struct pubkey_algorithm *pubkey; /** Bulk encryption cipher algorithm */ struct cipher_algorithm *cipher; /** MAC digest algorithm */ struct digest_algorithm *digest; /** Key length */ size_t key_len; /** Dynamically-allocated storage */ void *dynamic; /** Public key encryption context */ void *pubkey_ctx; /** Bulk encryption cipher context */ void *cipher_ctx; /** Next bulk encryption cipher context (TX only) */ void *cipher_next_ctx; /** MAC secret */ void *mac_secret; }; /** TLS pre-master secret */ struct tls_pre_master_secret { /** TLS version */ uint16_t version; /** Random data */ uint8_t random[46]; } __attribute__ (( packed )); /** TLS client random data */ struct tls_client_random { /** GMT Unix time */ uint32_t gmt_unix_time; /** Random data */ uint8_t random[28]; } __attribute__ (( packed )); /** A TLS session */ struct tls_session { /** Reference counter */ struct refcnt refcnt; /** Plaintext stream */ struct xfer_filter_half plainstream; /** Ciphertext stream */ struct xfer_filter_half cipherstream; /** Current TX cipher specification */ struct tls_cipherspec tx_cipherspec; /** Next TX cipher specification */ struct tls_cipherspec tx_cipherspec_pending; /** Current RX cipher specification */ struct tls_cipherspec rx_cipherspec; /** Next RX cipher specification */ struct tls_cipherspec rx_cipherspec_pending; /** Premaster secret */ struct tls_pre_master_secret pre_master_secret; /** Master secret */ uint8_t master_secret[48]; /** Server random bytes */ uint8_t server_random[32]; /** Client random bytes */ struct tls_client_random client_random; /** MD5 context for handshake verification */ uint8_t handshake_md5_ctx[MD5_CTX_SIZE]; /** SHA1 context for handshake verification */ uint8_t handshake_sha1_ctx[SHA1_CTX_SIZE]; /** Hack: server RSA public key */ struct x509_rsa_public_key rsa; /** TX sequence number */ uint64_t tx_seq; /** TX state */ enum tls_tx_state tx_state; /** TX process */ struct process process; /** RX sequence number */ uint64_t rx_seq; /** RX state */ enum tls_rx_state rx_state; /** Offset within current RX state */ size_t rx_rcvd; /** Current received record header */ struct tls_header rx_header; /** Current received raw data buffer */ void *rx_data; }; extern int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ); #endif /* _GPXE_TLS_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/socket.h0000664000000000000000000000407612524662415021001 0ustar #ifndef _GPXE_SOCKET_H #define _GPXE_SOCKET_H /** @file * * Socket addresses * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** * @defgroup commtypes Communication semantics * * @{ */ /** Connection-based, reliable streams */ extern int tcp_sock_stream; #define TCP_SOCK_STREAM 0x1 #define SOCK_STREAM tcp_sock_stream /** Connectionless, unreliable streams */ extern int udp_sock_dgram; #define UDP_SOCK_DGRAM 0x2 #define SOCK_DGRAM udp_sock_dgram /** @} */ /** * Name communication semantics * * @v semantics Communication semantics (e.g. SOCK_STREAM) * @ret name Name of communication semantics */ static inline __attribute__ (( always_inline )) const char * socket_semantics_name ( int semantics ) { /* Cannot use a switch() because of the {TCP_UDP}_SOCK_XXX hack */ if ( semantics == SOCK_STREAM ) { return "SOCK_STREAM"; } else if ( semantics == SOCK_DGRAM ) { return "SOCK_DGRAM"; } else { return "SOCK_UNKNOWN"; } } /** * @defgroup addrfam Address families * * @{ */ #define AF_INET 1 /**< IPv4 Internet addresses */ #define AF_INET6 2 /**< IPv6 Internet addresses */ /** @} */ /** * Name address family * * @v family Address family (e.g. AF_INET) * @ret name Name of address family */ static inline __attribute__ (( always_inline )) const char * socket_family_name ( int family ) { switch ( family ) { case AF_INET: return "AF_INET"; case AF_INET6: return "AF_INET6"; default: return "AF_UNKNOWN"; } } /** A socket address family */ typedef uint16_t sa_family_t; /** Length of a @c struct @c sockaddr */ #define SA_LEN 32 /** * Generalized socket address structure * * This contains the fields common to socket addresses for all address * families. */ struct sockaddr { /** Socket address family * * This is an AF_XXX constant. */ sa_family_t sa_family; /** Padding * * This ensures that a struct @c sockaddr_tcpip is large * enough to hold a socket address for any TCP/IP address * family. */ char pad[ SA_LEN - sizeof ( sa_family_t ) ]; } __attribute__ (( may_alias )); #endif /* _GPXE_SOCKET_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/cpio.h0000664000000000000000000000224312524662415020435 0ustar #ifndef _GPXE_CPIO_H #define _GPXE_CPIO_H /** @file * * CPIO archives * */ FILE_LICENCE ( GPL2_OR_LATER ); /** A CPIO archive header * * All field are hexadecimal ASCII numbers padded with '0' on the * left to the full width of the field. */ struct cpio_header { /** The string "070701" or "070702" */ char c_magic[6]; /** File inode number */ char c_ino[8]; /** File mode and permissions */ char c_mode[8]; /** File uid */ char c_uid[8]; /** File gid */ char c_gid[8]; /** Number of links */ char c_nlink[8]; /** Modification time */ char c_mtime[8]; /** Size of data field */ char c_filesize[8]; /** Major part of file device number */ char c_maj[8]; /** Minor part of file device number */ char c_min[8]; /** Major part of device node reference */ char c_rmaj[8]; /** Minor part of device node reference */ char c_rmin[8]; /** Length of filename, including final NUL */ char c_namesize[8]; /** Checksum of data field if c_magic is 070702, othersize zero */ char c_chksum[8]; } __attribute__ (( packed )); /** CPIO magic */ #define CPIO_MAGIC "070701" extern void cpio_set_field ( char *field, unsigned long value ); #endif /* _GPXE_CPIO_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/smbios.h0000664000000000000000000000737712524662415021014 0ustar #ifndef _GPXE_SMBIOS_H #define _GPXE_SMBIOS_H /** @file * * System Management BIOS * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include /** * Provide an SMBIOS API implementation * * @v _prefix Subsystem prefix * @v _api_func API function * @v _func Implementing function */ #define PROVIDE_SMBIOS( _subsys, _api_func, _func ) \ PROVIDE_SINGLE_API ( SMBIOS_PREFIX_ ## _subsys, _api_func, _func ) /* Include all architecture-independent SMBIOS API headers */ #include /* Include all architecture-dependent SMBIOS API headers */ #include /** Signature for SMBIOS entry point */ #define SMBIOS_SIGNATURE \ ( ( '_' << 0 ) + ( 'S' << 8 ) + ( 'M' << 16 ) + ( '_' << 24 ) ) /** * SMBIOS entry point * * This is the single table which describes the list of SMBIOS * structures. It is located by scanning through the BIOS segment. */ struct smbios_entry { /** Signature * * Must be equal to SMBIOS_SIGNATURE */ uint32_t signature; /** Checksum */ uint8_t checksum; /** Length */ uint8_t len; /** Major version */ uint8_t major; /** Minor version */ uint8_t minor; /** Maximum structure size */ uint16_t max; /** Entry point revision */ uint8_t revision; /** Formatted area */ uint8_t formatted[5]; /** DMI Signature */ uint8_t dmi_signature[5]; /** DMI checksum */ uint8_t dmi_checksum; /** Structure table length */ uint16_t smbios_len; /** Structure table address */ uint32_t smbios_address; /** Number of SMBIOS structures */ uint16_t smbios_count; /** BCD revision */ uint8_t bcd_revision; } __attribute__ (( packed )); /** An SMBIOS structure header */ struct smbios_header { /** Type */ uint8_t type; /** Length */ uint8_t len; /** Handle */ uint16_t handle; } __attribute__ (( packed )); /** SMBIOS structure descriptor */ struct smbios_structure { /** Copy of SMBIOS structure header */ struct smbios_header header; /** Offset of structure within SMBIOS */ size_t offset; /** Length of strings section */ size_t strings_len; }; /** SMBIOS system information structure */ struct smbios_system_information { /** SMBIOS structure header */ struct smbios_header header; /** Manufacturer string */ uint8_t manufacturer; /** Product string */ uint8_t product; /** Version string */ uint8_t version; /** Serial number string */ uint8_t serial; /** UUID */ uint8_t uuid[16]; /** Wake-up type */ uint8_t wakeup; } __attribute__ (( packed )); /** SMBIOS system information structure type */ #define SMBIOS_TYPE_SYSTEM_INFORMATION 1 /** SMBIOS enclosure information structure */ struct smbios_enclosure_information { /** SMBIOS structure header */ struct smbios_header header; /** Manufacturer string */ uint8_t manufacturer; /** Type string */ uint8_t type; /** Version string */ uint8_t version; /** Serial number string */ uint8_t serial; /** Asset tag */ uint8_t asset_tag; } __attribute__ (( packed )); /** SMBIOS enclosure information structure type */ #define SMBIOS_TYPE_ENCLOSURE_INFORMATION 3 /** * SMBIOS entry point descriptor * * This contains the information from the SMBIOS entry point that we * care about. */ struct smbios { /** Start of SMBIOS structures */ userptr_t address; /** Length of SMBIOS structures */ size_t len; /** Number of SMBIOS structures */ unsigned int count; }; extern int find_smbios ( struct smbios *smbios ); extern int find_smbios_structure ( unsigned int type, struct smbios_structure *structure ); extern int read_smbios_structure ( struct smbios_structure *structure, void *data, size_t len ); extern int read_smbios_string ( struct smbios_structure *structure, unsigned int index, void *data, size_t len ); #endif /* _GPXE_SMBIOS_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/threewire.h0000664000000000000000000000532112524662415021501 0ustar #ifndef _GPXE_THREEWIRE_H #define _GPXE_THREEWIRE_H /** @file * * Three-wire serial interface * * The Atmel three-wire interface is a subset of the (newer) SPI * interface, and is implemented here as a layer on top of the SPI * support. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** * @defgroup tcmds Three-wire commands * @{ */ /** Read data from memory array */ #define THREEWIRE_READ 0x6 /** Write data to memory array */ #define THREEWIRE_WRITE 0x5 /** Write enable */ #define THREEWIRE_EWEN 0x4 /** Address to be used for write enable command */ #define THREEWIRE_EWEN_ADDRESS INT_MAX /** Time to wait for write cycles to complete * * This is sufficient for AT93C46/AT93C56 devices, but may need to be * increased in future when other devices are added. */ #define THREEWIRE_WRITE_MDELAY 10 /** @} */ extern int threewire_read ( struct nvs_device *nvs, unsigned int address, void *data, size_t len ); extern int threewire_write ( struct nvs_device *nvs, unsigned int address, const void *data, size_t len ); extern int threewire_detect_address_len ( struct spi_device *device ); /** * @defgroup tdevs Three-wire device types * @{ */ static inline __attribute__ (( always_inline )) void init_at93cx6 ( struct spi_device *device, unsigned int organisation ) { device->nvs.word_len_log2 = ( ( organisation == 8 ) ? 0 : 1 ); device->nvs.block_size = 1; device->command_len = 3, device->nvs.read = threewire_read; device->nvs.write = threewire_write; } /** * Initialise Atmel AT93C46 serial EEPROM * * @v device SPI device * @v organisation Word organisation (8 or 16) */ static inline __attribute__ (( always_inline )) void init_at93c46 ( struct spi_device *device, unsigned int organisation ) { device->nvs.size = ( 1024 / organisation ); device->address_len = ( ( organisation == 8 ) ? 7 : 6 ); init_at93cx6 ( device, organisation ); } /** * Initialise Atmel AT93C56 serial EEPROM * * @v device SPI device * @v organisation Word organisation (8 or 16) */ static inline __attribute__ (( always_inline )) void init_at93c56 ( struct spi_device *device, unsigned int organisation ) { device->nvs.size = ( 2048 / organisation ); device->address_len = ( ( organisation == 8 ) ? 9 : 8 ); init_at93cx6 ( device, organisation ); } /** * Initialise Atmel AT93C66 serial EEPROM * * @v device SPI device * @v organisation Word organisation (8 or 16) */ static inline __attribute__ (( always_inline )) void init_at93c66 ( struct spi_device *device, unsigned int organisation ) { device->nvs.size = ( 4096 / organisation ); device->address_len = ( ( organisation == 8 ) ? 9 : 8 ); init_at93cx6 ( device, organisation ); } /** @} */ #endif /* _GPXE_THREEWIRE_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/command.h0000664000000000000000000000101412524662415021114 0ustar #ifndef _GPXE_COMMAND_H #define _GPXE_COMMAND_H FILE_LICENCE ( GPL2_OR_LATER ); #include /** A command-line command */ struct command { /** Name of the command */ const char *name; /** * Function implementing the command * * @v argc Argument count * @v argv Argument list * @ret rc Return status code */ int ( * exec ) ( int argc, char **argv ); }; #define COMMANDS __table ( struct command, "commands" ) #define __command __table_entry ( COMMANDS, 01 ) #endif /* _GPXE_COMMAND_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/open.h0000664000000000000000000000477212524662415020455 0ustar #ifndef _GPXE_OPEN_H #define _GPXE_OPEN_H /** @file * * Data transfer interface opening * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include struct xfer_interface; struct uri; /** Location types */ enum { /** Location is a URI * * Parameter list for open() is: * * struct uri *uri; */ LOCATION_URI = 1, /** Location is a URI string * * Parameter list for open() is: * * const char *uri_string; */ LOCATION_URI_STRING, /** Location is a socket * * Parameter list for open() is: * * int semantics; * struct sockaddr *peer; * struct sockaddr *local; */ LOCATION_SOCKET, }; /** A URI opener */ struct uri_opener { /** URI protocol name * * This is the "scheme" portion of the URI, e.g. "http" or * "file". */ const char *scheme; /** Open URI * * @v xfer Data transfer interface * @v uri URI * @ret rc Return status code */ int ( * open ) ( struct xfer_interface *xfer, struct uri *uri ); }; /** URI opener table */ #define URI_OPENERS __table ( struct uri_opener, "uri_openers" ) /** Register a URI opener */ #define __uri_opener __table_entry ( URI_OPENERS, 01 ) /** A socket opener */ struct socket_opener { /** Communication semantics (e.g. SOCK_STREAM) */ int semantics; /** Address family (e.g. AF_INET) */ int family; /** Open socket * * @v xfer Data transfer interface * @v peer Peer socket address * @v local Local socket address, or NULL * @ret rc Return status code */ int ( * open ) ( struct xfer_interface *xfer, struct sockaddr *peer, struct sockaddr *local ); }; /** Socket opener table */ #define SOCKET_OPENERS __table ( struct socket_opener, "socket_openers" ) /** Register a socket opener */ #define __socket_opener __table_entry ( SOCKET_OPENERS, 01 ) extern int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ); extern int xfer_open_uri_string ( struct xfer_interface *xfer, const char *uri_string ); extern int xfer_open_named_socket ( struct xfer_interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local ); extern int xfer_open_socket ( struct xfer_interface *xfer, int semantics, struct sockaddr *peer, struct sockaddr *local ); extern int xfer_vopen ( struct xfer_interface *xfer, int type, va_list args ); extern int xfer_open ( struct xfer_interface *xfer, int type, ... ); extern int xfer_vreopen ( struct xfer_interface *xfer, int type, va_list args ); #endif /* _GPXE_OPEN_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/eisa.h0000664000000000000000000000507012524662415020425 0ustar #ifndef EISA_H #define EISA_H FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include /* * EISA constants * */ #define EISA_MIN_SLOT (0x1) #define EISA_MAX_SLOT (0xf) /* Must be 2^n - 1 */ #define EISA_SLOT_BASE( n ) ( 0x1000 * (n) ) #define EISA_VENDOR_ID ( 0xc80 ) #define EISA_PROD_ID ( 0xc82 ) #define EISA_GLOBAL_CONFIG ( 0xc84 ) #define EISA_CMD_RESET ( 1 << 2 ) #define EISA_CMD_ENABLE ( 1 << 0 ) /** An EISA device ID list entry */ struct eisa_device_id { /** Name */ const char *name; /** Manufacturer ID */ uint16_t vendor_id; /** Product ID */ uint16_t prod_id; }; /** An EISA device */ struct eisa_device { /** Generic device */ struct device dev; /** Slot number */ unsigned int slot; /** I/O address */ uint16_t ioaddr; /** Manufacturer ID */ uint16_t vendor_id; /** Product ID */ uint16_t prod_id; /** Driver for this device */ struct eisa_driver *driver; /** Driver-private data * * Use eisa_set_drvdata() and eisa_get_drvdata() to access * this field. */ void *priv; /** Driver name */ const char *driver_name; }; /** An EISA driver */ struct eisa_driver { /** EISA ID table */ struct eisa_device_id *ids; /** Number of entries in EISA ID table */ unsigned int id_count; /** * Probe device * * @v eisa EISA device * @v id Matching entry in ID table * @ret rc Return status code */ int ( * probe ) ( struct eisa_device *eisa, const struct eisa_device_id *id ); /** * Remove device * * @v eisa EISA device */ void ( * remove ) ( struct eisa_device *eisa ); }; /** EISA driver table */ #define EISA_DRIVERS __table ( struct eisa_driver, "eisa_drivers" ) /** Declare an EISA driver */ #define __eisa_driver __table_entry ( EISA_DRIVERS, 01 ) extern void eisa_device_enabled ( struct eisa_device *eisa, int enabled ); /** * Enable EISA device * * @v eisa EISA device */ static inline void enable_eisa_device ( struct eisa_device *eisa ) { eisa_device_enabled ( eisa, 1 ); } /** * Disable EISA device * * @v eisa EISA device */ static inline void disable_eisa_device ( struct eisa_device *eisa ) { eisa_device_enabled ( eisa, 0 ); } /** * Set EISA driver-private data * * @v eisa EISA device * @v priv Private data */ static inline void eisa_set_drvdata ( struct eisa_device *eisa, void *priv ) { eisa->priv = priv; } /** * Get EISA driver-private data * * @v eisa EISA device * @ret priv Private data */ static inline void * eisa_get_drvdata ( struct eisa_device *eisa ) { return eisa->priv; } #endif /* EISA_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/settings.h0000664000000000000000000002341312524662415021345 0ustar #ifndef _GPXE_SETTINGS_H #define _GPXE_SETTINGS_H /** @file * * Configuration settings * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include struct settings; struct in_addr; union uuid; /** A setting */ struct setting { /** Name * * This is the human-readable name for the setting. */ const char *name; /** Description */ const char *description; /** Setting type * * This identifies the type of setting (e.g. string, IPv4 * address, etc.). */ struct setting_type *type; /** DHCP option number, if applicable */ unsigned int tag; }; /** Configuration setting table */ #define SETTINGS __table ( struct setting, "settings" ) /** Declare a configuration setting */ #define __setting __table_entry ( SETTINGS, 01 ) /** Settings block operations */ struct settings_operations { /** Store value of setting * * @v settings Settings block * @v setting Setting to store * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ int ( * store ) ( struct settings *settings, struct setting *setting, const void *data, size_t len ); /** Fetch value of setting * * @v settings Settings block * @v setting Setting to fetch * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error * * The actual length of the setting will be returned even if * the buffer was too small. */ int ( * fetch ) ( struct settings *settings, struct setting *setting, void *data, size_t len ); /** Clear settings block * * @v settings Settings block */ void ( * clear ) ( struct settings *settings ); }; /** A settings block */ struct settings { /** Reference counter */ struct refcnt *refcnt; /** Name */ const char *name; /** Tag magic * * This value will be ORed in to any numerical tags * constructed by parse_setting_name(), and can be used to * avoid e.g. attempting to retrieve the subnet mask from * SMBIOS, or the system UUID from DHCP. */ unsigned int tag_magic; /** Parent settings block */ struct settings *parent; /** Sibling settings blocks */ struct list_head siblings; /** Child settings blocks */ struct list_head children; /** Settings block operations */ struct settings_operations *op; }; /** * A setting type * * This represents a type of setting (e.g. string, IPv4 address, * etc.). */ struct setting_type { /** Name * * This is the name exposed to the user (e.g. "string"). */ const char *name; /** Parse and set value of setting * * @v settings Settings block * @v setting Setting to store * @v value Formatted setting data * @ret rc Return status code */ int ( * storef ) ( struct settings *settings, struct setting *setting, const char *value ); /** Fetch and format value of setting * * @v settings Settings block * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ int ( * fetchf ) ( struct settings *settings, struct setting *setting, char *buf, size_t len ); }; /** Configuration setting type table */ #define SETTING_TYPES __table ( struct setting_type, "setting_types" ) /** Declare a configuration setting type */ #define __setting_type __table_entry ( SETTING_TYPES, 01 ) /** * A settings applicator * */ struct settings_applicator { /** Apply updated settings * * @ret rc Return status code */ int ( * apply ) ( void ); }; /** Settings applicator table */ #define SETTINGS_APPLICATORS \ __table ( struct settings_applicator, "settings_applicators" ) /** Declare a settings applicator */ #define __settings_applicator __table_entry ( SETTINGS_APPLICATORS, 01 ) /** * A generic settings block * */ struct generic_settings { /** Settings block */ struct settings settings; /** List of generic settings */ struct list_head list; }; extern struct settings_operations generic_settings_operations; extern int generic_settings_store ( struct settings *settings, struct setting *setting, const void *data, size_t len ); extern int generic_settings_fetch ( struct settings *settings, struct setting *setting, void *data, size_t len ); extern void generic_settings_clear ( struct settings *settings ); extern int register_settings ( struct settings *settings, struct settings *parent ); extern void unregister_settings ( struct settings *settings ); extern int store_setting ( struct settings *settings, struct setting *setting, const void *data, size_t len ); extern int fetch_setting ( struct settings *settings, struct setting *setting, void *data, size_t len ); extern int fetch_setting_len ( struct settings *settings, struct setting *setting ); extern int fetch_string_setting ( struct settings *settings, struct setting *setting, char *data, size_t len ); extern int fetch_string_setting_copy ( struct settings *settings, struct setting *setting, char **data ); extern int fetch_ipv4_setting ( struct settings *settings, struct setting *setting, struct in_addr *inp ); extern int fetch_int_setting ( struct settings *settings, struct setting *setting, long *value ); extern int fetch_uint_setting ( struct settings *settings, struct setting *setting, unsigned long *value ); extern long fetch_intz_setting ( struct settings *settings, struct setting *setting ); extern unsigned long fetch_uintz_setting ( struct settings *settings, struct setting *setting ); extern int fetch_uuid_setting ( struct settings *settings, struct setting *setting, union uuid *uuid ); extern void clear_settings ( struct settings *settings ); extern int setting_cmp ( struct setting *a, struct setting *b ); extern struct settings * find_settings ( const char *name ); extern int storef_setting ( struct settings *settings, struct setting *setting, const char *value ); extern int storef_named_setting ( const char *name, const char *value ); extern int fetchf_named_setting ( const char *name, char *buf, size_t len ); extern struct setting_type setting_type_string __setting_type; extern struct setting_type setting_type_ipv4 __setting_type; extern struct setting_type setting_type_int8 __setting_type; extern struct setting_type setting_type_int16 __setting_type; extern struct setting_type setting_type_int32 __setting_type; extern struct setting_type setting_type_uint8 __setting_type; extern struct setting_type setting_type_uint16 __setting_type; extern struct setting_type setting_type_uint32 __setting_type; extern struct setting_type setting_type_hex __setting_type; extern struct setting_type setting_type_uuid __setting_type; extern struct setting ip_setting __setting; extern struct setting netmask_setting __setting; extern struct setting gateway_setting __setting; extern struct setting dns_setting __setting; extern struct setting domain_setting __setting; extern struct setting hostname_setting __setting; extern struct setting filename_setting __setting; extern struct setting root_path_setting __setting; extern struct setting username_setting __setting; extern struct setting password_setting __setting; extern struct setting priority_setting __setting; extern struct setting uuid_setting __setting; extern struct setting next_server_setting __setting; extern struct setting mac_setting __setting; extern struct setting user_class_setting __setting; /** * Initialise a settings block * * @v settings Settings block * @v op Settings block operations * @v refcnt Containing object reference counter, or NULL * @v name Settings block name * @v tag_magic Tag magic */ static inline void settings_init ( struct settings *settings, struct settings_operations *op, struct refcnt *refcnt, const char *name, unsigned int tag_magic ) { INIT_LIST_HEAD ( &settings->siblings ); INIT_LIST_HEAD ( &settings->children ); settings->op = op; settings->refcnt = refcnt; settings->name = name; settings->tag_magic = tag_magic; } /** * Initialise a settings block * * @v generics Generic settings block * @v refcnt Containing object reference counter, or NULL * @v name Settings block name */ static inline void generic_settings_init ( struct generic_settings *generics, struct refcnt *refcnt, const char *name ) { settings_init ( &generics->settings, &generic_settings_operations, refcnt, name, 0 ); INIT_LIST_HEAD ( &generics->list ); } /** * Delete setting * * @v settings Settings block * @v setting Setting to delete * @ret rc Return status code */ static inline int delete_setting ( struct settings *settings, struct setting *setting ) { return store_setting ( settings, setting, NULL, 0 ); } /** * Fetch and format value of setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v type Settings type * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ static inline int fetchf_setting ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { return setting->type->fetchf ( settings, setting, buf, len ); } /** * Delete named setting * * @v name Name of setting * @ret rc Return status code */ static inline int delete_named_setting ( const char *name ) { return storef_named_setting ( name, NULL ); } /** * Check existence of setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @ret exists Setting exists */ static inline int setting_exists ( struct settings *settings, struct setting *setting ) { return ( fetch_setting_len ( settings, setting ) >= 0 ); } #endif /* _GPXE_SETTINGS_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/image.h0000664000000000000000000001152712524662415020572 0ustar #ifndef _GPXE_IMAGE_H #define _GPXE_IMAGE_H /** * @file * * Executable/loadable images * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include struct uri; struct image_type; /** An executable or loadable image */ struct image { /** Reference count */ struct refcnt refcnt; /** List of registered images */ struct list_head list; /** URI of image */ struct uri *uri; /** Name */ char name[16]; /** Flags */ unsigned int flags; /** Command line to pass to image */ char *cmdline; /** Raw file image */ userptr_t data; /** Length of raw file image */ size_t len; /** Image type, if known */ struct image_type *type; /** Image type private data */ union { physaddr_t phys; userptr_t user; unsigned long ul; } priv; /** Replacement image * * An image wishing to replace itself with another image (in a * style similar to a Unix exec() call) should return from its * exec() method with the replacement image set to point to * the new image. The new image must already be in a suitable * state for execution (i.e. loaded). * * If an image unregisters itself as a result of being * executed, it must make sure that its replacement image (if * any) is registered, otherwise the replacement is likely to * be freed before it can be executed. */ struct image *replacement; }; /** Image is loaded */ #define IMAGE_LOADED 0x0001 /** An executable or loadable image type */ struct image_type { /** Name of this image type */ char *name; /** * Load image into memory * * @v image Executable/loadable image * @ret rc Return status code * * Load the image into memory at the correct location as * determined by the file format. * * If the file image is in the correct format, the method must * update @c image->type to point to its own type (unless @c * image->type is already set). This allows the autoloading * code to disambiguate between "this is not my image format" * and "there is something wrong with this image". In * particular, setting @c image->type and then returning an * error will cause image_autoload() to abort and return an * error, rather than continuing to the next image type. */ int ( * load ) ( struct image *image ); /** * Execute loaded image * * @v image Loaded image * @ret rc Return status code * * Note that the image may be invalidated by the act of * execution, i.e. an image is allowed to choose to unregister * (and so potentially free) itself. */ int ( * exec ) ( struct image *image ); }; /** * Multiboot image probe priority * * Multiboot images are also valid executables in another format * (e.g. ELF), so we must perform the multiboot probe first. */ #define PROBE_MULTIBOOT 01 /** * Normal image probe priority */ #define PROBE_NORMAL 02 /** * PXE image probe priority * * PXE images have no signature checks, so will claim all image files. * They must therefore be tried last in the probe order list. */ #define PROBE_PXE 03 /** Executable or loadable image type table */ #define IMAGE_TYPES __table ( struct image_type, "image_types" ) /** An executable or loadable image type */ #define __image_type( probe_order ) __table_entry ( IMAGE_TYPES, probe_order ) extern struct list_head images; /** Iterate over all registered images */ #define for_each_image( image ) \ list_for_each_entry ( (image), &images, list ) /** * Test for existence of images * * @ret existence Some images exist */ static inline int have_images ( void ) { return ( ! list_empty ( &images ) ); } extern struct image * alloc_image ( void ); extern int image_set_uri ( struct image *image, struct uri *uri ); extern int image_set_cmdline ( struct image *image, const char *cmdline ); extern int register_image ( struct image *image ); extern void unregister_image ( struct image *image ); extern void promote_image ( struct image *image ); struct image * find_image ( const char *name ); extern int image_load ( struct image *image ); extern int image_autoload ( struct image *image ); extern int image_exec ( struct image *image ); extern int register_and_autoload_image ( struct image *image ); extern int register_and_autoexec_image ( struct image *image ); /** * Increment reference count on an image * * @v image Image * @ret image Image */ static inline struct image * image_get ( struct image *image ) { ref_get ( &image->refcnt ); return image; } /** * Decrement reference count on an image * * @v image Image */ static inline void image_put ( struct image *image ) { ref_put ( &image->refcnt ); } /** * Set image name * * @v image Image * @v name New image name * @ret rc Return status code */ static inline int image_set_name ( struct image *image, const char *name ) { strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) ); return 0; } #endif /* _GPXE_IMAGE_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/errfile.h0000664000000000000000000002237512524662415021143 0ustar #ifndef _GPXE_ERRFILE_H #define _GPXE_ERRFILE_H /** @file * * Error file identifiers * */ FILE_LICENCE ( GPL2_OR_LATER ); #include /** * @defgroup errfilecat Error file identifier categories * * @{ */ #define ERRFILE_CORE 0x00002000 /**< Core code */ #define ERRFILE_DRIVER 0x00004000 /**< Driver code */ #define ERRFILE_NET 0x00006000 /**< Networking code */ #define ERRFILE_IMAGE 0x00008000 /**< Image code */ #define ERRFILE_OTHER 0x0000e000 /**< Any other code */ /** @} */ /** Flag for architecture-dependent error files */ #define ERRFILE_ARCH 0x00800000 /** * @defgroup errfile Error file identifiers * * These values are automatically incorporated into the definitions * for error numbers such as EINVAL. * * @{ */ #define ERRFILE_asprintf ( ERRFILE_CORE | 0x00000000 ) #define ERRFILE_downloader ( ERRFILE_CORE | 0x00010000 ) #define ERRFILE_exec ( ERRFILE_CORE | 0x00020000 ) #define ERRFILE_hw ( ERRFILE_CORE | 0x00030000 ) #define ERRFILE_iobuf ( ERRFILE_CORE | 0x00040000 ) #define ERRFILE_job ( ERRFILE_CORE | 0x00050000 ) #define ERRFILE_linebuf ( ERRFILE_CORE | 0x00060000 ) #define ERRFILE_monojob ( ERRFILE_CORE | 0x00070000 ) #define ERRFILE_nvo ( ERRFILE_CORE | 0x00080000 ) #define ERRFILE_open ( ERRFILE_CORE | 0x00090000 ) #define ERRFILE_posix_io ( ERRFILE_CORE | 0x000a0000 ) #define ERRFILE_resolv ( ERRFILE_CORE | 0x000b0000 ) #define ERRFILE_settings ( ERRFILE_CORE | 0x000c0000 ) #define ERRFILE_vsprintf ( ERRFILE_CORE | 0x000d0000 ) #define ERRFILE_xfer ( ERRFILE_CORE | 0x000e0000 ) #define ERRFILE_bitmap ( ERRFILE_CORE | 0x000f0000 ) #define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 ) #define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 ) #define ERRFILE_isapnp ( ERRFILE_DRIVER | 0x00020000 ) #define ERRFILE_mca ( ERRFILE_DRIVER | 0x00030000 ) #define ERRFILE_pci ( ERRFILE_DRIVER | 0x00040000 ) #define ERRFILE_nvs ( ERRFILE_DRIVER | 0x00100000 ) #define ERRFILE_spi ( ERRFILE_DRIVER | 0x00110000 ) #define ERRFILE_i2c_bit ( ERRFILE_DRIVER | 0x00120000 ) #define ERRFILE_spi_bit ( ERRFILE_DRIVER | 0x00130000 ) #define ERRFILE_3c509 ( ERRFILE_DRIVER | 0x00200000 ) #define ERRFILE_bnx2 ( ERRFILE_DRIVER | 0x00210000 ) #define ERRFILE_cs89x0 ( ERRFILE_DRIVER | 0x00220000 ) #define ERRFILE_eepro ( ERRFILE_DRIVER | 0x00230000 ) #define ERRFILE_etherfabric ( ERRFILE_DRIVER | 0x00240000 ) #define ERRFILE_legacy ( ERRFILE_DRIVER | 0x00250000 ) #define ERRFILE_natsemi ( ERRFILE_DRIVER | 0x00260000 ) #define ERRFILE_pnic ( ERRFILE_DRIVER | 0x00270000 ) #define ERRFILE_prism2_pci ( ERRFILE_DRIVER | 0x00280000 ) #define ERRFILE_prism2_plx ( ERRFILE_DRIVER | 0x00290000 ) #define ERRFILE_rtl8139 ( ERRFILE_DRIVER | 0x002a0000 ) #define ERRFILE_smc9000 ( ERRFILE_DRIVER | 0x002b0000 ) #define ERRFILE_tg3 ( ERRFILE_DRIVER | 0x002c0000 ) #define ERRFILE_3c509_eisa ( ERRFILE_DRIVER | 0x002d0000 ) #define ERRFILE_3c515 ( ERRFILE_DRIVER | 0x002e0000 ) #define ERRFILE_3c529 ( ERRFILE_DRIVER | 0x002f0000 ) #define ERRFILE_3c595 ( ERRFILE_DRIVER | 0x00300000 ) #define ERRFILE_3c5x9 ( ERRFILE_DRIVER | 0x00310000 ) #define ERRFILE_3c90x ( ERRFILE_DRIVER | 0x00320000 ) #define ERRFILE_amd8111e ( ERRFILE_DRIVER | 0x00330000 ) #define ERRFILE_davicom ( ERRFILE_DRIVER | 0x00340000 ) #define ERRFILE_depca ( ERRFILE_DRIVER | 0x00350000 ) #define ERRFILE_dmfe ( ERRFILE_DRIVER | 0x00360000 ) #define ERRFILE_eepro100 ( ERRFILE_DRIVER | 0x00380000 ) #define ERRFILE_epic100 ( ERRFILE_DRIVER | 0x00390000 ) #define ERRFILE_forcedeth ( ERRFILE_DRIVER | 0x003a0000 ) #define ERRFILE_mtd80x ( ERRFILE_DRIVER | 0x003b0000 ) #define ERRFILE_ns83820 ( ERRFILE_DRIVER | 0x003c0000 ) #define ERRFILE_ns8390 ( ERRFILE_DRIVER | 0x003d0000 ) #define ERRFILE_pcnet32 ( ERRFILE_DRIVER | 0x003e0000 ) #define ERRFILE_r8169 ( ERRFILE_DRIVER | 0x003f0000 ) #define ERRFILE_sis900 ( ERRFILE_DRIVER | 0x00400000 ) #define ERRFILE_sundance ( ERRFILE_DRIVER | 0x00410000 ) #define ERRFILE_tlan ( ERRFILE_DRIVER | 0x00420000 ) #define ERRFILE_tulip ( ERRFILE_DRIVER | 0x00430000 ) #define ERRFILE_via_rhine ( ERRFILE_DRIVER | 0x00440000 ) #define ERRFILE_via_velocity ( ERRFILE_DRIVER | 0x00450000 ) #define ERRFILE_w89c840 ( ERRFILE_DRIVER | 0x00460000 ) #define ERRFILE_ipoib ( ERRFILE_DRIVER | 0x00470000 ) #define ERRFILE_e1000 ( ERRFILE_DRIVER | 0x00480000 ) #define ERRFILE_e1000_hw ( ERRFILE_DRIVER | 0x00490000 ) #define ERRFILE_mtnic ( ERRFILE_DRIVER | 0x004a0000 ) #define ERRFILE_phantom ( ERRFILE_DRIVER | 0x004b0000 ) #define ERRFILE_ne2k_isa ( ERRFILE_DRIVER | 0x004c0000 ) #define ERRFILE_b44 ( ERRFILE_DRIVER | 0x004d0000 ) #define ERRFILE_rtl818x ( ERRFILE_DRIVER | 0x004e0000 ) #define ERRFILE_sky2 ( ERRFILE_DRIVER | 0x004f0000 ) #define ERRFILE_ath5k ( ERRFILE_DRIVER | 0x00500000 ) #define ERRFILE_atl1e ( ERRFILE_DRIVER | 0x00510000 ) #define ERRFILE_scsi ( ERRFILE_DRIVER | 0x00700000 ) #define ERRFILE_arbel ( ERRFILE_DRIVER | 0x00710000 ) #define ERRFILE_hermon ( ERRFILE_DRIVER | 0x00720000 ) #define ERRFILE_linda ( ERRFILE_DRIVER | 0x00730000 ) #define ERRFILE_ata ( ERRFILE_DRIVER | 0x00740000 ) #define ERRFILE_srp ( ERRFILE_DRIVER | 0x00750000 ) #define ERRFILE_aoe ( ERRFILE_NET | 0x00000000 ) #define ERRFILE_arp ( ERRFILE_NET | 0x00010000 ) #define ERRFILE_dhcpopts ( ERRFILE_NET | 0x00020000 ) #define ERRFILE_ethernet ( ERRFILE_NET | 0x00030000 ) #define ERRFILE_icmpv6 ( ERRFILE_NET | 0x00040000 ) #define ERRFILE_ipv4 ( ERRFILE_NET | 0x00050000 ) #define ERRFILE_ipv6 ( ERRFILE_NET | 0x00060000 ) #define ERRFILE_ndp ( ERRFILE_NET | 0x00070000 ) #define ERRFILE_netdevice ( ERRFILE_NET | 0x00080000 ) #define ERRFILE_nullnet ( ERRFILE_NET | 0x00090000 ) #define ERRFILE_tcp ( ERRFILE_NET | 0x000a0000 ) #define ERRFILE_ftp ( ERRFILE_NET | 0x000b0000 ) #define ERRFILE_http ( ERRFILE_NET | 0x000c0000 ) #define ERRFILE_iscsi ( ERRFILE_NET | 0x000d0000 ) #define ERRFILE_tcpip ( ERRFILE_NET | 0x000e0000 ) #define ERRFILE_udp ( ERRFILE_NET | 0x000f0000 ) #define ERRFILE_dhcp ( ERRFILE_NET | 0x00100000 ) #define ERRFILE_dns ( ERRFILE_NET | 0x00110000 ) #define ERRFILE_tftp ( ERRFILE_NET | 0x00120000 ) #define ERRFILE_infiniband ( ERRFILE_NET | 0x00130000 ) #define ERRFILE_netdev_settings ( ERRFILE_NET | 0x00140000 ) #define ERRFILE_dhcppkt ( ERRFILE_NET | 0x00150000 ) #define ERRFILE_slam ( ERRFILE_NET | 0x00160000 ) #define ERRFILE_ib_sma ( ERRFILE_NET | 0x00170000 ) #define ERRFILE_ib_packet ( ERRFILE_NET | 0x00180000 ) #define ERRFILE_icmp ( ERRFILE_NET | 0x00190000 ) #define ERRFILE_ib_qset ( ERRFILE_NET | 0x001a0000 ) #define ERRFILE_ib_gma ( ERRFILE_NET | 0x001b0000 ) #define ERRFILE_ib_pathrec ( ERRFILE_NET | 0x001c0000 ) #define ERRFILE_ib_mcast ( ERRFILE_NET | 0x001d0000 ) #define ERRFILE_ib_cm ( ERRFILE_NET | 0x001e0000 ) #define ERRFILE_net80211 ( ERRFILE_NET | 0x001f0000 ) #define ERRFILE_ib_mi ( ERRFILE_NET | 0x00200000 ) #define ERRFILE_ib_cmrc ( ERRFILE_NET | 0x00210000 ) #define ERRFILE_ib_srp ( ERRFILE_NET | 0x00220000 ) #define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 ) #define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 ) #define ERRFILE_script ( ERRFILE_IMAGE | 0x00020000 ) #define ERRFILE_segment ( ERRFILE_IMAGE | 0x00030000 ) #define ERRFILE_efi_image ( ERRFILE_IMAGE | 0x00040000 ) #define ERRFILE_embedded ( ERRFILE_IMAGE | 0x00050000 ) #define ERRFILE_asn1 ( ERRFILE_OTHER | 0x00000000 ) #define ERRFILE_chap ( ERRFILE_OTHER | 0x00010000 ) #define ERRFILE_aoeboot ( ERRFILE_OTHER | 0x00020000 ) #define ERRFILE_autoboot ( ERRFILE_OTHER | 0x00030000 ) #define ERRFILE_dhcpmgmt ( ERRFILE_OTHER | 0x00040000 ) #define ERRFILE_imgmgmt ( ERRFILE_OTHER | 0x00050000 ) #define ERRFILE_pxe_tftp ( ERRFILE_OTHER | 0x00060000 ) #define ERRFILE_pxe_udp ( ERRFILE_OTHER | 0x00070000 ) #define ERRFILE_axtls_aes ( ERRFILE_OTHER | 0x00080000 ) #define ERRFILE_cipher ( ERRFILE_OTHER | 0x00090000 ) #define ERRFILE_image_cmd ( ERRFILE_OTHER | 0x000a0000 ) #define ERRFILE_uri_test ( ERRFILE_OTHER | 0x000b0000 ) #define ERRFILE_ibft ( ERRFILE_OTHER | 0x000c0000 ) #define ERRFILE_tls ( ERRFILE_OTHER | 0x000d0000 ) #define ERRFILE_ifmgmt ( ERRFILE_OTHER | 0x000e0000 ) #define ERRFILE_iscsiboot ( ERRFILE_OTHER | 0x000f0000 ) #define ERRFILE_efi_pci ( ERRFILE_OTHER | 0x00100000 ) #define ERRFILE_efi_snp ( ERRFILE_OTHER | 0x00110000 ) #define ERRFILE_smbios ( ERRFILE_OTHER | 0x00120000 ) #define ERRFILE_smbios_settings ( ERRFILE_OTHER | 0x00130000 ) #define ERRFILE_efi_smbios ( ERRFILE_OTHER | 0x00140000 ) #define ERRFILE_pxemenu ( ERRFILE_OTHER | 0x00150000 ) #define ERRFILE_x509 ( ERRFILE_OTHER | 0x00160000 ) #define ERRFILE_login_ui ( ERRFILE_OTHER | 0x00170000 ) #define ERRFILE_ib_srpboot ( ERRFILE_OTHER | 0x00180000 ) /** @} */ #endif /* _GPXE_ERRFILE_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/refcnt.h0000664000000000000000000000220112524662415020756 0ustar #ifndef _GPXE_REFCNT_H #define _GPXE_REFCNT_H /** @file * * Reference counting * */ FILE_LICENCE ( GPL2_OR_LATER ); /** * A reference counter * * This data structure is designed to be embedded within a * reference-counted object. * * Reference-counted objects are freed when their reference count * drops below zero. This means that a freshly allocated-and-zeroed * reference-counted object will be freed on the first call to * ref_put(). */ struct refcnt { /** Current reference count * * When this count is decremented below zero, the free() * method will be called. */ int refcnt; /** Free containing object * * This method is called when the reference count is * decremented below zero. * * If this method is left NULL, the standard library free() * function will be called. The upshot of this is that you * may omit the free() method if the @c refcnt object is the * first element of your reference-counted struct. */ void ( * free ) ( struct refcnt *refcnt ); }; extern struct refcnt * ref_get ( struct refcnt *refcnt ); extern void ref_put ( struct refcnt *refcnt ); #endif /* _GPXE_REFCNT_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/init.h0000664000000000000000000000370412524662415020451 0ustar #ifndef _GPXE_INIT_H #define _GPXE_INIT_H FILE_LICENCE ( GPL2_OR_LATER ); #include /** * An initialisation function * * Initialisation functions are called exactly once, as part of the * call to initialise(). */ struct init_fn { void ( * initialise ) ( void ); }; /** Initialisation function table */ #define INIT_FNS __table ( struct init_fn, "init_fns" ) /** Declare an initialisation functon */ #define __init_fn( init_order ) __table_entry ( INIT_FNS, init_order ) /** @defgroup initfn_order Initialisation function ordering * @{ */ #define INIT_EARLY 01 /**< Early initialisation */ #define INIT_SERIAL 02 /**< Serial driver initialisation */ #define INIT_CONSOLE 03 /**< Console initialisation */ #define INIT_NORMAL 04 /**< Normal initialisation */ /** @} */ /** Shutdown flags */ enum shutdown_flags { /** Shutdown is in order to exit (return to gPXE's caller) */ SHUTDOWN_EXIT = 0x0001, /** Shutdown is in order to boot an OS */ SHUTDOWN_BOOT = 0x0002, /** Do not remove devices */ SHUTDOWN_KEEP_DEVICES = 0x0004, }; /** * A startup/shutdown function * * Startup and shutdown functions may be called multiple times, as * part of the calls to startup() and shutdown(). */ struct startup_fn { void ( * startup ) ( void ); void ( * shutdown ) ( int flags ); }; /** Startup/shutdown function table */ #define STARTUP_FNS __table ( struct startup_fn, "startup_fns" ) /** Declare a startup/shutdown function */ #define __startup_fn( startup_order ) \ __table_entry ( STARTUP_FNS, startup_order ) /** @defgroup startfn_order Startup/shutdown function ordering * * Shutdown functions are called in the reverse order to startup * functions. * * @{ */ #define STARTUP_EARLY 01 /**< Early startup */ #define STARTUP_NORMAL 02 /**< Normal startup */ #define STARTUP_LATE 03 /**< Late startup */ /** @} */ extern void initialise ( void ); extern void startup ( void ); extern void shutdown ( int flags ); #endif /* _GPXE_INIT_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/bitmap.h0000664000000000000000000000340412524662415020757 0ustar #ifndef _GPXE_BITMAP_H #define _GPXE_BITMAP_H /** @file * * Bitmaps for multicast downloads * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include /** A single block of bits within a bitmap */ typedef unsigned long bitmap_block_t; /** Size of a block of bits (in bits) */ #define BITMAP_BLKSIZE ( sizeof ( bitmap_block_t ) * 8 ) /** * Block index within bitmap * * @v bit Bit index * @ret index Block index */ #define BITMAP_INDEX( bit ) ( (bit) / BITMAP_BLKSIZE ) /** * Block mask within bitmap * * @v bit Bit index * @ret mask Block mask */ #define BITMAP_MASK( bit ) ( 1 << ( (bit) % BITMAP_BLKSIZE ) ) /** A bitmap */ struct bitmap { /** Bitmap data */ bitmap_block_t *blocks; /** Length of the bitmap, in bits */ unsigned int length; /** Index of first gap in the bitmap */ unsigned int first_gap; }; extern int bitmap_resize ( struct bitmap *bitmap, unsigned int new_length ); extern int bitmap_test ( struct bitmap *bitmap, unsigned int bit ); extern void bitmap_set ( struct bitmap *bitmap, unsigned int bit ); /** * Free bitmap resources * * @v bitmap Bitmap */ static inline void bitmap_free ( struct bitmap *bitmap ) { free ( bitmap->blocks ); } /** * Get first gap within bitmap * * @v bitmap Bitmap * @ret first_gap First gap * * The first gap is the first unset bit within the bitmap. */ static inline unsigned int bitmap_first_gap ( struct bitmap *bitmap ) { return bitmap->first_gap; } /** * Check to see if bitmap is full * * @v bitmap Bitmap * @ret is_full Bitmap is full * * The bitmap is full if it has no gaps (i.e. no unset bits). */ static inline int bitmap_full ( struct bitmap *bitmap ) { return ( bitmap->first_gap == bitmap->length ); } #endif /* _GPXE_BITMAP_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/api.h0000664000000000000000000000473512524662415020264 0ustar #ifndef _GPXE_API_H #define _GPXE_API_H /** @file * * gPXE internal APIs * * There are various formally-defined APIs internal to gPXE, with * several differing implementations specific to particular execution * environments (e.g. PC BIOS, EFI, LinuxBIOS). * */ FILE_LICENCE ( GPL2_OR_LATER ); /** @defgroup Single-implementation APIs * * These are APIs for which only a single implementation may be * compiled in at any given time. * * @{ */ /** * Calculate function implementation name * * @v _prefix Subsystem prefix * @v _api_func API function * @ret _subsys_func Subsystem API function * * The subsystem prefix should be an empty string for the currently * selected subsystem, and should be a subsystem-unique string for all * other subsystems. */ #define SINGLE_API_NAME( _prefix, _api_func ) _prefix ## _api_func /** * Calculate static inline function name * * @v _prefix Subsystem prefix * @v _api_func API function * @ret _subsys_func Subsystem API function */ #define SINGLE_API_INLINE( _prefix, _api_func ) \ SINGLE_API_NAME ( _prefix, _api_func ) /** * Provide an API implementation * * @v _prefix Subsystem prefix * @v _api_func API function * @v _func Implementing function */ #define PROVIDE_SINGLE_API( _prefix, _api_func, _func ) \ /* Ensure that _api_func exists */ \ typeof ( _api_func ) _api_func; \ /* Ensure that _func exists */ \ typeof ( _func ) _func; \ /* Ensure that _func is type-compatible with _api_func */ \ typeof ( _api_func ) _func; \ /* Ensure that _subsys_func is non-static */ \ extern typeof ( _api_func ) SINGLE_API_NAME ( _prefix, _api_func ); \ /* Provide symbol alias from _subsys_func to _func */ \ typeof ( _api_func ) SINGLE_API_NAME ( _prefix, _api_func ) \ __attribute__ (( alias ( #_func ) )); /** * Provide a static inline API implementation * * @v _prefix Subsystem prefix * @v _api_func API function */ #define PROVIDE_SINGLE_API_INLINE( _prefix, _api_func ) \ /* Ensure that _api_func exists */ \ typeof ( _api_func ) _api_func; \ /* Ensure that _subsys_func exists and is static */ \ static typeof ( SINGLE_API_INLINE ( _prefix, _api_func ) ) \ SINGLE_API_INLINE ( _prefix, _api_func ); \ /* Ensure that _subsys_func is type-compatible with _api_func */ \ typeof ( _api_func ) SINGLE_API_INLINE ( _prefix, _api_func ); /** @} */ #endif /* _GPXE_API_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/tables.h0000664000000000000000000002703512524662415020763 0ustar #ifndef _GPXE_TABLES_H #define _GPXE_TABLES_H FILE_LICENCE ( GPL2_OR_LATER ); /** @page ifdef_harmful #ifdef considered harmful * * Overuse of @c #ifdef has long been a problem in Etherboot. * Etherboot provides a rich array of features, but all these features * take up valuable space in a ROM image. The traditional solution to * this problem has been for each feature to have its own @c #ifdef * option, allowing the feature to be compiled in only if desired. * * The problem with this is that it becomes impossible to compile, let * alone test, all possible versions of Etherboot. Code that is not * typically used tends to suffer from bit-rot over time. It becomes * extremely difficult to predict which combinations of compile-time * options will result in code that can even compile and link * correctly. * * To solve this problem, we have adopted a new approach from * Etherboot 5.5 onwards. @c #ifdef is now "considered harmful", and * its use should be minimised. Separate features should be * implemented in separate @c .c files, and should \b always be * compiled (i.e. they should \b not be guarded with a @c #ifdef @c * MY_PET_FEATURE statement). By making (almost) all code always * compile, we avoid the problem of bit-rot in rarely-used code. * * The file config.h, in combination with the @c make command line, * specifies the objects that will be included in any particular build * of Etherboot. For example, suppose that config.h includes the line * * @code * * #define CONSOLE_SERIAL * #define DOWNLOAD_PROTO_TFTP * * @endcode * * When a particular Etherboot image (e.g. @c bin/rtl8139.zdsk) is * built, the options specified in config.h are used to drag in the * relevant objects at link-time. For the above example, serial.o and * tftp.o would be linked in. * * There remains one problem to solve: how do these objects get used? * Traditionally, we had code such as * * @code * * #ifdef CONSOLE_SERIAL * serial_init(); * #endif * * @endcode * * in main.c, but this reintroduces @c #ifdef and so is a Bad Idea. * We cannot simply remove the @c #ifdef and make it * * @code * * serial_init(); * * @endcode * * because then serial.o would end up always being linked in. * * The solution is to use @link tables.h linker tables @endlink. * */ /** @file * * Linker tables * * Read @ref ifdef_harmful first for some background on the motivation * for using linker tables. * * This file provides macros for dealing with linker-generated tables * of fixed-size symbols. We make fairly extensive use of these in * order to avoid @c #ifdef spaghetti and/or linker symbol pollution. * For example, instead of having code such as * * @code * * #ifdef CONSOLE_SERIAL * serial_init(); * #endif * * @endcode * * we make serial.c generate an entry in the initialisation function * table, and then have a function call_init_fns() that simply calls * all functions present in this table. If and only if serial.o gets * linked in, then its initialisation function will be called. We * avoid linker symbol pollution (i.e. always dragging in serial.o * just because of a call to serial_init()) and we also avoid @c * #ifdef spaghetti (having to conditionalise every reference to * functions in serial.c). * * The linker script takes care of assembling the tables for us. All * our table sections have names of the format @c .tbl.NAME.NN where * @c NAME designates the data structure stored in the table (e.g. @c * init_fns) and @c NN is a two-digit decimal number used to impose an * ordering upon the tables if required. @c NN=00 is reserved for the * symbol indicating "table start", and @c NN=99 is reserved for the * symbol indicating "table end". * * As an example, suppose that we want to create a "frobnicator" * feature framework, and allow for several independent modules to * provide frobnicating services. Then we would create a frob.h * header file containing e.g. * * @code * * struct frobnicator { * const char *name; // Name of the frobnicator * void ( *frob ) ( void ); // The frobnicating function itself * }; * * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) * * #define __frobnicator __table_entry ( FROBNICATORS, 01 ) * * @endcode * * Any module providing frobnicating services would look something * like * * @code * * #include "frob.h" * * static void my_frob ( void ) { * // Do my frobnicating * ... * } * * struct frob my_frobnicator __frobnicator = { * .name = "my_frob", * .frob = my_frob, * }; * * @endcode * * The central frobnicator code (frob.c) would use the frobnicating * modules as follows * * @code * * #include "frob.h" * * // Call all linked-in frobnicators * void frob_all ( void ) { * struct frob *frob; * * for_each_table ( frob, FROBNICATORS ) { * printf ( "Calling frobnicator \"%s\"\n", frob->name ); * frob->frob (); * } * } * * @endcode * * See init.h and init.c for a real-life example. * */ #ifdef DOXYGEN #define __attribute__( x ) #endif /** * Declare a linker table * * @v type Data type * @v name Table name * @ret table Linker table */ #define __table( type, name ) ( type, name ) /** * Get linker table data type * * @v table Linker table * @ret type Data type */ #define __table_type( table ) __table_extract_type table #define __table_extract_type( type, name ) type /** * Get linker table name * * @v table Linker table * @ret name Table name */ #define __table_name( table ) __table_extract_name table #define __table_extract_name( type, name ) name /** * Get linker table section name * * @v table Linker table * @v idx Sub-table index * @ret section Section name */ #define __table_section( table, idx ) \ ".tbl." __table_name ( table ) "." __table_str ( idx ) #define __table_str( x ) #x /** * Get linker table alignment * * @v table Linker table * @ret align Alignment */ #define __table_alignment( table ) __alignof__ ( __table_type ( table ) ) /** * Declare a linker table entry * * @v table Linker table * @v idx Sub-table index * * Example usage: * * @code * * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) * * #define __frobnicator __table_entry ( FROBNICATORS, 01 ) * * struct frobnicator my_frob __frobnicator = { * ... * }; * * @endcode */ #define __table_entry( table, idx ) \ __attribute__ (( __section__ ( __table_section ( table, idx ) ),\ __aligned__ ( __table_alignment ( table ) ) )) /** * Get start of linker table entries * * @v table Linker table * @v idx Sub-table index * @ret entries Start of entries */ #define __table_entries( table, idx ) ( { \ static __table_type ( table ) __table_entries[0] \ __table_entry ( table, idx ); \ __table_entries; } ) /** * Get start of linker table * * @v table Linker table * @ret start Start of linker table * * Example usage: * * @code * * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) * * struct frobnicator *frobs = table_start ( FROBNICATORS ); * * @endcode */ #define table_start( table ) __table_entries ( table, 00 ) /** * Get end of linker table * * @v table Linker table * @ret end End of linker table * * Example usage: * * @code * * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) * * struct frobnicator *frobs_end = table_end ( FROBNICATORS ); * * @endcode */ #define table_end( table ) __table_entries ( table, 99 ) /** * Get number of entries in linker table * * @v table Linker table * @ret num_entries Number of entries in linker table * * Example usage: * * @code * * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) * * unsigned int num_frobs = table_num_entries ( FROBNICATORS ); * * @endcode * */ #define table_num_entries( table ) \ ( ( unsigned int ) ( table_end ( table ) - \ table_start ( table ) ) ) /** * Iterate through all entries within a linker table * * @v pointer Entry pointer * @v table Linker table * * Example usage: * * @code * * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) * * struct frobnicator *frob; * * for_each_table_entry ( frob, FROBNICATORS ) { * ... * } * * @endcode * */ #define for_each_table_entry( pointer, table ) \ for ( pointer = table_start ( table ) ; \ pointer < table_end ( table ) ; \ pointer++ ) /** * Iterate through all entries within a linker table in reverse order * * @v pointer Entry pointer * @v table Linker table * * Example usage: * * @code * * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) * * struct frobnicator *frob; * * for_each_table_entry_reverse ( frob, FROBNICATORS ) { * ... * } * * @endcode * */ #define for_each_table_entry_reverse( pointer, table ) \ for ( pointer = ( table_end ( table ) - 1 ) ; \ pointer >= table_start ( table ) ; \ pointer-- ) /****************************************************************************** * * Intel's C compiler chokes on several of the constructs used in this * file. The workarounds are ugly, so we use them only for an icc * build. * */ #define ICC_ALIGN_HACK_FACTOR 128 #ifdef __ICC /* * icc miscompiles zero-length arrays by inserting padding to a length * of two array elements. We therefore have to generate the * __table_entries() symbols by hand in asm. * */ #undef __table_entries #define __table_entries( table, idx ) ( { \ extern __table_type ( table ) \ __table_temp_sym ( idx, __LINE__ ) [] \ __table_entry ( table, idx ) \ asm ( __table_entries_sym ( table, idx ) ); \ __asm__ ( ".ifndef %c0\n\t" \ ".section " __table_section ( table, idx ) "\n\t" \ ".align %c1\n\t" \ "\n%c0:\n\t" \ ".previous\n\t" \ ".endif\n\t" \ : : "i" ( __table_temp_sym ( idx, __LINE__ ) ), \ "i" ( __table_alignment ( table ) ) ); \ __table_temp_sym ( idx, __LINE__ ); } ) #define __table_entries_sym( table, idx ) \ "__tbl_" __table_name ( table ) "_" #idx #define __table_temp_sym( a, b ) \ ___table_temp_sym( __table_, a, _, b ) #define ___table_temp_sym( a, b, c, d ) a ## b ## c ## d /* * icc ignores __attribute__ (( aligned (x) )) when it is used to * decrease the compiler's default choice of alignment (which may be * higher than the alignment actually required by the structure). We * work around this by forcing the alignment to a large multiple of * the required value (so that we are never attempting to decrease the * default alignment) and then postprocessing the object file to * reduce the alignment back down to the "real" value. * */ #undef __table_alignment #define __table_alignment( table ) \ ( ICC_ALIGN_HACK_FACTOR * __alignof__ ( __table_type ( table ) ) ) /* * Because of the alignment hack, we must ensure that the compiler * never tries to place multiple objects within the same section, * otherwise the assembler will insert padding to the (incorrect) * alignment boundary. Do this by appending the line number to table * section names. * * Note that we don't need to worry about padding between array * elements, since the alignment is declared on the variable (i.e. the * whole array) rather than on the type (i.e. on all individual array * elements). */ #undef __table_section #define __table_section( table, idx ) \ ".tbl." __table_name ( table ) "." __table_str ( idx ) \ "." __table_xstr ( __LINE__ ) #define __table_xstr( x ) __table_str ( x ) #endif /* __ICC */ #endif /* _GPXE_TABLES_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/asn1.h0000664000000000000000000000120712524662415020344 0ustar #ifndef _GPXE_ASN1_H #define _GPXE_ASN1_H /** @file * * ASN.1 encoding * */ FILE_LICENCE ( GPL2_OR_LATER ); #define ASN1_INTEGER 0x02 #define ASN1_BIT_STRING 0x03 #define ASN1_OCTET_STRING 0x04 #define ASN1_NULL 0x05 #define ASN1_OID 0x06 #define ASN1_SEQUENCE 0x30 #define ASN1_IP_ADDRESS 0x40 #define ASN1_EXPLICIT_TAG 0xa0 /** * A DER-encoded ASN.1 object cursor */ struct asn1_cursor { /** Start of data */ void *data; /** Length of data */ size_t len; }; extern int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ); extern int asn1_skip ( struct asn1_cursor *cursor, unsigned int type ); #endif /* _GPXE_ASN1_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/job.h0000664000000000000000000001035412524662415020257 0ustar #ifndef _GPXE_JOB_H #define _GPXE_JOB_H /** @file * * Job control interfaces * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** Job progress */ struct job_progress { /** Amount of operation completed so far * * The units for this quantity are arbitrary. @c completed * divded by @total should give something which approximately * represents the progress through the operation. For a * download operation, using byte counts would make sense. */ unsigned long completed; /** Total operation size * * See @c completed. A zero value means "total size unknown" * and is explcitly permitted; users should take this into * account before calculating @c completed/total. */ unsigned long total; }; struct job_interface; /** Job control interface operations */ struct job_interface_operations { /** Job completed * * @v job Job control interface * @v rc Overall job status code */ void ( * done ) ( struct job_interface *job, int rc ); /** Abort job * * @v job Job control interface */ void ( * kill ) ( struct job_interface *job ); /** Get job progress * * @v job Job control interface * @v progress Progress data to fill in */ void ( * progress ) ( struct job_interface *job, struct job_progress *progress ); }; /** A job control interface */ struct job_interface { /** Generic object communication interface */ struct interface intf; /** Operations for received messages */ struct job_interface_operations *op; }; extern struct job_interface null_job; extern struct job_interface_operations null_job_ops; extern void job_done ( struct job_interface *job, int rc ); extern void job_kill ( struct job_interface *job ); extern void job_progress ( struct job_interface *job, struct job_progress *progress ); extern void ignore_job_done ( struct job_interface *job, int rc ); extern void ignore_job_kill ( struct job_interface *job ); extern void ignore_job_progress ( struct job_interface *job, struct job_progress *progress ); /** * Initialise a job control interface * * @v job Job control interface * @v op Job control interface operations * @v refcnt Containing object reference counter, or NULL */ static inline void job_init ( struct job_interface *job, struct job_interface_operations *op, struct refcnt *refcnt ) { job->intf.dest = &null_job.intf; job->intf.refcnt = refcnt; job->op = op; } /** * Get job control interface from generic object communication interface * * @v intf Generic object communication interface * @ret job Job control interface */ static inline __attribute__ (( always_inline )) struct job_interface * intf_to_job ( struct interface *intf ) { return container_of ( intf, struct job_interface, intf ); } /** * Get reference to destination job control interface * * @v job Job control interface * @ret dest Destination interface */ static inline __attribute__ (( always_inline )) struct job_interface * job_get_dest ( struct job_interface *job ) { return intf_to_job ( intf_get ( job->intf.dest ) ); } /** * Drop reference to job control interface * * @v job Job control interface */ static inline __attribute__ (( always_inline )) void job_put ( struct job_interface *job ) { intf_put ( &job->intf ); } /** * Plug a job control interface into a new destination interface * * @v job Job control interface * @v dest New destination interface */ static inline void job_plug ( struct job_interface *job, struct job_interface *dest ) { plug ( &job->intf, &dest->intf ); } /** * Plug two job control interfaces together * * @v a Job control interface A * @v b Job control interface B */ static inline void job_plug_plug ( struct job_interface *a, struct job_interface *b ) { plug_plug ( &a->intf, &b->intf ); } /** * Unplug a job control interface * * @v job Job control interface */ static inline void job_unplug ( struct job_interface *job ) { plug ( &job->intf, &null_job.intf ); } /** * Stop using a job control interface * * @v job Job control interface * * After calling this method, no further messages will be received via * the interface. */ static inline void job_nullify ( struct job_interface *job ) { job->op = &null_job_ops; }; #endif /* _GPXE_JOB_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/editstring.h0000664000000000000000000000124312524662415021656 0ustar #ifndef _GPXE_EDITSTRING_H #define _GPXE_EDITSTRING_H /** @file * * Editable strings * */ FILE_LICENCE ( GPL2_OR_LATER ); /** An editable string */ struct edit_string { /** Buffer for string */ char *buf; /** Size of buffer (including terminating NUL) */ size_t len; /** Cursor position */ unsigned int cursor; /* The following items are the edit history */ /** Last cursor position */ unsigned int last_cursor; /** Start of modified portion of string */ unsigned int mod_start; /** End of modified portion of string */ unsigned int mod_end; }; extern int edit_string ( struct edit_string *string, int key ) __nonnull; #endif /* _GPXE_EDITSTRING_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/shell_banner.h0000664000000000000000000000031612524662415022136 0ustar #ifndef _GPXE_SHELL_BANNER_H #define _GPXE_SHELL_BANNER_H /** @file * * Shell startup banner * */ FILE_LICENCE ( GPL2_OR_LATER ); extern int shell_banner ( void ); #endif /* _GPXE_SHELL_BANNER_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/linebuf.h0000664000000000000000000000116712524662415021133 0ustar #ifndef _GPXE_LINEBUF_H #define _GPXE_LINEBUF_H /** @file * * Line buffering * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** A line buffer */ struct line_buffer { /** Current string in the buffer */ char *data; /** Length of current string, excluding the terminating NUL */ size_t len; /** String is ready to read */ int ready; }; extern char * buffered_line ( struct line_buffer *linebuf ); extern ssize_t line_buffer ( struct line_buffer *linebuf, const char *data, size_t len ); extern void empty_line_buffer ( struct line_buffer *linebuf ); #endif /* _GPXE_LINEBUF_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/aes.h0000664000000000000000000000026012524662415020250 0ustar #ifndef _GPXE_AES_H #define _GPXE_AES_H FILE_LICENCE ( GPL2_OR_LATER ); struct cipher_algorithm; extern struct cipher_algorithm aes_cbc_algorithm; #endif /* _GPXE_AES_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/isa.h0000664000000000000000000000362112524662415020260 0ustar #ifndef ISA_H #define ISA_H FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include /** An ISA device */ struct isa_device { /** Generic device */ struct device dev; /** I/O address */ uint16_t ioaddr; /** Driver for this device */ struct isa_driver *driver; /** Driver-private data * * Use isa_set_drvdata() and isa_get_drvdata() to access * this field. */ void *priv; /** Driver name */ const char *driver_name; }; /* * An individual ISA device, identified by probe address * */ typedef uint16_t isa_probe_addr_t; /** An ISA driver */ struct isa_driver { /** Name */ const char *name; /** Probe address list */ isa_probe_addr_t *probe_addrs; /** Number of entries in probe address list */ unsigned int addr_count; /** Manufacturer ID to be assumed for this device */ uint16_t vendor_id; /** Product ID to be assumed for this device */ uint16_t prod_id; /** * Probe device * * @v isa ISA device * @v id Matching entry in ID table * @ret rc Return status code */ int ( * probe ) ( struct isa_device *isa ); /** * Remove device * * @v isa ISA device */ void ( * remove ) ( struct isa_device *isa ); }; /** ISA driver table */ #define ISA_DRIVERS __table ( struct isa_driver, "isa_drivers" ) /** Declare an ISA driver */ #define __isa_driver __table_entry ( ISA_DRIVERS, 01 ) /** * Set ISA driver-private data * * @v isa ISA device * @v priv Private data */ static inline void isa_set_drvdata ( struct isa_device *isa, void *priv ) { isa->priv = priv; } /** * Get ISA driver-private data * * @v isa ISA device * @ret priv Private data */ static inline void * isa_get_drvdata ( struct isa_device *isa ) { return isa->priv; } /* * ISA_ROM is parsed by parserom.pl to generate Makefile rules and * files for rom-o-matic. * */ #define ISA_ROM( IMAGE, DESCRIPTION ) #endif /* ISA_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/uri.h0000664000000000000000000000677512524662415020320 0ustar #ifndef _GPXE_URI_H #define _GPXE_URI_H /** @file * * Uniform Resource Identifiers * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include /** A Uniform Resource Identifier * * Terminology for this data structure is as per uri(7), except that * "path" is defined to include the leading '/' for an absolute path. * * Note that all fields within a URI are optional and may be NULL. * * Some examples are probably helpful: * * http://www.etherboot.org/wiki : * * scheme = "http", host = "www.etherboot.org", path = "/wiki" * * /var/lib/tftpboot : * * path = "/var/lib/tftpboot" * * mailto:bob@nowhere.com : * * scheme = "mailto", opaque = "bob@nowhere.com" * * ftp://joe:secret@insecure.org:8081/hidden/path/to?what=is#this * * scheme = "ftp", user = "joe", password = "secret", * host = "insecure.org", port = "8081", path = "/hidden/path/to", * query = "what=is", fragment = "this" */ struct uri { /** Reference count */ struct refcnt refcnt; /** Scheme */ const char *scheme; /** Opaque part */ const char *opaque; /** User name */ const char *user; /** Password */ const char *password; /** Host name */ const char *host; /** Port number */ const char *port; /** Path */ const char *path; /** Query */ const char *query; /** Fragment */ const char *fragment; }; /** * URI is an absolute URI * * @v uri URI * @ret is_absolute URI is absolute * * An absolute URI begins with a scheme, e.g. "http:" or "mailto:". * Note that this is a separate concept from a URI with an absolute * path. */ static inline int uri_is_absolute ( struct uri *uri ) { return ( uri->scheme != NULL ); } /** * URI has an absolute path * * @v uri URI * @ret has_absolute_path URI has an absolute path * * An absolute path begins with a '/'. Note that this is a separate * concept from an absolute URI. Note also that a URI may not have a * path at all. */ static inline int uri_has_absolute_path ( struct uri *uri ) { return ( uri->path && ( uri->path[0] == '/' ) ); } /** * URI has a relative path * * @v uri URI * @ret has_relative_path URI has a relative path * * A relative path begins with something other than a '/'. Note that * this is a separate concept from a relative URI. Note also that a * URI may not have a path at all. */ static inline int uri_has_relative_path ( struct uri *uri ) { return ( uri->path && ( uri->path[0] != '/' ) ); } /** * Increment URI reference count * * @v uri URI, or NULL * @ret uri URI as passed in */ static inline __attribute__ (( always_inline )) struct uri * uri_get ( struct uri *uri ) { ref_get ( &uri->refcnt ); return uri; } /** * Decrement URI reference count * * @v uri URI, or NULL */ static inline __attribute__ (( always_inline )) void uri_put ( struct uri *uri ) { ref_put ( &uri->refcnt ); } extern struct uri *cwuri; extern struct uri * parse_uri ( const char *uri_string ); extern unsigned int uri_port ( struct uri *uri, unsigned int default_port ); extern int unparse_uri ( char *buf, size_t size, struct uri *uri ); extern struct uri * uri_dup ( struct uri *uri ); extern char * resolve_path ( const char *base_path, const char *relative_path ); extern struct uri * resolve_uri ( struct uri *base_uri, struct uri *relative_uri ); extern void churi ( struct uri *uri ); extern size_t uri_encode ( const char *raw_string, char *buf, size_t len ); extern size_t uri_decode ( const char *encoded_string, char *buf, size_t len ); #endif /* _GPXE_URI_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/ieee80211.h0000664000000000000000000011151212524662415021006 0ustar #ifndef _GPXE_IEEE80211_H #define _GPXE_IEEE80211_H #include /* for ETH_ALEN */ /** @file * Constants and data structures defined in IEEE 802.11, subsetted * according to what gPXE knows how to use. */ FILE_LICENCE(GPL2_OR_LATER); /* ---------- Maximum lengths of things ---------- */ /** * @defgroup ieee80211_maxlen Maximum lengths in the 802.11 protocol * @{ */ /** Maximum length of frame payload * * This does not include cryptographic overhead, which can be up to 20 * bytes, but it DOES include the 802.2 LLC/SNAP headers that are used * on data frames (but not management frames). */ #define IEEE80211_MAX_DATA_LEN 2304 /** Length of LLC/SNAP headers on data frames */ #define IEEE80211_LLC_HEADER_LEN 8 /** Maximum cryptographic overhead before encrypted data */ #define IEEE80211_MAX_CRYPTO_HEADER 8 /** Maximum cryptographic overhead after encrypted data * * This does not count the MIC in TKIP frames, since that is * considered to be part of the MSDU and thus contributes to the size * of the data field. * * It @e does count the MIC in CCMP frames, which is considered part * of the MPDU (outside the data field). */ #define IEEE80211_MAX_CRYPTO_TRAILER 8 /** Total maximum cryptographic overhead */ #define IEEE80211_MAX_CRYPTO_OVERHEAD 16 /** Bytes of network-layer data that can go into a regular data frame */ #define IEEE80211_MAX_FRAME_DATA 2296 /** Frame header length for frames we might work with * * QoS adds a two-byte field on top of this, and APs communicating * with each other in Wireless Distribution System (WDS) mode add an * extra 6-byte MAC address field, but we do not work with such * frames. */ #define IEEE80211_TYP_FRAME_HEADER_LEN 24 /** Theoretical maximum frame header length * * This includes the QoS and WDS Addr4 fields that we should never * see. */ #define IEEE80211_MAX_FRAME_HEADER_LEN 32 /** Maximum combined frame length * * The biggest frame will include 32 frame header bytes, 16 bytes of * crypto overhead, and 2304 data bytes. */ #define IEEE80211_MAX_FRAME_LEN 2352 /** Maximum length of an ESSID */ #define IEEE80211_MAX_SSID_LEN 32 /** @} */ /* ---------- Frame Control defines ---------- */ /** * @defgroup ieee80211_fc 802.11 Frame Control field bits * @{ */ /** 802.11 Frame Control field, Version bitmask */ #define IEEE80211_FC_VERSION 0x0003 /** Expected value of Version bits in Frame Control */ #define IEEE80211_THIS_VERSION 0x0000 /** 802.11 Frame Control field, Frame Type bitmask */ #define IEEE80211_FC_TYPE 0x000C /** Type value for management (layer-2) frames */ #define IEEE80211_TYPE_MGMT 0x0000 /** Type value for control (layer-1, hardware-managed) frames */ #define IEEE80211_TYPE_CTRL 0x0004 /** Type value for data frames */ #define IEEE80211_TYPE_DATA 0x0008 /** 802.11 Frame Control field, Frame Subtype bitmask */ #define IEEE80211_FC_SUBTYPE 0x00F0 /** Subtype value for association-request management frames * * Association request frames are sent after authentication from the * client to the Access Point to establish the client as part of the * Access Point's network. */ #define IEEE80211_STYPE_ASSOC_REQ 0x0000 /** Subtype value for association-response management frames * * Association response frames are sent by the Access Point to confirm * or deny the association requested in an association request frame. */ #define IEEE80211_STYPE_ASSOC_RESP 0x0010 /** Subtype value for reassociation-request management frames * * Reassociation request frames are sent by clients wishing to change * from one Access Point to another while roaming within the same * extended network (same ESSID). */ #define IEEE80211_STYPE_REASSOC_REQ 0x0020 /** Subtype value for reassociation-response management frames * * Reassociation response frames are sent by the Access Point to * confirm or deny the swap requested in a reassociation request * frame. */ #define IEEE80211_STYPE_REASSOC_RESP 0x0030 /** Subtype value for probe-request management frames * * Probe request frames are sent by clients to request that all Access * Points on the sending channel, or all belonging to a particular * ESSID, identify themselves by BSSID, supported transfer rates, RF * configuration, and other capabilities. */ #define IEEE80211_STYPE_PROBE_REQ 0x0040 /** Subtype value for probe-response management frames * * Probe response frames are sent by Access Points in response to * probe request frames, providing the requested information. */ #define IEEE80211_STYPE_PROBE_RESP 0x0050 /** Subtype value for beacon management frames * * Beacon frames are sent by Access Points at regular intervals, * usually ten per second, on the channel on which they communicate. * They can be used to probe passively for access points on a channel * where local regulatory restrictions prohibit active scanning, or * due to their regularity as a mechanism to determine the fraction of * packets that are being dropped. */ #define IEEE80211_STYPE_BEACON 0x0080 /** Subtype value for disassociation management frames * * Disassociation frames are sent by either a client or an Access * Point to unequivocally terminate the association between the two. * They may be sent by clients upon leaving the network, or by an * Access Point upon reconfiguration, among other reasons; they are * usually more "polite" than deauthentication frames. */ #define IEEE80211_STYPE_DISASSOC 0x00A0 /** Subtype value for authentication management frames * * Authentication frames are exchanged between a client and an Access * Point before association may be performed. Confusingly, in the most * common authentication method (Open System) no security tokens are * exchanged at all. Modern 802.11 security handshaking takes place * after association. */ #define IEEE80211_STYPE_AUTH 0x00B0 /** Subtype value for deauthentication management frames * * Deauthentication frames are sent by either a client or an Access * Point to terminate the authentication (and therefore also the * association) between the two. They are generally more forceful than * disassociation frames, sent for such reasons as a failure to * set up security properly after associating. */ #define IEEE80211_STYPE_DEAUTH 0x00C0 /** Subtype value for action management frames * * Action frames are used to implement spectrum management and QoS * features that gPXE currently does not support. */ #define IEEE80211_STYPE_ACTION 0x00D0 /** Subtype value for RTS (request to send) control frames */ #define IEEE80211_STYPE_RTS 0x00B0 /** Subtype value for CTS (clear to send) control frames */ #define IEEE80211_STYPE_CTS 0x00C0 /** Subtype value for ACK (acknowledgement) control frames */ #define IEEE80211_STYPE_ACK 0x00D0 /** Subtype value for ordinary data frames, with no QoS or CF add-ons */ #define IEEE80211_STYPE_DATA 0x0000 /** Subtype value for data frames containing no data */ #define IEEE80211_STYPE_NODATA 0x0040 /** 802.11 Frame Control field: To Data System flag * * This is set on data frames sent to an Access Point. */ #define IEEE80211_FC_TODS 0x0100 /** 802.11 Frame Control field: From Data System flag * * This is set on data frames sent from an Access Point. If both TODS * and FROMDS are set, the frame header is a 4-address format used for * inter-Access Point communication. */ #define IEEE80211_FC_FROMDS 0x0200 /** 802.11 Frame Control field: More Fragments flag */ #define IEEE80211_FC_MORE_FRAG 0x0400 /** 802.11 Frame Control field: Retransmission flag */ #define IEEE80211_FC_RETRY 0x0800 /** 802.11 Frame Control field: Power Managed flag * * This is set on any frame sent by a low-power station that will go * into a power-saving mode immediately after this frame. Access * Points are not allowed to act as low-power stations. */ #define IEEE80211_FC_PWR_MGMT 0x1000 /** 802.11 Frame Control field: More Data flag * * This is set on any frame sent by a station that has more data * queued to be sent than is in the frame. */ #define IEEE80211_FC_MORE_DATA 0x2000 /** 802.11 Frame Control field: Protected flag * * This is set on frames in which data is encrypted (by any method). */ #define IEEE80211_FC_PROTECTED 0x4000 /** 802.11 Frame Control field: Ordered flag [?] */ #define IEEE80211_FC_ORDER 0x8000 /** @} */ /* ---------- Sequence Control defines ---------- */ /** * @defgroup ieee80211_seq 802.11 Sequence Control field handling * @{ */ /** Extract sequence number from 802.11 Sequence Control field */ #define IEEE80211_SEQNR( seq ) ( ( seq ) >> 4 ) /** Extract fragment number from 802.11 Sequence Control field */ #define IEEE80211_FRAG( seq ) ( ( seq ) & 0x000F ) /** Make 802.11 Sequence Control field from sequence and fragment numbers */ #define IEEE80211_MAKESEQ( seqnr, frag ) \ ( ( ( ( seqnr ) & 0xFFF ) << 4 ) | ( ( frag ) & 0xF ) ) /** @} */ /* ---------- Frame header formats ---------- */ /** * @defgroup ieee80211_hdr 802.11 frame header formats * @{ */ /** An 802.11 data or management frame without QoS or WDS header fields */ struct ieee80211_frame { u16 fc; /**< 802.11 Frame Control field */ u16 duration; /**< Microseconds to reserve link */ u8 addr1[ETH_ALEN]; /**< Address 1 (immediate receiver) */ u8 addr2[ETH_ALEN]; /**< Address 2 (immediate sender) */ u8 addr3[ETH_ALEN]; /**< Address 3 (often "forward to") */ u16 seq; /**< 802.11 Sequence Control field */ u8 data[0]; /**< Beginning of frame data */ } __attribute__((packed)); /** The 802.2 LLC/SNAP header sent before actual data in a data frame * * This header is not acknowledged in the 802.11 standard at all; it * is treated just like data for MAC-layer purposes, including * fragmentation and encryption. It is actually two headers * concatenated: a three-byte 802.2 LLC header indicating Subnetwork * Accesss Protocol (SNAP) in both source and destination Service * Access Point (SAP) fields, and a five-byte SNAP header indicating a * zero OUI and two-byte Ethernet protocol type field. * * Thus, an eight-byte header in which six of the bytes are redundant. * Lovely, isn't it? */ struct ieee80211_llc_snap_header { /* LLC part: */ u8 dsap; /**< Destination SAP ID */ u8 ssap; /**< Source SAP ID */ u8 ctrl; /**< Control information */ /* SNAP part: */ u8 oui[3]; /**< Organization code, usually 0 */ u16 ethertype; /**< Ethernet Type field */ } __attribute__((packed)); /** Value for DSAP field in 802.2 LLC header for 802.11 frames: SNAP */ #define IEEE80211_LLC_DSAP 0xAA /** Value for SSAP field in 802.2 LLC header for 802.11 frames: SNAP */ #define IEEE80211_LLC_SSAP 0xAA /** Value for control field in 802.2 LLC header for 802.11 frames * * "Unnumbered Information". */ #define IEEE80211_LLC_CTRL 0x03 /** 16-byte RTS frame format, with abbreviated header */ struct ieee80211_rts { u16 fc; /**< 802.11 Frame Control field */ u16 duration; /**< Microseconds to reserve link */ u8 addr1[ETH_ALEN]; /**< Address 1 (immediate receiver) */ u8 addr2[ETH_ALEN]; /**< Address 2 (immediate sender) */ } __attribute__((packed)); /** Length of 802.11 RTS control frame */ #define IEEE80211_RTS_LEN 16 /** 10-byte CTS or ACK frame format, with abbreviated header */ struct ieee80211_cts_or_ack { u16 fc; /**< 802.11 Frame Control field */ u16 duration; /**< Microseconds to reserve link */ u8 addr1[ETH_ALEN]; /**< Address 1 (immediate receiver) */ } __attribute__((packed)); #define ieee80211_cts ieee80211_cts_or_ack #define ieee80211_ack ieee80211_cts_or_ack /** Length of 802.11 CTS control frame */ #define IEEE80211_CTS_LEN 10 /** Length of 802.11 ACK control frame */ #define IEEE80211_ACK_LEN 10 /** @} */ /* ---------- Capability bits, status and reason codes ---------- */ /** * @defgroup ieee80211_capab 802.11 management frame capability field bits * @{ */ /** Set if using an Access Point (managed mode) */ #define IEEE80211_CAPAB_MANAGED 0x0001 /** Set if operating in IBSS (no-AP, "Ad-Hoc") mode */ #define IEEE80211_CAPAB_ADHOC 0x0002 /** Set if we support Contention-Free Period operation */ #define IEEE80211_CAPAB_CFPOLL 0x0004 /** Set if we wish to be polled for Contention-Free operation */ #define IEEE80211_CAPAB_CFPR 0x0008 /** Set if the network is encrypted (by any method) */ #define IEEE80211_CAPAB_PRIVACY 0x0010 /** Set if PHY supports short preambles on 802.11b */ #define IEEE80211_CAPAB_SHORT_PMBL 0x0020 /** Set if PHY supports PBCC modulation */ #define IEEE80211_CAPAB_PBCC 0x0040 /** Set if we support Channel Agility */ #define IEEE80211_CAPAB_CHAN_AGILITY 0x0080 /** Set if we support spectrum management (DFS and TPC) on the 5GHz band */ #define IEEE80211_CAPAB_SPECTRUM_MGMT 0x0100 /** Set if we support Quality of Service enhancements */ #define IEEE80211_CAPAB_QOS 0x0200 /** Set if PHY supports short slot time on 802.11g */ #define IEEE80211_CAPAB_SHORT_SLOT 0x0400 /** Set if PHY supports APSD option */ #define IEEE80211_CAPAB_APSD 0x0800 /** Set if PHY supports DSSS/OFDM modulation (one way of 802.11 b/g mixing) */ #define IEEE80211_CAPAB_DSSS_OFDM 0x2000 /** Set if we support delayed block ACK */ #define IEEE80211_CAPAB_DELAYED_BACK 0x4000 /** Set if we support immediate block ACK */ #define IEEE80211_CAPAB_IMMED_BACK 0x8000 /** @} */ /** * @defgroup ieee80211_status 802.11 status codes * * These are returned to indicate an immediate denial of * authentication or association. In gPXE, the lower 5 bits of the * status code are encoded into the file-unique portion of an error * code, the ERRFILE portion is always @c ERRFILE_net80211, and the * POSIX error code is @c ECONNREFUSED for status 0-31 or @c * EHOSTUNREACH for status 32-63. * * For a complete table with non-abbreviated error messages, see IEEE * Std 802.11-2007, Table 7-23, p.94. * * @{ */ #define IEEE80211_STATUS_SUCCESS 0 #define IEEE80211_STATUS_FAILURE 1 #define IEEE80211_STATUS_CAPAB_UNSUPP 10 #define IEEE80211_STATUS_REASSOC_INVALID 11 #define IEEE80211_STATUS_ASSOC_DENIED 12 #define IEEE80211_STATUS_AUTH_ALGO_UNSUPP 13 #define IEEE80211_STATUS_AUTH_SEQ_INVALID 14 #define IEEE80211_STATUS_AUTH_CHALL_INVALID 15 #define IEEE80211_STATUS_AUTH_TIMEOUT 16 #define IEEE80211_STATUS_ASSOC_NO_ROOM 17 #define IEEE80211_STATUS_ASSOC_NEED_RATE 18 #define IEEE80211_STATUS_ASSOC_NEED_SHORT_PMBL 19 #define IEEE80211_STATUS_ASSOC_NEED_PBCC 20 #define IEEE80211_STATUS_ASSOC_NEED_CHAN_AGILITY 21 #define IEEE80211_STATUS_ASSOC_NEED_SPECTRUM_MGMT 22 #define IEEE80211_STATUS_ASSOC_BAD_POWER 23 #define IEEE80211_STATUS_ASSOC_BAD_CHANNELS 24 #define IEEE80211_STATUS_ASSOC_NEED_SHORT_SLOT 25 #define IEEE80211_STATUS_ASSOC_NEED_DSSS_OFDM 26 #define IEEE80211_STATUS_QOS_FAILURE 32 #define IEEE80211_STATUS_QOS_NO_ROOM 33 #define IEEE80211_STATUS_LINK_IS_HORRIBLE 34 #define IEEE80211_STATUS_ASSOC_NEED_QOS 35 #define IEEE80211_STATUS_REQUEST_DECLINED 37 #define IEEE80211_STATUS_REQUEST_INVALID 38 #define IEEE80211_STATUS_TS_NOT_CREATED_AGAIN 39 #define IEEE80211_STATUS_INVALID_IE 40 #define IEEE80211_STATUS_GROUP_CIPHER_INVALID 41 #define IEEE80211_STATUS_PAIR_CIPHER_INVALID 42 #define IEEE80211_STATUS_AKMP_INVALID 43 #define IEEE80211_STATUS_RSN_VERSION_UNSUPP 44 #define IEEE80211_STATUS_RSN_CAPAB_INVALID 45 #define IEEE80211_STATUS_CIPHER_REJECTED 46 #define IEEE80211_STATUS_TS_NOT_CREATED_WAIT 47 #define IEEE80211_STATUS_DIRECT_LINK_FORBIDDEN 48 #define IEEE80211_STATUS_DEST_NOT_PRESENT 49 #define IEEE80211_STATUS_DEST_NOT_QOS 50 #define IEEE80211_STATUS_ASSOC_LISTEN_TOO_HIGH 51 /** @} */ /** * @defgroup ieee80211_reason 802.11 reason codes * * These are returned to indicate the reason for a deauthentication or * disassociation sent (usually) after authentication or association * had succeeded. In gPXE, the lower 5 bits of the reason code are * encoded into the file-unique portion of an error code, the ERRFILE * portion is always @c ERRFILE_net80211, and the POSIX error code is * @c ECONNRESET for reason 0-31 or @c ENETRESET for reason 32-63. * * For a complete table with non-abbreviated error messages, see IEEE * Std 802.11-2007, Table 7-22, p.92. * * @{ */ #define IEEE80211_REASON_NONE 0 #define IEEE80211_REASON_UNSPECIFIED 1 #define IEEE80211_REASON_AUTH_NO_LONGER_VALID 2 #define IEEE80211_REASON_LEAVING 3 #define IEEE80211_REASON_INACTIVITY 4 #define IEEE80211_REASON_OUT_OF_RESOURCES 5 #define IEEE80211_REASON_NEED_AUTH 6 #define IEEE80211_REASON_NEED_ASSOC 7 #define IEEE80211_REASON_LEAVING_TO_ROAM 8 #define IEEE80211_REASON_REASSOC_INVALID 9 #define IEEE80211_REASON_BAD_POWER 10 #define IEEE80211_REASON_BAD_CHANNELS 11 #define IEEE80211_REASON_INVALID_IE 13 #define IEEE80211_REASON_MIC_FAILURE 14 #define IEEE80211_REASON_4WAY_TIMEOUT 15 #define IEEE80211_REASON_GROUPKEY_TIMEOUT 16 #define IEEE80211_REASON_4WAY_INVALID 17 #define IEEE80211_REASON_GROUP_CIPHER_INVALID 18 #define IEEE80211_REASON_PAIR_CIPHER_INVALID 19 #define IEEE80211_REASON_AKMP_INVALID 20 #define IEEE80211_REASON_RSN_VERSION_INVALID 21 #define IEEE80211_REASON_RSN_CAPAB_INVALID 22 #define IEEE80211_REASON_8021X_FAILURE 23 #define IEEE80211_REASON_CIPHER_REJECTED 24 #define IEEE80211_REASON_QOS_UNSPECIFIED 32 #define IEEE80211_REASON_QOS_OUT_OF_RESOURCES 33 #define IEEE80211_REASON_LINK_IS_HORRIBLE 34 #define IEEE80211_REASON_INVALID_TXOP 35 #define IEEE80211_REASON_REQUESTED_LEAVING 36 #define IEEE80211_REASON_REQUESTED_NO_USE 37 #define IEEE80211_REASON_REQUESTED_NEED_SETUP 38 #define IEEE80211_REASON_REQUESTED_TIMEOUT 39 #define IEEE80211_REASON_CIPHER_UNSUPPORTED 45 /** @} */ /* ---------- Information element declarations ---------- */ /** * @defgroup ieee80211_ie 802.11 information elements * * Many management frames include a section that amounts to a * concatenation of these information elements, so that the sender can * choose which information to send and the receiver can ignore the * parts it doesn't understand. Each IE contains a two-byte header, * one byte ID and one byte length, followed by IE-specific data. The * length does not include the two-byte header. Information elements * are required to be sorted by ID, but gPXE does not require that in * those it receives. * * This group also includes a few inline functions to simplify common * tasks in IE processing. * * @{ */ /** Generic 802.11 information element header */ struct ieee80211_ie_header { u8 id; /**< Information element ID */ u8 len; /**< Information element length */ } __attribute__ ((packed)); /** 802.11 SSID information element */ struct ieee80211_ie_ssid { u8 id; /**< SSID ID: 0 */ u8 len; /**< SSID length */ char ssid[0]; /**< SSID data, not NUL-terminated */ } __attribute__ ((packed)); /** Information element ID for SSID information element */ #define IEEE80211_IE_SSID 0 /** 802.11 rates information element * * The first 8 rates go in an IE of type RATES (1), and any more rates * go in one of type EXT_RATES (50). Each rate is a byte with the low * 7 bits equal to the rate in units of 500 kbps, and the high bit set * if and only if the rate is "basic" (must be supported by all * connected stations). */ struct ieee80211_ie_rates { u8 id; /**< Rates ID: 1 or 50 */ u8 len; /**< Number of rates */ u8 rates[0]; /**< Rates data, one rate per byte */ } __attribute__ ((packed)); /** Information element ID for rates information element */ #define IEEE80211_IE_RATES 1 /** Information element ID for extended rates information element */ #define IEEE80211_IE_EXT_RATES 50 /** 802.11 Direct Spectrum parameter information element * * This just contains the channel number. It has the fancy name * because IEEE 802.11 also defines a frequency-hopping PHY that * changes channels at regular intervals following a predetermined * pattern; in practice nobody uses the FH PHY. */ struct ieee80211_ie_ds_param { u8 id; /**< DS parameter ID: 3 */ u8 len; /**< DS parameter length: 1 */ u8 current_channel; /**< Current channel number, 1-14 */ } __attribute__ ((packed)); /** Information element ID for Direct Spectrum parameter information element */ #define IEEE80211_IE_DS_PARAM 3 /** 802.11 Country information element regulatory extension triplet */ struct ieee80211_ie_country_ext_triplet { u8 reg_ext_id; /**< Regulatory extension ID */ u8 reg_class_id; /**< Regulatory class ID */ u8 coverage_class; /**< Coverage class */ } __attribute__ ((packed)); /** 802.11 Country information element regulatory band triplet */ struct ieee80211_ie_country_band_triplet { u8 first_channel; /**< Channel number for first channel in band */ u8 nr_channels; /**< Number of contiguous channels in band */ u8 max_txpower; /**< Maximum TX power in dBm */ } __attribute__ ((packed)); /** 802.11 Country information element regulatory triplet * * It is a band triplet if the first byte is 200 or less, and a * regulatory extension triplet otherwise. */ union ieee80211_ie_country_triplet { /** Differentiator between band and ext triplets */ u8 first; /** Information about a band of channels */ struct ieee80211_ie_country_band_triplet band; /** Regulatory extension information */ struct ieee80211_ie_country_ext_triplet ext; }; /** 802.11 Country information element * * This contains some data about RF regulations. */ struct ieee80211_ie_country { u8 id; /**< Country information ID: 7 */ u8 len; /**< Country information length: varies */ char name[2]; /**< ISO Alpha2 country code */ char in_out; /**< 'I' for indoor, 'O' for outdoor */ /** List of regulatory triplets */ union ieee80211_ie_country_triplet triplet[0]; } __attribute__ ((packed)); /** Information element ID for Country information element */ #define IEEE80211_IE_COUNTRY 7 /** 802.11 Request information element * * This contains a list of information element types we would like to * be included in probe response frames. */ struct ieee80211_ie_request { u8 id; /**< Request ID: 10 */ u8 len; /**< Number of IEs requested */ u8 request[0]; /**< List of IEs requested */ } __attribute__ ((packed)); /** Information element ID for Request information element */ #define IEEE80211_IE_REQUEST 10 /** 802.11 Challenge Text information element * * This is used in authentication frames under Shared Key * authentication. */ struct ieee80211_ie_challenge_text { u8 id; /**< Challenge Text ID: 16 */ u8 len; /**< Challenge Text length: usually 128 */ u8 challenge_text[0]; /**< Challenge Text data */ } __attribute__ ((packed)); /** Information element ID for Challenge Text information element */ #define IEEE80211_IE_CHALLENGE_TEXT 16 /** 802.11 Power Constraint information element * * This is used to specify an additional power limitation on top of * the Country requirements. */ struct ieee80211_ie_power_constraint { u8 id; /**< Power Constraint ID: 52 */ u8 len; /**< Power Constraint length: 1 */ u8 power_constraint; /**< Decrease in allowed TX power, dBm */ } __attribute__ ((packed)); /** Information element ID for Power Constraint information element */ #define IEEE80211_IE_POWER_CONSTRAINT 52 /** 802.11 Power Capability information element * * This is used in association request frames to indicate the extremes * of our TX power abilities. It is required only if we indicate * support for spectrum management. */ struct ieee80211_ie_power_capab { u8 id; /**< Power Capability ID: 33 */ u8 len; /**< Power Capability length: 2 */ u8 min_txpower; /**< Minimum possible TX power, dBm */ u8 max_txpower; /**< Maximum possible TX power, dBm */ } __attribute__ ((packed)); /** Information element ID for Power Capability information element */ #define IEEE80211_IE_POWER_CAPAB 33 /** 802.11 Channels information element channel band tuple */ struct ieee80211_ie_channels_channel_band { u8 first_channel; /**< Channel number of first channel in band */ u8 nr_channels; /**< Number of channels in band */ } __attribute__ ((packed)); /** 802.11 Channels information element * * This is used in association frames to indicate the channels we can * use. It is required only if we indicate support for spectrum * management. */ struct ieee80211_ie_channels { u8 id; /**< Channels ID: 36 */ u8 len; /**< Channels length: 2 */ /** List of (start, length) channel bands we can use */ struct ieee80211_ie_channels_channel_band channels[0]; } __attribute__ ((packed)); /** Information element ID for Channels information element */ #define IEEE80211_IE_CHANNELS 36 /** 802.11 ERP Information information element * * This is used to communicate some PHY-level flags. */ struct ieee80211_ie_erp_info { u8 id; /**< ERP Information ID: 42 */ u8 len; /**< ERP Information length: 1 */ u8 erp_info; /**< ERP flags */ } __attribute__ ((packed)); /** Information element ID for ERP Information information element */ #define IEEE80211_IE_ERP_INFO 42 /** ERP information element: Flag set if 802.11b stations are present */ #define IEEE80211_ERP_NONERP_PRESENT 0x01 /** ERP information element: Flag set if CTS protection must be used */ #define IEEE80211_ERP_USE_PROTECTION 0x02 /** ERP information element: Flag set if long preambles must be used */ #define IEEE80211_ERP_BARKER_LONG 0x04 /** 802.11 Robust Security Network ("WPA") information element * * Showing once again a striking clarity of design, the IEEE folks put * dynamically-sized data in the middle of this structure. As such, * the below structure definition is only a guideline; the * @c IEEE80211_RSN_FIELD, @c IEEE80211_RSN_CIPHER, and * @c IEEE80211_RSN_AUTHTYPE macros should be used to access any * data. * * Also inspired was IEEE's choice of 16-bit fields to count the * number of 4-byte elements in a structure with a maximum length of * 255 bytes. * * Many fields reference a cipher or authentication-type ID; this is a * three-byte OUI followed by one byte identifying the cipher with * respect to that OUI. For all standard ciphers the OUI is 00:0F:AC. * * The authentication types referenced in this structure have nothing * to do with 802.11 authentication frames or the @c algorithm field * within them. */ struct ieee80211_ie_rsn { /** Information element ID */ u8 id; /** Information element length */ u8 len; /** RSN information element version */ u16 version; /** Cipher ID for the cipher used in multicast/broadcast frames */ u8 group_cipher[4]; /** Number of unicast ciphers supported */ u16 pairwise_count; /** List of cipher IDs for supported unicast frame ciphers */ u8 pairwise_cipher[4]; /** Number of authentication types supported */ u16 akm_count; /** List of authentication type IDs for supported types */ u8 akm_list[4]; /** Security capabilities field. */ u16 rsn_capab; /** Number of PMKIDs included (present only in association frames) */ u16 pmkid_count; /** List of PMKIDs included, each a 16-byte SHA1 hash */ u8 pmkid_list[0]; } __attribute__((packed)); /** Information element ID for Robust Security Network information element */ #define IEEE80211_IE_RSN 48 /** OUI for standard ciphers in RSN information element */ #define IEEE80211_RSN_OUI "\x00\x0F\xAC" /** Extract RSN IE version field */ #define IEEE80211_RSN_FIELD_version( rsnp ) ( (rsnp)->version ) /** Extract RSN IE group_cipher field */ #define IEEE80211_RSN_FIELD_group_cipher( rsnp ) ( (rsnp)->group_cipher ) /** Extract RSN IE pairwise_count field */ #define IEEE80211_RSN_FIELD_pairwise_count( rsnp ) ( (rsnp)->pairwise_count ) /** Extract RSN IE akm_count field */ #define IEEE80211_RSN_FIELD_akm_count( rsnp ) \ ( ( ( struct ieee80211_ie_rsn * ) ( ( void * ) ( rsnp ) + \ 4*( ( rsnp )->pairwise_count - 1 ) ) )->akm_count ) /** Extract RSN IE rsn_capab field */ #define IEEE80211_RSN_FIELD_rsn_capab( rsnp ) \ ( ( ( struct ieee80211_ie_rsn * ) ( ( void * ) ( rsnp ) + \ 4*( ( rsnp )->pairwise_count - 1 ) + \ 4*( ( rsnp )->akm_count - 1 ) ) )->rsn_capab ) /** Extract RSN IE pmkid_count field */ #define IEEE80211_RSN_FIELD_pmkid_count( rsnp ) \ ( ( ( struct ieee80211_ie_rsn * ) ( ( void * ) ( rsnp ) + \ 4*( ( rsnp )->pairwise_count - 1 ) + \ 4*( ( rsnp )->akm_count - 1 ) ) )->pmkid_count ) /** Extract field from RSN information element * * @v rsnp Pointer to RSN information element * @v field Name of field to extract * @ret val Lvalue of the requested field * * You must fill the fields of the structure in order for this to work * properly. */ #define IEEE80211_RSN_FIELD( rsnp, field ) \ IEEE80211_RSN_FIELD_ ## field ( rsnp ) /** Get pointer to pairwise cipher from RSN information element * * @v rsnp Pointer to RSN information element * @v cipher Index of pairwise cipher to extract * @ret ptr Pointer to requested cipher */ #define IEEE80211_RSN_CIPHER( rsnp, cipher ) \ ( ( rsnp )->pairwise_cipher + 4 * ( cipher ) ) /** Get pointer to authentication type from RSN information element * * @v rsnp Pointer to RSN information element * @v akm Index of authentication type to extract * @ret ptr Pointer to requested authentication type * * The @c pairwise_count field must be correct. */ #define IEEE80211_RSN_AUTHTYPE( rsnp, akm ) \ ( ( rsnp )->akm_list + 4 * ( ( rsnp )->pairwise_count - 1 ) + 4 * ( akm ) ) /** Get pointer to PMKID from RSN information element * * @v rsnp Pointer to RSN information element * @v idx Index of PMKID to extract * @ret ptr Pointer to requested PMKID * * The @c pairwise_count and @c akm_count fields must be correct. */ #define IEEE80211_RSN_PMKID( rsnp, idx ) \ ( ( rsnp )->pmkid_list + 4 * ( ( rsnp )->pairwise_count - 1 ) + \ 4 * ( ( rsnp )->akm_count - 1 ) + 16 * ( idx ) ) /** Verify size of RSN information element * * @v rsnp Pointer to RSN information element * @ret ok TRUE if count fields are consistent with length field * * It is important to drop any RSN IE that does not pass this function * before using the @c IEEE80211_RSN_FIELD, @c IEEE80211_RSN_CIPHER, * and @c IEEE80211_RSN_AUTHTYPE macros, to avoid potential security * compromise due to a malformed RSN IE. * * This function does not consider the possibility of some PMKIDs * included in the RSN IE, because PMKIDs are only included in RSN IEs * sent in association request frames, and we should never receive an * association request frame. An RSN IE that includes PMKIDs will * always fail this check. */ static inline int ieee80211_rsn_check ( struct ieee80211_ie_rsn *rsnp ) { if ( rsnp->len < 12 + 4 * rsnp->pairwise_count ) return 0; return ( rsnp->len == 12 + 4 * ( rsnp->pairwise_count + IEEE80211_RSN_FIELD ( rsnp, akm_count ) ) ); } /** Calculate necessary size of RSN information element * * @v npair Number of pairwise ciphers supported * @v nauth Number of authentication types supported * @v npmkid Number of PMKIDs to include * @ret size Necessary size of RSN IE, including header bytes */ static inline size_t ieee80211_rsn_size ( int npair, int nauth, int npmkid ) { return 16 + 4 * ( npair + nauth ) + 16 * npmkid; } /** 802.11 RSN IE: expected version number */ #define IEEE80211_RSN_VERSION 1 /** 802.11 RSN IE: fourth byte of cipher type for 40-bit WEP */ #define IEEE80211_RSN_CTYPE_WEP40 1 /** 802.11 RSN IE: fourth byte of cipher type for 104-bit WEP */ #define IEEE80211_RSN_CTYPE_WEP104 5 /** 802.11 RSN IE: fourth byte of cipher type for TKIP ("WPA") */ #define IEEE80211_RSN_CTYPE_TKIP 2 /** 802.11 RSN IE: fourth byte of cipher type for CCMP ("WPA2") */ #define IEEE80211_RSN_CTYPE_CCMP 4 /** 802.11 RSN IE: fourth byte of cipher type for "use group" * * This can only appear as a pairwise cipher, and means unicast frames * should be encrypted in the same way as broadcast/multicast frames. */ #define IEEE80211_RSN_CTYPE_USEGROUP 0 /** 802.11 RSN IE: fourth byte of auth method type for using an 802.1X server */ #define IEEE80211_RSN_ATYPE_8021X 1 /** 802.11 RSN IE: fourth byte of auth method type for using a pre-shared key */ #define IEEE80211_RSN_ATYPE_PSK 2 /** 802.11 RSN IE capabilities: AP supports pre-authentication */ #define IEEE80211_RSN_CAPAB_PREAUTH 0x001 /** 802.11 RSN IE capabilities: Node has conflict between TKIP and WEP * * This is a legacy issue; APs always set it to 0, and gPXE sets it to * 0. */ #define IEEE80211_RSN_CAPAB_NO_PAIRWISE 0x002 /** 802.11 RSN IE capabilities: Number of PTKSA replay counters * * A value of 0 means one replay counter, 1 means two, 2 means four, * and 3 means sixteen. */ #define IEEE80211_RSN_CAPAB_PTKSA_REPLAY 0x00C /** 802.11 RSN IE capabilities: Number of GTKSA replay counters * * A value of 0 means one replay counter, 1 means two, 2 means four, * and 3 means sixteen. */ #define IEEE80211_RSN_CAPAB_GTKSA_REPLAY 0x030 /** 802.11 RSN IE capabilities: PeerKey Handshaking is suported */ #define IEEE80211_RSN_CAPAB_PEERKEY 0x200 /** Any 802.11 information element * * This is formatted for ease of use, so IEs with complex structures * get referenced in full, while those with only one byte of data or a * simple array are pulled in to avoid a layer of indirection like * ie->channels.channels[0]. */ union ieee80211_ie { /** Generic and simple information element info */ struct { u8 id; /**< Information element ID */ u8 len; /**< Information element data length */ union { char ssid[0]; /**< SSID text */ u8 rates[0]; /**< Rates data */ u8 request[0]; /**< Request list */ u8 challenge_text[0]; /**< Challenge text data */ u8 power_constraint; /**< Power constraint, dBm */ u8 erp_info; /**< ERP information flags */ /** List of channels */ struct ieee80211_ie_channels_channel_band channels[0]; }; }; /** DS parameter set */ struct ieee80211_ie_ds_param ds_param; /** Country information */ struct ieee80211_ie_country country; /** Power capability */ struct ieee80211_ie_power_capab power_capab; /** Security information */ struct ieee80211_ie_rsn rsn; }; /** Advance to next 802.11 information element * * @v ie Current information element pointer * @v end Pointer to first byte not in information element space * @ret next Pointer to next information element, or NULL if no more * * When processing received IEs, @a end should be set to the I/O * buffer tail pointer; when marshalling IEs for sending, @a end * should be NULL. */ static inline union ieee80211_ie * ieee80211_next_ie ( union ieee80211_ie *ie, void *end ) { void *next_ie_byte = ( void * ) ie + ie->len + 2; union ieee80211_ie *next_ie = next_ie_byte; if ( ! end ) return next_ie; if ( next_ie_byte < end && next_ie_byte + next_ie->len <= end ) return next_ie; return NULL; } /** @} */ /* ---------- Management frame data formats ---------- */ /** * @defgroup ieee80211_mgmt_data Management frame data payloads * @{ */ /** Beacon or probe response frame data */ struct ieee80211_beacon_or_probe_resp { /** 802.11 TSFT value at frame send */ u64 timestamp; /** Interval at which beacons are sent, in units of 1024 us */ u16 beacon_interval; /** Capability flags */ u16 capability; /** List of information elements */ union ieee80211_ie info_element[0]; } __attribute__((packed)); #define ieee80211_beacon ieee80211_beacon_or_probe_resp #define ieee80211_probe_resp ieee80211_beacon_or_probe_resp /** Disassociation or deauthentication frame data */ struct ieee80211_disassoc_or_deauth { /** Reason code */ u16 reason; } __attribute__((packed)); #define ieee80211_disassoc ieee80211_disassoc_or_deauth #define ieee80211_deauth ieee80211_disassoc_or_deauth /** Association request frame data */ struct ieee80211_assoc_req { /** Capability flags */ u16 capability; /** Interval at which we wake up, in units of the beacon interval */ u16 listen_interval; /** List of information elements */ union ieee80211_ie info_element[0]; } __attribute__((packed)); /** Association or reassociation response frame data */ struct ieee80211_assoc_or_reassoc_resp { /** Capability flags */ u16 capability; /** Status code */ u16 status; /** Association ID */ u16 aid; /** List of information elements */ union ieee80211_ie info_element[0]; } __attribute__((packed)); #define ieee80211_assoc_resp ieee80211_assoc_or_reassoc_resp #define ieee80211_reassoc_resp ieee80211_assoc_or_reassoc_resp /** Reassociation request frame data */ struct ieee80211_reassoc_req { /** Capability flags */ u16 capability; /** Interval at which we wake up, in units of the beacon interval */ u16 listen_interval; /** MAC address of current Access Point */ u8 current_addr[ETH_ALEN]; /** List of information elements */ union ieee80211_ie info_element[0]; } __attribute__((packed)); /** Probe request frame data */ struct ieee80211_probe_req { /** List of information elements */ union ieee80211_ie info_element[0]; } __attribute__((packed)); /** Authentication frame data */ struct ieee80211_auth { /** Authentication algorithm (Open System or Shared Key) */ u16 algorithm; /** Sequence number of this frame; first from client to AP is 1 */ u16 tx_seq; /** Status code */ u16 status; /** List of information elements */ union ieee80211_ie info_element[0]; } __attribute__((packed)); /** Open System authentication algorithm */ #define IEEE80211_AUTH_OPEN_SYSTEM 0 /** Shared Key authentication algorithm */ #define IEEE80211_AUTH_SHARED_KEY 1 /** @} */ #endif debian/grub-extras/disabled/gpxe/src/include/gpxe/x509.h0000664000000000000000000000133012524662415020204 0ustar #ifndef _GPXE_X509_H #define _GPXE_X509_H /** @file * * X.509 certificates * */ FILE_LICENCE ( GPL2_OR_LATER ); #include struct asn1_cursor; /** An X.509 RSA public key */ struct x509_rsa_public_key { /** Modulus */ uint8_t *modulus; /** Modulus length */ size_t modulus_len; /** Exponent */ uint8_t *exponent; /** Exponent length */ size_t exponent_len; }; /** * Free X.509 RSA public key * * @v rsa_pubkey RSA public key */ static inline void x509_free_rsa_public_key ( struct x509_rsa_public_key *rsa_pubkey ) { free ( rsa_pubkey->modulus ); } extern int x509_rsa_public_key ( const struct asn1_cursor *certificate, struct x509_rsa_public_key *rsa_pubkey ); #endif /* _GPXE_X509_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/posix_io.h0000664000000000000000000000352112524662415021334 0ustar #ifndef _GPXE_POSIX_IO_H #define _GPXE_POSIX_IO_H /** @file * * POSIX-like I/O * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** Minimum file descriptor that will ever be allocated */ #define POSIX_FD_MIN ( 1 ) /** Maximum file descriptor that will ever be allocated */ #define POSIX_FD_MAX ( 31 ) /** File descriptor set as used for select() */ typedef uint32_t fd_set; extern int open ( const char *uri_string ); extern ssize_t read_user ( int fd, userptr_t buffer, off_t offset, size_t len ); extern int select ( fd_set *readfds, int wait ); extern ssize_t fsize ( int fd ); extern int close ( int fd ); /** * Zero a file descriptor set * * @v set File descriptor set */ static inline __attribute__ (( always_inline )) void FD_ZERO ( fd_set *set ) { *set = 0; } /** * Set a bit within a file descriptor set * * @v fd File descriptor * @v set File descriptor set */ static inline __attribute__ (( always_inline )) void FD_SET ( int fd, fd_set *set ) { *set |= ( 1 << fd ); } /** * Clear a bit within a file descriptor set * * @v fd File descriptor * @v set File descriptor set */ static inline __attribute__ (( always_inline )) void FD_CLR ( int fd, fd_set *set ) { *set &= ~( 1 << fd ); } /** * Test a bit within a file descriptor set * * @v fd File descriptor * @v set File descriptor set * @ret is_set Corresponding bit is set */ static inline __attribute__ (( always_inline )) int FD_ISSET ( int fd, fd_set *set ) { return ( *set & ( 1 << fd ) ); } /** * Read data from file * * @v fd File descriptor * @v buf Data buffer * @v len Maximum length to read * @ret len Actual length read, or negative error number */ static inline ssize_t read ( int fd, void *buf, size_t len ) { return read_user ( fd, virt_to_user ( buf ), 0, len ); } #endif /* _GPXE_POSIX_IO_H */ debian/grub-extras/disabled/gpxe/src/include/gpxe/bitbash.h0000664000000000000000000000236212524662415021121 0ustar #ifndef _GPXE_BITBASH_H #define _GPXE_BITBASH_H /** @file * * Bit-bashing interfaces * */ FILE_LICENCE ( GPL2_OR_LATER ); struct bit_basher; /** Bit-bashing operations */ struct bit_basher_operations { /** * Set/clear output bit * * @v basher Bit-bashing interface * @v bit_id Bit number * @v data Value to write * * @c data will be 0 if a logic 0 should be written (i.e. the * bit should be cleared), or -1UL if a logic 1 should be * written (i.e. the bit should be set). This is done so that * the method may simply binary-AND @c data with the * appropriate bit mask. */ void ( * write ) ( struct bit_basher *basher, unsigned int bit_id, unsigned long data ); /** * Read input bit * * @v basher Bit-bashing interface * @v bit_id Bit number * @ret zero Input is a logic 0 * @ret non-zero Input is a logic 1 */ int ( * read ) ( struct bit_basher *basher, unsigned int bit_id ); }; /** A bit-bashing interface */ struct bit_basher { /** Bit-bashing operations */ struct bit_basher_operations *op; }; extern void write_bit ( struct bit_basher *basher, unsigned int bit_id, unsigned long data ); extern int read_bit ( struct bit_basher *basher, unsigned int bit_id ); #endif /* _GPXE_BITBASH_H */ debian/grub-extras/disabled/gpxe/src/core/0000775000000000000000000000000012524676037015700 5ustar debian/grub-extras/disabled/gpxe/src/core/process.c0000664000000000000000000000542212524662415017520 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include /** @file * * Processes * * We implement a trivial form of cooperative multitasking, in which * all processes share a single stack and address space. */ /** Process run queue */ static LIST_HEAD ( run_queue ); /** * Add process to process list * * @v process Process * * It is safe to call process_add() multiple times; further calls will * have no effect. */ void process_add ( struct process *process ) { if ( list_empty ( &process->list ) ) { DBGC ( process, "PROCESS %p starting\n", process ); ref_get ( process->refcnt ); list_add_tail ( &process->list, &run_queue ); } else { DBGC ( process, "PROCESS %p already started\n", process ); } } /** * Remove process from process list * * @v process Process * * It is safe to call process_del() multiple times; further calls will * have no effect. */ void process_del ( struct process *process ) { if ( ! list_empty ( &process->list ) ) { DBGC ( process, "PROCESS %p stopping\n", process ); list_del ( &process->list ); INIT_LIST_HEAD ( &process->list ); ref_put ( process->refcnt ); } else { DBGC ( process, "PROCESS %p already stopped\n", process ); } } /** * Single-step a single process * * This executes a single step of the first process in the run queue, * and moves the process to the end of the run queue. */ void step ( void ) { struct process *process; list_for_each_entry ( process, &run_queue, list ) { list_del ( &process->list ); list_add_tail ( &process->list, &run_queue ); DBGC2 ( process, "PROCESS %p executing\n", process ); process->step ( process ); DBGC2 ( process, "PROCESS %p finished executing\n", process ); break; } } /** * Initialise processes * */ static void init_processes ( void ) { struct process *process; for_each_table_entry ( process, PERMANENT_PROCESSES ) process_add ( process ); } /** Process initialiser */ struct init_fn process_init_fn __init_fn ( INIT_NORMAL ) = { .initialise = init_processes, }; debian/grub-extras/disabled/gpxe/src/core/basename.c0000664000000000000000000000270512524662415017616 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); /** * @file * * Get base name of path * */ #include #include /** * Return base name from path * * @v path Full path * @ret basename Base name */ char * basename ( char *path ) { char *basename; basename = strrchr ( path, '/' ); return ( basename ? ( basename + 1 ) : path ); } /** * Return directory name from path * * @v path Full path * @ret dirname Directory name * * Note that this function may modify its argument. */ char * dirname ( char *path ) { char *separator; separator = strrchr ( path, '/' ); if ( separator == path ) { return "/"; } else if ( separator ) { *separator = 0; return path; } else { return "."; } } debian/grub-extras/disabled/gpxe/src/core/uuid.c0000664000000000000000000000277212524662415017015 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include /** @file * * Universally unique IDs * */ /** * Convert UUID to printable string * * @v uuid UUID * @ret string UUID in canonical form */ char * uuid_ntoa ( union uuid *uuid ) { static char buf[37]; /* "00000000-0000-0000-0000-000000000000" */ snprintf ( buf, sizeof (buf), "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", be32_to_cpu ( uuid->canonical.a ), be16_to_cpu ( uuid->canonical.b ), be16_to_cpu ( uuid->canonical.c ), be16_to_cpu ( uuid->canonical.d ), uuid->canonical.e[0], uuid->canonical.e[1], uuid->canonical.e[2], uuid->canonical.e[3], uuid->canonical.e[4], uuid->canonical.e[5] ); return buf; } debian/grub-extras/disabled/gpxe/src/core/settings.c0000664000000000000000000011107512524662415017704 0ustar /* * Copyright (C) 2008 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * Configuration settings * */ /****************************************************************************** * * Generic settings blocks * ****************************************************************************** */ /** * A generic setting * */ struct generic_setting { /** List of generic settings */ struct list_head list; /** Setting */ struct setting setting; /** Size of setting name */ size_t name_len; /** Size of setting data */ size_t data_len; }; /** * Get generic setting name * * @v generic Generic setting * @ret name Generic setting name */ static inline void * generic_setting_name ( struct generic_setting *generic ) { return ( ( ( void * ) generic ) + sizeof ( *generic ) ); } /** * Get generic setting data * * @v generic Generic setting * @ret data Generic setting data */ static inline void * generic_setting_data ( struct generic_setting *generic ) { return ( ( ( void * ) generic ) + sizeof ( *generic ) + generic->name_len ); } /** * Find generic setting * * @v generics Generic settings block * @v setting Setting to find * @ret generic Generic setting, or NULL */ static struct generic_setting * find_generic_setting ( struct generic_settings *generics, struct setting *setting ) { struct generic_setting *generic; list_for_each_entry ( generic, &generics->list, list ) { if ( setting_cmp ( &generic->setting, setting ) == 0 ) return generic; } return NULL; } /** * Store value of generic setting * * @v settings Settings block * @v setting Setting to store * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ int generic_settings_store ( struct settings *settings, struct setting *setting, const void *data, size_t len ) { struct generic_settings *generics = container_of ( settings, struct generic_settings, settings ); struct generic_setting *old; struct generic_setting *new = NULL; size_t name_len; /* Identify existing generic setting, if any */ old = find_generic_setting ( generics, setting ); /* Create new generic setting, if required */ if ( len ) { /* Allocate new generic setting */ name_len = ( strlen ( setting->name ) + 1 ); new = zalloc ( sizeof ( *new ) + name_len + len ); if ( ! new ) return -ENOMEM; /* Populate new generic setting */ new->name_len = name_len; new->data_len = len; memcpy ( &new->setting, setting, sizeof ( new->setting ) ); new->setting.name = generic_setting_name ( new ); memcpy ( generic_setting_name ( new ), setting->name, name_len ); memcpy ( generic_setting_data ( new ), data, len ); } /* Delete existing generic setting, if any */ if ( old ) { list_del ( &old->list ); free ( old ); } /* Add new setting to list, if any */ if ( new ) list_add ( &new->list, &generics->list ); return 0; } /** * Fetch value of generic setting * * @v settings Settings block * @v setting Setting to fetch * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error */ int generic_settings_fetch ( struct settings *settings, struct setting *setting, void *data, size_t len ) { struct generic_settings *generics = container_of ( settings, struct generic_settings, settings ); struct generic_setting *generic; /* Find generic setting */ generic = find_generic_setting ( generics, setting ); if ( ! generic ) return -ENOENT; /* Copy out generic setting data */ if ( len > generic->data_len ) len = generic->data_len; memcpy ( data, generic_setting_data ( generic ), len ); return generic->data_len; } /** * Clear generic settings block * * @v settings Settings block */ void generic_settings_clear ( struct settings *settings ) { struct generic_settings *generics = container_of ( settings, struct generic_settings, settings ); struct generic_setting *generic; struct generic_setting *tmp; list_for_each_entry_safe ( generic, tmp, &generics->list, list ) { list_del ( &generic->list ); free ( generic ); } assert ( list_empty ( &generics->list ) ); } /** Generic settings operations */ struct settings_operations generic_settings_operations = { .store = generic_settings_store, .fetch = generic_settings_fetch, .clear = generic_settings_clear, }; /****************************************************************************** * * Registered settings blocks * ****************************************************************************** */ /** Root generic settings block */ struct generic_settings generic_settings_root = { .settings = { .refcnt = NULL, .name = "", .siblings = LIST_HEAD_INIT ( generic_settings_root.settings.siblings ), .children = LIST_HEAD_INIT ( generic_settings_root.settings.children ), .op = &generic_settings_operations, }, .list = LIST_HEAD_INIT ( generic_settings_root.list ), }; /** Root settings block */ #define settings_root generic_settings_root.settings /** * Find child named settings block * * @v parent Parent settings block * @v name Name within this parent * @ret settings Settings block, or NULL */ static struct settings * find_child_settings ( struct settings *parent, const char *name ) { struct settings *settings; /* Treat empty name as meaning "this block" */ if ( ! *name ) return parent; /* Look for child with matching name */ list_for_each_entry ( settings, &parent->children, siblings ) { if ( strcmp ( settings->name, name ) == 0 ) return settings; } return NULL; } /** * Find or create child named settings block * * @v parent Parent settings block * @v name Name within this parent * @ret settings Settings block, or NULL */ static struct settings * autovivify_child_settings ( struct settings *parent, const char *name ) { struct { struct generic_settings generic; char name[ strlen ( name ) + 1 /* NUL */ ]; } *new_child; struct settings *settings; /* Return existing settings, if existent */ if ( ( settings = find_child_settings ( parent, name ) ) != NULL ) return settings; /* Create new generic settings block */ new_child = zalloc ( sizeof ( *new_child ) ); if ( ! new_child ) { DBGC ( parent, "Settings %p could not create child %s\n", parent, name ); return NULL; } memcpy ( new_child->name, name, sizeof ( new_child->name ) ); generic_settings_init ( &new_child->generic, NULL, new_child->name ); settings = &new_child->generic.settings; register_settings ( settings, parent ); return settings; } /** * Return settings block name (for debug only) * * @v settings Settings block * @ret name Settings block name */ static const char * settings_name ( struct settings *settings ) { static char buf[64]; char tmp[ sizeof ( buf ) ]; int count; for ( count = 0 ; settings ; settings = settings->parent ) { memcpy ( tmp, buf, sizeof ( tmp ) ); snprintf ( buf, sizeof ( buf ), "%s%c%s", settings->name, ( count++ ? '.' : '\0' ), tmp ); } return ( buf + 1 ); } /** * Parse settings block name * * @v name Name * @v get_child Function to find or create child settings block * @ret settings Settings block, or NULL */ static struct settings * parse_settings_name ( const char *name, struct settings * ( * get_child ) ( struct settings *, const char * ) ) { struct settings *settings = &settings_root; char name_copy[ strlen ( name ) + 1 ]; char *subname; char *remainder; /* Create modifiable copy of name */ memcpy ( name_copy, name, sizeof ( name_copy ) ); remainder = name_copy; /* Parse each name component in turn */ while ( remainder ) { subname = remainder; remainder = strchr ( subname, '.' ); if ( remainder ) *(remainder++) = '\0'; settings = get_child ( settings, subname ); if ( ! settings ) break; } return settings; } /** * Find named settings block * * @v name Name * @ret settings Settings block, or NULL */ struct settings * find_settings ( const char *name ) { return parse_settings_name ( name, find_child_settings ); } /** * Apply all settings * * @ret rc Return status code */ static int apply_settings ( void ) { struct settings_applicator *applicator; int rc; /* Call all settings applicators */ for_each_table_entry ( applicator, SETTINGS_APPLICATORS ) { if ( ( rc = applicator->apply() ) != 0 ) { DBG ( "Could not apply settings using applicator " "%p: %s\n", applicator, strerror ( rc ) ); return rc; } } return 0; } /** * Reprioritise settings * * @v settings Settings block * * Reorders the settings block amongst its siblings according to its * priority. */ static void reprioritise_settings ( struct settings *settings ) { struct settings *parent = settings->parent; long priority; struct settings *tmp; long tmp_priority; /* Stop when we reach the top of the tree */ if ( ! parent ) return; /* Read priority, if present */ priority = fetch_intz_setting ( settings, &priority_setting ); /* Remove from siblings list */ list_del ( &settings->siblings ); /* Reinsert after any existing blocks which have a higher priority */ list_for_each_entry ( tmp, &parent->children, siblings ) { tmp_priority = fetch_intz_setting ( tmp, &priority_setting ); if ( priority > tmp_priority ) break; } list_add_tail ( &settings->siblings, &tmp->siblings ); /* Recurse up the tree */ reprioritise_settings ( parent ); } /** * Register settings block * * @v settings Settings block * @v parent Parent settings block, or NULL * @ret rc Return status code */ int register_settings ( struct settings *settings, struct settings *parent ) { struct settings *old_settings; /* NULL parent => add to settings root */ assert ( settings != NULL ); if ( parent == NULL ) parent = &settings_root; /* Remove any existing settings with the same name */ if ( ( old_settings = find_child_settings ( parent, settings->name ) )) unregister_settings ( old_settings ); /* Add to list of settings */ ref_get ( settings->refcnt ); ref_get ( parent->refcnt ); settings->parent = parent; list_add_tail ( &settings->siblings, &parent->children ); DBGC ( settings, "Settings %p (\"%s\") registered\n", settings, settings_name ( settings ) ); /* Fix up settings priority */ reprioritise_settings ( settings ); /* Apply potentially-updated settings */ apply_settings(); return 0; } /** * Unregister settings block * * @v settings Settings block */ void unregister_settings ( struct settings *settings ) { DBGC ( settings, "Settings %p (\"%s\") unregistered\n", settings, settings_name ( settings ) ); /* Remove from list of settings */ ref_put ( settings->refcnt ); ref_put ( settings->parent->refcnt ); settings->parent = NULL; list_del ( &settings->siblings ); /* Apply potentially-updated settings */ apply_settings(); } /****************************************************************************** * * Core settings routines * ****************************************************************************** */ /** * Store value of setting * * @v settings Settings block, or NULL * @v setting Setting to store * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ int store_setting ( struct settings *settings, struct setting *setting, const void *data, size_t len ) { int rc; /* NULL settings implies storing into the global settings root */ if ( ! settings ) settings = &settings_root; /* Sanity check */ if ( ! settings->op->store ) return -ENOTSUP; /* Store setting */ if ( ( rc = settings->op->store ( settings, setting, data, len ) ) != 0 ) return rc; /* Reprioritise settings if necessary */ if ( setting_cmp ( setting, &priority_setting ) == 0 ) reprioritise_settings ( settings ); /* If these settings are registered, apply potentially-updated * settings */ for ( ; settings ; settings = settings->parent ) { if ( settings == &settings_root ) { if ( ( rc = apply_settings() ) != 0 ) return rc; break; } } return 0; } /** * Fetch value of setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error * * The actual length of the setting will be returned even if * the buffer was too small. */ int fetch_setting ( struct settings *settings, struct setting *setting, void *data, size_t len ) { struct settings *child; int ret; /* Avoid returning uninitialised data on error */ memset ( data, 0, len ); /* NULL settings implies starting at the global settings root */ if ( ! settings ) settings = &settings_root; /* Sanity check */ if ( ! settings->op->fetch ) return -ENOTSUP; /* Try this block first */ if ( ( ret = settings->op->fetch ( settings, setting, data, len ) ) >= 0 ) return ret; /* Recurse into each child block in turn */ list_for_each_entry ( child, &settings->children, siblings ) { if ( ( ret = fetch_setting ( child, setting, data, len ) ) >= 0 ) return ret; } return -ENOENT; } /** * Fetch length of setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @ret len Length of setting data, or negative error * * This function can also be used as an existence check for the * setting. */ int fetch_setting_len ( struct settings *settings, struct setting *setting ) { return fetch_setting ( settings, setting, NULL, 0 ); } /** * Fetch value of string setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v data Buffer to fill with setting string data * @v len Length of buffer * @ret len Length of string setting, or negative error * * The resulting string is guaranteed to be correctly NUL-terminated. * The returned length will be the length of the underlying setting * data. */ int fetch_string_setting ( struct settings *settings, struct setting *setting, char *data, size_t len ) { memset ( data, 0, len ); return fetch_setting ( settings, setting, data, ( ( len > 0 ) ? ( len - 1 ) : 0 ) ); } /** * Fetch value of string setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v data Buffer to allocate and fill with setting string data * @ret len Length of string setting, or negative error * * The resulting string is guaranteed to be correctly NUL-terminated. * The returned length will be the length of the underlying setting * data. The caller is responsible for eventually freeing the * allocated buffer. */ int fetch_string_setting_copy ( struct settings *settings, struct setting *setting, char **data ) { int len; int check_len = 0; len = fetch_setting_len ( settings, setting ); if ( len < 0 ) return len; *data = malloc ( len + 1 ); if ( ! *data ) return -ENOMEM; check_len = fetch_string_setting ( settings, setting, *data, ( len + 1 ) ); assert ( check_len == len ); return len; } /** * Fetch value of IPv4 address setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v inp IPv4 address to fill in * @ret len Length of setting, or negative error */ int fetch_ipv4_setting ( struct settings *settings, struct setting *setting, struct in_addr *inp ) { int len; len = fetch_setting ( settings, setting, inp, sizeof ( *inp ) ); if ( len < 0 ) return len; if ( len < ( int ) sizeof ( *inp ) ) return -ERANGE; return len; } /** * Fetch value of signed integer setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v value Integer value to fill in * @ret len Length of setting, or negative error */ int fetch_int_setting ( struct settings *settings, struct setting *setting, long *value ) { union { uint8_t u8[ sizeof ( long ) ]; int8_t s8[ sizeof ( long ) ]; } buf; int len; int i; /* Avoid returning uninitialised data on error */ *value = 0; /* Fetch raw (network-ordered, variable-length) setting */ len = fetch_setting ( settings, setting, &buf, sizeof ( buf ) ); if ( len < 0 ) return len; if ( len > ( int ) sizeof ( buf ) ) return -ERANGE; /* Convert to host-ordered signed long */ *value = ( ( buf.s8[0] >= 0 ) ? 0 : -1L ); for ( i = 0 ; i < len ; i++ ) { *value = ( ( *value << 8 ) | buf.u8[i] ); } return len; } /** * Fetch value of unsigned integer setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v value Integer value to fill in * @ret len Length of setting, or negative error */ int fetch_uint_setting ( struct settings *settings, struct setting *setting, unsigned long *value ) { long svalue; int len; /* Avoid returning uninitialised data on error */ *value = 0; /* Fetch as a signed long */ len = fetch_int_setting ( settings, setting, &svalue ); if ( len < 0 ) return len; /* Mask off sign-extended bits */ assert ( len <= ( int ) sizeof ( long ) ); *value = ( svalue & ( -1UL >> ( 8 * ( sizeof ( long ) - len ) ) ) ); return len; } /** * Fetch value of signed integer setting, or zero * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @ret value Setting value, or zero */ long fetch_intz_setting ( struct settings *settings, struct setting *setting ){ long value; fetch_int_setting ( settings, setting, &value ); return value; } /** * Fetch value of unsigned integer setting, or zero * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @ret value Setting value, or zero */ unsigned long fetch_uintz_setting ( struct settings *settings, struct setting *setting ) { unsigned long value; fetch_uint_setting ( settings, setting, &value ); return value; } /** * Fetch value of UUID setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v uuid UUID to fill in * @ret len Length of setting, or negative error */ int fetch_uuid_setting ( struct settings *settings, struct setting *setting, union uuid *uuid ) { int len; len = fetch_setting ( settings, setting, uuid, sizeof ( *uuid ) ); if ( len < 0 ) return len; if ( len != sizeof ( *uuid ) ) return -ERANGE; return len; } /** * Clear settings block * * @v settings Settings block */ void clear_settings ( struct settings *settings ) { if ( settings->op->clear ) settings->op->clear ( settings ); } /** * Compare two settings * * @v a Setting to compare * @v b Setting to compare * @ret 0 Settings are the same * @ret non-zero Settings are not the same */ int setting_cmp ( struct setting *a, struct setting *b ) { /* If the settings have tags, compare them */ if ( a->tag && ( a->tag == b->tag ) ) return 0; /* Otherwise, if the settings have names, compare them */ if ( a->name && b->name && a->name[0] ) return strcmp ( a->name, b->name ); /* Otherwise, return a non-match */ return ( ! 0 ); } /****************************************************************************** * * Formatted setting routines * ****************************************************************************** */ /** * Store value of typed setting * * @v settings Settings block * @v setting Setting to store * @v type Settings type * @v value Formatted setting data, or NULL * @ret rc Return status code */ int storef_setting ( struct settings *settings, struct setting *setting, const char *value ) { /* NULL value implies deletion. Avoid imposing the burden of * checking for NULL values on each typed setting's storef() * method. */ if ( ! value ) return delete_setting ( settings, setting ); return setting->type->storef ( settings, setting, value ); } /** * Find named setting * * @v name Name * @ret setting Named setting, or NULL */ static struct setting * find_setting ( const char *name ) { struct setting *setting; for_each_table_entry ( setting, SETTINGS ) { if ( strcmp ( name, setting->name ) == 0 ) return setting; } return NULL; } /** * Parse setting name as tag number * * @v name Name * @ret tag Tag number, or 0 if not a valid number */ static unsigned int parse_setting_tag ( const char *name ) { char *tmp = ( ( char * ) name ); unsigned int tag = 0; while ( 1 ) { tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) ); if ( *tmp == 0 ) return tag; if ( *tmp != '.' ) return 0; tmp++; } } /** * Find setting type * * @v name Name * @ret type Setting type, or NULL */ static struct setting_type * find_setting_type ( const char *name ) { struct setting_type *type; for_each_table_entry ( type, SETTING_TYPES ) { if ( strcmp ( name, type->name ) == 0 ) return type; } return NULL; } /** * Parse setting name * * @v name Name of setting * @v get_child Function to find or create child settings block * @v settings Settings block to fill in * @v setting Setting to fill in * @v tmp_name Buffer for copy of setting name * @ret rc Return status code * * Interprets a name of the form * "[settings_name/]tag_name[:type_name]" and fills in the appropriate * fields. * * The @c tmp_name buffer must be large enough to hold a copy of the * setting name. */ static int parse_setting_name ( const char *name, struct settings * ( * get_child ) ( struct settings *, const char * ), struct settings **settings, struct setting *setting, char *tmp_name ) { char *settings_name; char *setting_name; char *type_name; struct setting *named_setting; /* Set defaults */ *settings = &settings_root; memset ( setting, 0, sizeof ( *setting ) ); setting->name = ""; setting->type = &setting_type_string; /* Split name into "[settings_name/]setting_name[:type_name]" */ strcpy ( tmp_name, name ); if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) { *(setting_name++) = 0; settings_name = tmp_name; } else { setting_name = tmp_name; settings_name = NULL; } if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL ) *(type_name++) = 0; /* Identify settings block, if specified */ if ( settings_name ) { *settings = parse_settings_name ( settings_name, get_child ); if ( *settings == NULL ) { DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n", settings_name, name ); return -ENODEV; } } /* Identify setting */ if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) { /* Matches a defined named setting; use that setting */ memcpy ( setting, named_setting, sizeof ( *setting ) ); } else if ( ( setting->tag = parse_setting_tag ( setting_name ) ) !=0){ /* Is a valid numeric tag; use the tag */ setting->tag |= (*settings)->tag_magic; } else { /* Use the arbitrary name */ setting->name = setting_name; } /* Identify setting type, if specified */ if ( type_name ) { setting->type = find_setting_type ( type_name ); if ( setting->type == NULL ) { DBG ( "Invalid setting type \"%s\" in \"%s\"\n", type_name, name ); return -ENOTSUP; } } return 0; } /** * Parse and store value of named setting * * @v name Name of setting * @v value Formatted setting data, or NULL * @ret rc Return status code */ int storef_named_setting ( const char *name, const char *value ) { struct settings *settings; struct setting setting; char tmp_name[ strlen ( name ) + 1 ]; int rc; if ( ( rc = parse_setting_name ( name, autovivify_child_settings, &settings, &setting, tmp_name )) != 0) return rc; return storef_setting ( settings, &setting, value ); } /** * Fetch and format value of named setting * * @v name Name of setting * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ int fetchf_named_setting ( const char *name, char *buf, size_t len ) { struct settings *settings; struct setting setting; char tmp_name[ strlen ( name ) + 1 ]; int rc; if ( ( rc = parse_setting_name ( name, find_child_settings, &settings, &setting, tmp_name )) != 0) return rc; return fetchf_setting ( settings, &setting, buf, len ); } /****************************************************************************** * * Setting types * ****************************************************************************** */ /** * Parse and store value of string setting * * @v settings Settings block * @v setting Setting to store * @v value Formatted setting data * @ret rc Return status code */ static int storef_string ( struct settings *settings, struct setting *setting, const char *value ) { return store_setting ( settings, setting, value, strlen ( value ) ); } /** * Fetch and format value of string setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ static int fetchf_string ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { return fetch_string_setting ( settings, setting, buf, len ); } /** A string setting type */ struct setting_type setting_type_string __setting_type = { .name = "string", .storef = storef_string, .fetchf = fetchf_string, }; /** * Parse and store value of URI-encoded string setting * * @v settings Settings block * @v setting Setting to store * @v value Formatted setting data * @ret rc Return status code */ static int storef_uristring ( struct settings *settings, struct setting *setting, const char *value ) { char buf[ strlen ( value ) + 1 ]; /* Decoding never expands string */ size_t len; len = uri_decode ( value, buf, sizeof ( buf ) ); return store_setting ( settings, setting, buf, len ); } /** * Fetch and format value of URI-encoded string setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ static int fetchf_uristring ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { ssize_t raw_len; /* We need to always retrieve the full raw string to know the * length of the encoded string. */ raw_len = fetch_setting ( settings, setting, NULL, 0 ); if ( raw_len < 0 ) return raw_len; { char raw_buf[ raw_len + 1 ]; fetch_string_setting ( settings, setting, raw_buf, sizeof ( raw_buf ) ); return uri_encode ( raw_buf, buf, len ); } } /** A URI-encoded string setting type */ struct setting_type setting_type_uristring __setting_type = { .name = "uristring", .storef = storef_uristring, .fetchf = fetchf_uristring, }; /** * Parse and store value of IPv4 address setting * * @v settings Settings block * @v setting Setting to store * @v value Formatted setting data * @ret rc Return status code */ static int storef_ipv4 ( struct settings *settings, struct setting *setting, const char *value ) { struct in_addr ipv4; if ( inet_aton ( value, &ipv4 ) == 0 ) return -EINVAL; return store_setting ( settings, setting, &ipv4, sizeof ( ipv4 ) ); } /** * Fetch and format value of IPv4 address setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ static int fetchf_ipv4 ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { struct in_addr ipv4; int raw_len; if ( ( raw_len = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0) return raw_len; return snprintf ( buf, len, "%s", inet_ntoa ( ipv4 ) ); } /** An IPv4 address setting type */ struct setting_type setting_type_ipv4 __setting_type = { .name = "ipv4", .storef = storef_ipv4, .fetchf = fetchf_ipv4, }; /** * Parse and store value of integer setting * * @v settings Settings block * @v setting Setting to store * @v value Formatted setting data * @v size Integer size, in bytes * @ret rc Return status code */ static int storef_int ( struct settings *settings, struct setting *setting, const char *value, unsigned int size ) { union { uint32_t num; uint8_t bytes[4]; } u; char *endp; u.num = htonl ( strtoul ( value, &endp, 0 ) ); if ( *endp ) return -EINVAL; return store_setting ( settings, setting, &u.bytes[ sizeof ( u ) - size ], size ); } /** * Parse and store value of 8-bit integer setting * * @v settings Settings block * @v setting Setting to store * @v value Formatted setting data * @v size Integer size, in bytes * @ret rc Return status code */ static int storef_int8 ( struct settings *settings, struct setting *setting, const char *value ) { return storef_int ( settings, setting, value, 1 ); } /** * Parse and store value of 16-bit integer setting * * @v settings Settings block * @v setting Setting to store * @v value Formatted setting data * @v size Integer size, in bytes * @ret rc Return status code */ static int storef_int16 ( struct settings *settings, struct setting *setting, const char *value ) { return storef_int ( settings, setting, value, 2 ); } /** * Parse and store value of 32-bit integer setting * * @v settings Settings block * @v setting Setting to store * @v value Formatted setting data * @v size Integer size, in bytes * @ret rc Return status code */ static int storef_int32 ( struct settings *settings, struct setting *setting, const char *value ) { return storef_int ( settings, setting, value, 4 ); } /** * Fetch and format value of signed integer setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ static int fetchf_int ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { long value; int rc; if ( ( rc = fetch_int_setting ( settings, setting, &value ) ) < 0 ) return rc; return snprintf ( buf, len, "%ld", value ); } /** * Fetch and format value of unsigned integer setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ static int fetchf_uint ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { unsigned long value; int rc; if ( ( rc = fetch_uint_setting ( settings, setting, &value ) ) < 0 ) return rc; return snprintf ( buf, len, "%#lx", value ); } /** A signed 8-bit integer setting type */ struct setting_type setting_type_int8 __setting_type = { .name = "int8", .storef = storef_int8, .fetchf = fetchf_int, }; /** A signed 16-bit integer setting type */ struct setting_type setting_type_int16 __setting_type = { .name = "int16", .storef = storef_int16, .fetchf = fetchf_int, }; /** A signed 32-bit integer setting type */ struct setting_type setting_type_int32 __setting_type = { .name = "int32", .storef = storef_int32, .fetchf = fetchf_int, }; /** An unsigned 8-bit integer setting type */ struct setting_type setting_type_uint8 __setting_type = { .name = "uint8", .storef = storef_int8, .fetchf = fetchf_uint, }; /** An unsigned 16-bit integer setting type */ struct setting_type setting_type_uint16 __setting_type = { .name = "uint16", .storef = storef_int16, .fetchf = fetchf_uint, }; /** An unsigned 32-bit integer setting type */ struct setting_type setting_type_uint32 __setting_type = { .name = "uint32", .storef = storef_int32, .fetchf = fetchf_uint, }; /** * Parse and store value of hex string setting * * @v settings Settings block * @v setting Setting to store * @v value Formatted setting data * @ret rc Return status code */ static int storef_hex ( struct settings *settings, struct setting *setting, const char *value ) { char *ptr = ( char * ) value; uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */ unsigned int len = 0; while ( 1 ) { bytes[len++] = strtoul ( ptr, &ptr, 16 ); switch ( *ptr ) { case '\0' : return store_setting ( settings, setting, bytes, len ); case ':' : ptr++; break; default : return -EINVAL; } } } /** * Fetch and format value of hex string setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ static int fetchf_hex ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { int raw_len; int check_len; int used = 0; int i; raw_len = fetch_setting_len ( settings, setting ); if ( raw_len < 0 ) return raw_len; { uint8_t raw[raw_len]; check_len = fetch_setting ( settings, setting, raw, sizeof ( raw ) ); if ( check_len < 0 ) return check_len; assert ( check_len == raw_len ); if ( len ) buf[0] = 0; /* Ensure that a terminating NUL exists */ for ( i = 0 ; i < raw_len ; i++ ) { used += ssnprintf ( ( buf + used ), ( len - used ), "%s%02x", ( used ? ":" : "" ), raw[i] ); } return used; } } /** A hex-string setting */ struct setting_type setting_type_hex __setting_type = { .name = "hex", .storef = storef_hex, .fetchf = fetchf_hex, }; /** * Parse and store value of UUID setting * * @v settings Settings block * @v setting Setting to store * @v value Formatted setting data * @ret rc Return status code */ static int storef_uuid ( struct settings *settings __unused, struct setting *setting __unused, const char *value __unused ) { return -ENOTSUP; } /** * Fetch and format value of UUID setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ static int fetchf_uuid ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { union uuid uuid; int raw_len; if ( ( raw_len = fetch_uuid_setting ( settings, setting, &uuid ) ) < 0) return raw_len; return snprintf ( buf, len, "%s", uuid_ntoa ( &uuid ) ); } /** UUID setting type */ struct setting_type setting_type_uuid __setting_type = { .name = "uuid", .storef = storef_uuid, .fetchf = fetchf_uuid, }; /****************************************************************************** * * Settings * ****************************************************************************** */ /** Hostname setting */ struct setting hostname_setting __setting = { .name = "hostname", .description = "Host name", .tag = DHCP_HOST_NAME, .type = &setting_type_string, }; /** Filename setting */ struct setting filename_setting __setting = { .name = "filename", .description = "Boot filename", .tag = DHCP_BOOTFILE_NAME, .type = &setting_type_string, }; /** Root path setting */ struct setting root_path_setting __setting = { .name = "root-path", .description = "NFS/iSCSI root path", .tag = DHCP_ROOT_PATH, .type = &setting_type_string, }; /** Username setting */ struct setting username_setting __setting = { .name = "username", .description = "User name", .tag = DHCP_EB_USERNAME, .type = &setting_type_string, }; /** Password setting */ struct setting password_setting __setting = { .name = "password", .description = "Password", .tag = DHCP_EB_PASSWORD, .type = &setting_type_string, }; /** Priority setting */ struct setting priority_setting __setting = { .name = "priority", .description = "Priority of these settings", .tag = DHCP_EB_PRIORITY, .type = &setting_type_int8, }; debian/grub-extras/disabled/gpxe/src/core/refcnt.c0000664000000000000000000000354512524662415017327 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** @file * * Reference counting * */ /** * Increment reference count * * @v refcnt Reference counter, or NULL * @ret refcnt Reference counter * * If @c refcnt is NULL, no action is taken. */ struct refcnt * ref_get ( struct refcnt *refcnt ) { if ( refcnt ) { refcnt->refcnt++; DBGC2 ( refcnt, "REFCNT %p incremented to %d\n", refcnt, refcnt->refcnt ); } return refcnt; } /** * Decrement reference count * * @v refcnt Reference counter, or NULL * * If the reference count decreases below zero, the object's free() * method will be called. * * If @c refcnt is NULL, no action is taken. */ void ref_put ( struct refcnt *refcnt ) { if ( ! refcnt ) return; refcnt->refcnt--; DBGC2 ( refcnt, "REFCNT %p decremented to %d\n", refcnt, refcnt->refcnt ); if ( refcnt->refcnt >= 0 ) return; if ( refcnt->free ) { DBGC ( refcnt, "REFCNT %p being freed via method %p\n", refcnt, refcnt->free ); refcnt->free ( refcnt ); } else { DBGC ( refcnt, "REFCNT %p being freed\n", refcnt ); free ( refcnt ); } } debian/grub-extras/disabled/gpxe/src/core/bitmap.c0000664000000000000000000000520012524662415017310 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** @file * * Bitmaps for multicast downloads * */ /** * Resize bitmap * * @v bitmap Bitmap * @v new_length New length of bitmap, in bits * @ret rc Return status code */ int bitmap_resize ( struct bitmap *bitmap, unsigned int new_length ) { unsigned int old_num_blocks; unsigned int new_num_blocks; size_t new_size; bitmap_block_t *new_blocks; old_num_blocks = BITMAP_INDEX ( bitmap->length + BITMAP_BLKSIZE - 1 ); new_num_blocks = BITMAP_INDEX ( new_length + BITMAP_BLKSIZE - 1 ); if ( old_num_blocks != new_num_blocks ) { new_size = ( new_num_blocks * sizeof ( bitmap->blocks[0] ) ); new_blocks = realloc ( bitmap->blocks, new_size ); if ( ! new_blocks ) { DBGC ( bitmap, "Bitmap %p could not resize to %d " "bits\n", bitmap, new_length ); return -ENOMEM; } bitmap->blocks = new_blocks; } bitmap->length = new_length; while ( old_num_blocks < new_num_blocks ) { bitmap->blocks[old_num_blocks++] = 0; } DBGC ( bitmap, "Bitmap %p resized to %d bits\n", bitmap, new_length ); return 0; } /** * Test bit in bitmap * * @v bitmap Bitmap * @v bit Bit index * @ret is_set Bit is set */ int bitmap_test ( struct bitmap *bitmap, unsigned int bit ) { unsigned int index = BITMAP_INDEX ( bit ); bitmap_block_t mask = BITMAP_MASK ( bit ); if ( bit >= bitmap->length ) return 0; return ( bitmap->blocks[index] & mask ); } /** * Set bit in bitmap * * @v bitmap Bitmap * @v bit Bit index */ void bitmap_set ( struct bitmap *bitmap, unsigned int bit ) { unsigned int index = BITMAP_INDEX ( bit ); bitmap_block_t mask = BITMAP_MASK ( bit ); DBGC ( bitmap, "Bitmap %p setting bit %d\n", bitmap, bit ); /* Update bitmap */ bitmap->blocks[index] |= mask; /* Update first gap counter */ while ( bitmap_test ( bitmap, bitmap->first_gap ) ) { bitmap->first_gap++; } } debian/grub-extras/disabled/gpxe/src/core/misc.c0000664000000000000000000000325412524662415016776 0ustar /************************************************************************** MISC Support Routines **************************************************************************/ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include /************************************************************************** INET_ATON - Convert an ascii x.x.x.x to binary form **************************************************************************/ int inet_aton ( const char *cp, struct in_addr *inp ) { const char *p = cp; const char *digits_start; unsigned long ip = 0; unsigned long val; int j; for(j = 0; j <= 3; j++) { digits_start = p; val = strtoul(p, ( char ** ) &p, 10); if ((p == digits_start) || (val > 255)) return 0; if ( ( j < 3 ) && ( *(p++) != '.' ) ) return 0; ip = (ip << 8) | val; } if ( *p == '\0' ) { inp->s_addr = htonl(ip); return 1; } return 0; } unsigned long strtoul ( const char *p, char **endp, int base ) { unsigned long ret = 0; unsigned int charval; while ( isspace ( *p ) ) p++; if ( base == 0 ) { base = 10; if ( *p == '0' ) { p++; base = 8; if ( ( *p | 0x20 ) == 'x' ) { p++; base = 16; } } } while ( 1 ) { charval = *p; if ( charval >= 'a' ) { charval = ( charval - 'a' + 10 ); } else if ( charval >= 'A' ) { charval = ( charval - 'A' + 10 ); } else if ( charval <= '9' ) { charval = ( charval - '0' ); } if ( charval >= ( unsigned int ) base ) break; ret = ( ( ret * base ) + charval ); p++; } if ( endp ) *endp = ( char * ) p; return ( ret ); } /* * Local variables: * c-basic-offset: 8 * End: */ debian/grub-extras/disabled/gpxe/src/core/base64.c0000664000000000000000000000402612524662415017125 0ustar /* * Copyright (C) 2009 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include /** @file * * Base64 encoding * */ static const char base64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * Base64-encode a string * * @v raw Raw string * @v encoded Buffer for encoded string * * The buffer must be the correct length for the encoded string. Use * something like * * char buf[ base64_encoded_len ( strlen ( raw ) ) + 1 ]; * * (the +1 is for the terminating NUL) to provide a buffer of the * correct size. */ void base64_encode ( const char *raw, char *encoded ) { const uint8_t *raw_bytes = ( ( const uint8_t * ) raw ); uint8_t *encoded_bytes = ( ( uint8_t * ) encoded ); size_t raw_bit_len = ( 8 * strlen ( raw ) ); unsigned int bit; unsigned int tmp; for ( bit = 0 ; bit < raw_bit_len ; bit += 6 ) { tmp = ( ( raw_bytes[ bit / 8 ] << ( bit % 8 ) ) | ( raw_bytes[ bit / 8 + 1 ] >> ( 8 - ( bit % 8 ) ) ) ); tmp = ( ( tmp >> 2 ) & 0x3f ); *(encoded_bytes++) = base64[tmp]; } for ( ; ( bit % 8 ) != 0 ; bit += 6 ) *(encoded_bytes++) = '='; *(encoded_bytes++) = '\0'; DBG ( "Base64-encoded \"%s\" as \"%s\"\n", raw, encoded ); assert ( strlen ( encoded ) == base64_encoded_len ( strlen ( raw ) ) ); } debian/grub-extras/disabled/gpxe/src/core/nvo.c0000664000000000000000000001553412524662415016651 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include /** @file * * Non-volatile stored options * */ /** * Calculate checksum over non-volatile stored options * * @v nvo Non-volatile options block * @ret sum Checksum */ static unsigned int nvo_checksum ( struct nvo_block *nvo ) { uint8_t *data = nvo->data; uint8_t sum = 0; unsigned int i; for ( i = 0 ; i < nvo->total_len ; i++ ) { sum += *(data++); } return sum; } /** * Load non-volatile stored options from non-volatile storage device * * @v nvo Non-volatile options block * @ret rc Return status code */ static int nvo_load ( struct nvo_block *nvo ) { void *data = nvo->data; struct nvo_fragment *frag; int rc; /* Read data a fragment at a time */ for ( frag = nvo->fragments ; frag->len ; frag++ ) { if ( ( rc = nvs_read ( nvo->nvs, frag->address, data, frag->len ) ) != 0 ) { DBGC ( nvo, "NVO %p could not read %zd bytes at " "%#04x\n", nvo, frag->len, frag->address ); return rc; } data += frag->len; } DBGC ( nvo, "NVO %p loaded from non-volatile storage\n", nvo ); return 0; } /** * Save non-volatile stored options back to non-volatile storage device * * @v nvo Non-volatile options block * @ret rc Return status code */ static int nvo_save ( struct nvo_block *nvo ) { void *data = nvo->data; uint8_t *checksum = data; struct nvo_fragment *frag; int rc; /* Recalculate checksum */ *checksum -= nvo_checksum ( nvo ); /* Write data a fragment at a time */ for ( frag = nvo->fragments ; frag->len ; frag++ ) { if ( ( rc = nvs_write ( nvo->nvs, frag->address, data, frag->len ) ) != 0 ) { DBGC ( nvo, "NVO %p could not write %zd bytes at " "%#04x\n", nvo, frag->len, frag->address ); return rc; } data += frag->len; } DBGC ( nvo, "NVO %p saved to non-volatile storage\n", nvo ); return 0; } /** * Parse stored options * * @v nvo Non-volatile options block * * Verifies that the options data is valid, and configures the DHCP * options block. If the data is not valid, it is replaced with an * empty options block. */ static void nvo_init_dhcpopts ( struct nvo_block *nvo ) { uint8_t *options_data; size_t options_len; /* Steal one byte for the checksum */ options_data = ( nvo->data + 1 ); options_len = ( nvo->total_len - 1 ); /* If checksum fails, or options data starts with a zero, * assume the whole block is invalid. This should capture the * case of random initial contents. */ if ( ( nvo_checksum ( nvo ) != 0 ) || ( options_data[0] == 0 ) ) { DBGC ( nvo, "NVO %p has checksum %02x and initial byte %02x; " "assuming empty\n", nvo, nvo_checksum ( nvo ), options_data[0] ); memset ( nvo->data, 0, nvo->total_len ); } dhcpopt_init ( &nvo->dhcpopts, options_data, options_len ); } /** * Store value of NVO setting * * @v settings Settings block * @v setting Setting to store * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ static int nvo_store ( struct settings *settings, struct setting *setting, const void *data, size_t len ) { struct nvo_block *nvo = container_of ( settings, struct nvo_block, settings ); int rc; /* Update stored options */ if ( ( rc = dhcpopt_store ( &nvo->dhcpopts, setting->tag, data, len ) ) != 0 ) { DBGC ( nvo, "NVO %p could not store %zd bytes: %s\n", nvo, len, strerror ( rc ) ); return rc; } /* Save updated options to NVS */ if ( ( rc = nvo_save ( nvo ) ) != 0 ) return rc; return 0; } /** * Fetch value of NVO setting * * @v settings Settings block * @v setting Setting to fetch * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error * * The actual length of the setting will be returned even if * the buffer was too small. */ static int nvo_fetch ( struct settings *settings, struct setting *setting, void *data, size_t len ) { struct nvo_block *nvo = container_of ( settings, struct nvo_block, settings ); return dhcpopt_fetch ( &nvo->dhcpopts, setting->tag, data, len ); } /** NVO settings operations */ static struct settings_operations nvo_settings_operations = { .store = nvo_store, .fetch = nvo_fetch, }; /** * Initialise non-volatile stored options * * @v nvo Non-volatile options block * @v nvs Underlying non-volatile storage device * @v fragments List of option-containing fragments * @v refcnt Containing object reference counter, or NULL */ void nvo_init ( struct nvo_block *nvo, struct nvs_device *nvs, struct nvo_fragment *fragments, struct refcnt *refcnt ) { nvo->nvs = nvs; nvo->fragments = fragments; settings_init ( &nvo->settings, &nvo_settings_operations, refcnt, "nvo", 0 ); } /** * Register non-volatile stored options * * @v nvo Non-volatile options block * @v parent Parent settings block, or NULL * @ret rc Return status code */ int register_nvo ( struct nvo_block *nvo, struct settings *parent ) { struct nvo_fragment *fragment = nvo->fragments; int rc; /* Calculate total length of all fragments */ for ( fragment = nvo->fragments ; fragment->len ; fragment++ ) nvo->total_len += fragment->len; /* Allocate memory for options and read in from NVS */ nvo->data = malloc ( nvo->total_len ); if ( ! nvo->data ) { DBGC ( nvo, "NVO %p could not allocate %zd bytes\n", nvo, nvo->total_len ); rc = -ENOMEM; goto err_malloc; } if ( ( rc = nvo_load ( nvo ) ) != 0 ) goto err_load; /* Verify and register options */ nvo_init_dhcpopts ( nvo ); if ( ( rc = register_settings ( &nvo->settings, parent ) ) != 0 ) goto err_register; DBGC ( nvo, "NVO %p registered\n", nvo ); return 0; err_register: err_load: free ( nvo->data ); nvo->data = NULL; err_malloc: return rc; } /** * Unregister non-volatile stored options * * @v nvo Non-volatile options block */ void unregister_nvo ( struct nvo_block *nvo ) { unregister_settings ( &nvo->settings ); free ( nvo->data ); nvo->data = NULL; DBGC ( nvo, "NVO %p unregistered\n", nvo ); } debian/grub-extras/disabled/gpxe/src/core/resolv.c0000664000000000000000000002535612524662415017364 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include /** @file * * Name resolution * */ /*************************************************************************** * * Name resolution interfaces * *************************************************************************** */ /** * Name resolution completed * * @v resolv Name resolution interface * @v sa Completed socket address (if successful) * @v rc Final status code */ void resolv_done ( struct resolv_interface *resolv, struct sockaddr *sa, int rc ) { struct resolv_interface *dest = resolv_get_dest ( resolv ); resolv_unplug ( resolv ); dest->op->done ( dest, sa, rc ); resolv_put ( dest ); } /** * Ignore name resolution done() event * * @v resolv Name resolution interface * @v sa Completed socket address (if successful) * @v rc Final status code */ void ignore_resolv_done ( struct resolv_interface *resolv __unused, struct sockaddr *sa __unused, int rc __unused ) { /* Do nothing */ } /** Null name resolution interface operations */ struct resolv_interface_operations null_resolv_ops = { .done = ignore_resolv_done, }; /** Null name resolution interface */ struct resolv_interface null_resolv = { .intf = { .dest = &null_resolv.intf, .refcnt = NULL, }, .op = &null_resolv_ops, }; /*************************************************************************** * * Numeric name resolver * *************************************************************************** */ /** A numeric name resolver */ struct numeric_resolv { /** Reference counter */ struct refcnt refcnt; /** Name resolution interface */ struct resolv_interface resolv; /** Process */ struct process process; /** Completed socket address */ struct sockaddr sa; /** Overall status code */ int rc; }; static void numeric_step ( struct process *process ) { struct numeric_resolv *numeric = container_of ( process, struct numeric_resolv, process ); resolv_done ( &numeric->resolv, &numeric->sa, numeric->rc ); process_del ( process ); } static int numeric_resolv ( struct resolv_interface *resolv, const char *name, struct sockaddr *sa ) { struct numeric_resolv *numeric; struct sockaddr_in *sin; /* Allocate and initialise structure */ numeric = zalloc ( sizeof ( *numeric ) ); if ( ! numeric ) return -ENOMEM; resolv_init ( &numeric->resolv, &null_resolv_ops, &numeric->refcnt ); process_init ( &numeric->process, numeric_step, &numeric->refcnt ); memcpy ( &numeric->sa, sa, sizeof ( numeric->sa ) ); DBGC ( numeric, "NUMERIC %p attempting to resolve \"%s\"\n", numeric, name ); /* Attempt to resolve name */ sin = ( ( struct sockaddr_in * ) &numeric->sa ); sin->sin_family = AF_INET; if ( inet_aton ( name, &sin->sin_addr ) == 0 ) numeric->rc = -EINVAL; /* Attach to parent interface, mortalise self, and return */ resolv_plug_plug ( &numeric->resolv, resolv ); ref_put ( &numeric->refcnt ); return 0; } struct resolver numeric_resolver __resolver ( RESOLV_NUMERIC ) = { .name = "NUMERIC", .resolv = numeric_resolv, }; /*************************************************************************** * * Name resolution multiplexer * *************************************************************************** */ /** A name resolution multiplexer */ struct resolv_mux { /** Reference counter */ struct refcnt refcnt; /** Parent name resolution interface */ struct resolv_interface parent; /** Child name resolution interface */ struct resolv_interface child; /** Current child resolver */ struct resolver *resolver; /** Socket address to complete */ struct sockaddr sa; /** Name to be resolved * * Must be at end of structure */ char name[0]; }; /** * Try current child name resolver * * @v mux Name resolution multiplexer * @ret rc Return status code */ static int resolv_mux_try ( struct resolv_mux *mux ) { struct resolver *resolver = mux->resolver; int rc; DBGC ( mux, "RESOLV %p trying method %s\n", mux, resolver->name ); if ( ( rc = resolver->resolv ( &mux->child, mux->name, &mux->sa ) ) != 0 ) { DBGC ( mux, "RESOLV %p could not use method %s: %s\n", mux, resolver->name, strerror ( rc ) ); return rc; } return 0; } /** * Handle done() event from child name resolver * * @v resolv Child name resolution interface * @v sa Completed socket address (if successful) * @v rc Final status code */ static void resolv_mux_done ( struct resolv_interface *resolv, struct sockaddr *sa, int rc ) { struct resolv_mux *mux = container_of ( resolv, struct resolv_mux, child ); /* Unplug child */ resolv_unplug ( &mux->child ); /* If this resolution succeeded, stop now */ if ( rc == 0 ) { DBGC ( mux, "RESOLV %p succeeded using method %s\n", mux, mux->resolver->name ); goto finished; } /* Attempt next child resolver, if possible */ mux->resolver++; if ( mux->resolver >= table_end ( RESOLVERS ) ) { DBGC ( mux, "RESOLV %p failed to resolve name\n", mux ); goto finished; } if ( ( rc = resolv_mux_try ( mux ) ) != 0 ) goto finished; /* Next resolver is now running */ return; finished: resolv_done ( &mux->parent, sa, rc ); } /** Name resolution multiplexer operations */ static struct resolv_interface_operations resolv_mux_child_ops = { .done = resolv_mux_done, }; /** * Start name resolution * * @v resolv Name resolution interface * @v name Name to resolve * @v sa Socket address to complete * @ret rc Return status code */ int resolv ( struct resolv_interface *resolv, const char *name, struct sockaddr *sa ) { struct resolv_mux *mux; size_t name_len = ( strlen ( name ) + 1 ); int rc; /* Allocate and initialise structure */ mux = zalloc ( sizeof ( *mux ) + name_len ); if ( ! mux ) return -ENOMEM; resolv_init ( &mux->parent, &null_resolv_ops, &mux->refcnt ); resolv_init ( &mux->child, &resolv_mux_child_ops, &mux->refcnt ); mux->resolver = table_start ( RESOLVERS ); memcpy ( &mux->sa, sa, sizeof ( mux->sa ) ); memcpy ( mux->name, name, name_len ); DBGC ( mux, "RESOLV %p attempting to resolve \"%s\"\n", mux, name ); /* Start first resolver in chain. There will always be at * least one resolver (the numeric resolver), so no need to * check for the zero-resolvers-available case. */ if ( ( rc = resolv_mux_try ( mux ) ) != 0 ) goto err; /* Attach parent interface, mortalise self, and return */ resolv_plug_plug ( &mux->parent, resolv ); ref_put ( &mux->refcnt ); return 0; err: ref_put ( &mux->refcnt ); return rc; } /*************************************************************************** * * Named socket opening * *************************************************************************** */ /** A named socket */ struct named_socket { /** Reference counter */ struct refcnt refcnt; /** Data transfer interface */ struct xfer_interface xfer; /** Name resolution interface */ struct resolv_interface resolv; /** Communication semantics (e.g. SOCK_STREAM) */ int semantics; /** Stored local socket address, if applicable */ struct sockaddr local; /** Stored local socket address exists */ int have_local; }; /** * Finish using named socket * * @v named Named socket * @v rc Reason for finish */ static void named_done ( struct named_socket *named, int rc ) { /* Close all interfaces */ resolv_nullify ( &named->resolv ); xfer_nullify ( &named->xfer ); xfer_close ( &named->xfer, rc ); } /** * Handle close() event * * @v xfer Data transfer interface * @v rc Reason for close */ static void named_xfer_close ( struct xfer_interface *xfer, int rc ) { struct named_socket *named = container_of ( xfer, struct named_socket, xfer ); named_done ( named, rc ); } /** Named socket opener data transfer interface operations */ static struct xfer_interface_operations named_xfer_ops = { .close = named_xfer_close, .vredirect = ignore_xfer_vredirect, .window = no_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, .deliver_raw = ignore_xfer_deliver_raw, }; /** * Handle done() event * * @v resolv Name resolution interface * @v sa Completed socket address (if successful) * @v rc Final status code */ static void named_resolv_done ( struct resolv_interface *resolv, struct sockaddr *sa, int rc ) { struct named_socket *named = container_of ( resolv, struct named_socket, resolv ); /* Redirect if name resolution was successful */ if ( rc == 0 ) { rc = xfer_redirect ( &named->xfer, LOCATION_SOCKET, named->semantics, sa, ( named->have_local ? &named->local : NULL ) ); } /* Terminate resolution */ named_done ( named, rc ); } /** Named socket opener name resolution interface operations */ static struct resolv_interface_operations named_resolv_ops = { .done = named_resolv_done, }; /** * Open named socket * * @v semantics Communication semantics (e.g. SOCK_STREAM) * @v peer Peer socket address to complete * @v name Name to resolve * @v local Local socket address, or NULL * @ret rc Return status code */ int xfer_open_named_socket ( struct xfer_interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local ) { struct named_socket *named; int rc; /* Allocate and initialise structure */ named = zalloc ( sizeof ( *named ) ); if ( ! named ) return -ENOMEM; xfer_init ( &named->xfer, &named_xfer_ops, &named->refcnt ); resolv_init ( &named->resolv, &named_resolv_ops, &named->refcnt ); named->semantics = semantics; if ( local ) { memcpy ( &named->local, local, sizeof ( named->local ) ); named->have_local = 1; } DBGC ( named, "RESOLV %p opening named socket \"%s\"\n", named, name ); /* Start name resolution */ if ( ( rc = resolv ( &named->resolv, name, peer ) ) != 0 ) goto err; /* Attach parent interface, mortalise self, and return */ xfer_plug_plug ( &named->xfer, xfer ); ref_put ( &named->refcnt ); return 0; err: ref_put ( &named->refcnt ); return rc; } debian/grub-extras/disabled/gpxe/src/core/open.c0000664000000000000000000001220012524662415016773 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include /** @file * * Data transfer interface opening * */ /** * Open URI * * @v xfer Data transfer interface * @v uri URI * @ret rc Return status code * * The URI will be regarded as being relative to the current working * URI (see churi()). */ int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { struct uri_opener *opener; struct uri *resolved_uri; int rc = -ENOTSUP; /* Resolve URI */ resolved_uri = resolve_uri ( cwuri, uri ); if ( ! resolved_uri ) return -ENOMEM; /* Find opener which supports this URI scheme */ for_each_table_entry ( opener, URI_OPENERS ) { if ( strcmp ( resolved_uri->scheme, opener->scheme ) == 0 ) { DBGC ( xfer, "XFER %p opening %s URI\n", xfer, opener->scheme ); rc = opener->open ( xfer, resolved_uri ); goto done; } } DBGC ( xfer, "XFER %p attempted to open unsupported URI scheme " "\"%s\"\n", xfer, resolved_uri->scheme ); done: uri_put ( resolved_uri ); return rc; } /** * Open URI string * * @v xfer Data transfer interface * @v uri_string URI string (e.g. "http://etherboot.org/kernel") * @ret rc Return status code * * The URI will be regarded as being relative to the current working * URI (see churi()). */ int xfer_open_uri_string ( struct xfer_interface *xfer, const char *uri_string ) { struct uri *uri; int rc; DBGC ( xfer, "XFER %p opening URI %s\n", xfer, uri_string ); uri = parse_uri ( uri_string ); if ( ! uri ) return -ENOMEM; rc = xfer_open_uri ( xfer, uri ); uri_put ( uri ); return rc; } /** * Open socket * * @v xfer Data transfer interface * @v semantics Communication semantics (e.g. SOCK_STREAM) * @v peer Peer socket address * @v local Local socket address, or NULL * @ret rc Return status code */ int xfer_open_socket ( struct xfer_interface *xfer, int semantics, struct sockaddr *peer, struct sockaddr *local ) { struct socket_opener *opener; DBGC ( xfer, "XFER %p opening (%s,%s) socket\n", xfer, socket_semantics_name ( semantics ), socket_family_name ( peer->sa_family ) ); for_each_table_entry ( opener, SOCKET_OPENERS ) { if ( ( opener->semantics == semantics ) && ( opener->family == peer->sa_family ) ) { return opener->open ( xfer, peer, local ); } } DBGC ( xfer, "XFER %p attempted to open unsupported socket type " "(%s,%s)\n", xfer, socket_semantics_name ( semantics ), socket_family_name ( peer->sa_family ) ); return -ENOTSUP; } /** * Open location * * @v xfer Data transfer interface * @v type Location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ int xfer_vopen ( struct xfer_interface *xfer, int type, va_list args ) { switch ( type ) { case LOCATION_URI_STRING: { const char *uri_string = va_arg ( args, const char * ); return xfer_open_uri_string ( xfer, uri_string ); } case LOCATION_URI: { struct uri *uri = va_arg ( args, struct uri * ); return xfer_open_uri ( xfer, uri ); } case LOCATION_SOCKET: { int semantics = va_arg ( args, int ); struct sockaddr *peer = va_arg ( args, struct sockaddr * ); struct sockaddr *local = va_arg ( args, struct sockaddr * ); return xfer_open_socket ( xfer, semantics, peer, local ); } default: DBGC ( xfer, "XFER %p attempted to open unsupported location " "type %d\n", xfer, type ); return -ENOTSUP; } } /** * Open location * * @v xfer Data transfer interface * @v type Location type * @v ... Remaining arguments depend upon location type * @ret rc Return status code */ int xfer_open ( struct xfer_interface *xfer, int type, ... ) { va_list args; int rc; va_start ( args, type ); rc = xfer_vopen ( xfer, type, args ); va_end ( args ); return rc; } /** * Reopen location * * @v xfer Data transfer interface * @v type Location type * @v args Remaining arguments depend upon location type * @ret rc Return status code * * This will close the existing connection and open a new connection * using xfer_vopen(). It is intended to be used as a .vredirect * method handler. */ int xfer_vreopen ( struct xfer_interface *xfer, int type, va_list args ) { /* Close existing connection */ xfer_close ( xfer, 0 ); /* Open new location */ return xfer_vopen ( xfer, type, args ); } debian/grub-extras/disabled/gpxe/src/core/uri.c0000664000000000000000000002644712524662415016653 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); /** @file * * Uniform Resource Identifiers * */ #include #include #include #include #include #include #include /** * Dump URI for debugging * * @v uri URI */ static void dump_uri ( struct uri *uri ) { if ( ! uri ) return; if ( uri->scheme ) DBG ( " scheme \"%s\"", uri->scheme ); if ( uri->opaque ) DBG ( " opaque \"%s\"", uri->opaque ); if ( uri->user ) DBG ( " user \"%s\"", uri->user ); if ( uri->password ) DBG ( " password \"%s\"", uri->password ); if ( uri->host ) DBG ( " host \"%s\"", uri->host ); if ( uri->port ) DBG ( " port \"%s\"", uri->port ); if ( uri->path ) DBG ( " path \"%s\"", uri->path ); if ( uri->query ) DBG ( " query \"%s\"", uri->query ); if ( uri->fragment ) DBG ( " fragment \"%s\"", uri->fragment ); } /** * Parse URI * * @v uri_string URI as a string * @ret uri URI * * Splits a URI into its component parts. The return URI structure is * dynamically allocated and must eventually be freed by calling * uri_put(). */ struct uri * parse_uri ( const char *uri_string ) { struct uri *uri; char *raw; char *tmp; char *path = NULL; char *authority = NULL; size_t raw_len; /* Allocate space for URI struct and a copy of the string */ raw_len = ( strlen ( uri_string ) + 1 /* NUL */ ); uri = zalloc ( sizeof ( *uri ) + raw_len ); if ( ! uri ) return NULL; raw = ( ( ( char * ) uri ) + sizeof ( *uri ) ); /* Zero URI struct and copy in the raw string */ memcpy ( raw, uri_string, raw_len ); /* Start by chopping off the fragment, if it exists */ if ( ( tmp = strchr ( raw, '#' ) ) ) { *(tmp++) = '\0'; uri->fragment = tmp; } /* Identify absolute/relative URI. We ignore schemes that are * apparently only a single character long, since otherwise we * misinterpret a DOS-style path name ("C:\path\to\file") as a * URI with scheme="C",opaque="\path\to\file". */ if ( ( tmp = strchr ( raw, ':' ) ) && ( tmp > ( raw + 1 ) ) ) { /* Absolute URI: identify hierarchical/opaque */ uri->scheme = raw; *(tmp++) = '\0'; if ( *tmp == '/' ) { /* Absolute URI with hierarchical part */ path = tmp; } else { /* Absolute URI with opaque part */ uri->opaque = tmp; } } else { /* Relative URI */ path = raw; } /* If we don't have a path (i.e. we have an absolute URI with * an opaque portion, we're already finished processing */ if ( ! path ) goto done; /* Chop off the query, if it exists */ if ( ( tmp = strchr ( path, '?' ) ) ) { *(tmp++) = '\0'; uri->query = tmp; } /* Identify net/absolute/relative path */ if ( strncmp ( path, "//", 2 ) == 0 ) { /* Net path. If this is terminated by the first '/' * of an absolute path, then we have no space for a * terminator after the authority field, so shuffle * the authority down by one byte, overwriting one of * the two slashes. */ authority = ( path + 2 ); if ( ( tmp = strchr ( authority, '/' ) ) ) { /* Shuffle down */ uri->path = tmp; memmove ( ( authority - 1 ), authority, ( tmp - authority ) ); authority--; *(--tmp) = '\0'; } } else { /* Absolute/relative path */ uri->path = path; } /* Split authority into user[:password] and host[:port] portions */ if ( ( tmp = strchr ( authority, '@' ) ) ) { /* Has user[:password] */ *(tmp++) = '\0'; uri->host = tmp; uri->user = authority; if ( ( tmp = strchr ( authority, ':' ) ) ) { /* Has password */ *(tmp++) = '\0'; uri->password = tmp; } } else { /* No user:password */ uri->host = authority; } /* Split host into host[:port] */ if ( ( tmp = strchr ( uri->host, ':' ) ) ) { *(tmp++) = '\0'; uri->port = tmp; } done: DBG ( "URI \"%s\" split into", uri_string ); dump_uri ( uri ); DBG ( "\n" ); return uri; } /** * Get port from URI * * @v uri URI, or NULL * @v default_port Default port to use if none specified in URI * @ret port Port */ unsigned int uri_port ( struct uri *uri, unsigned int default_port ) { if ( ( ! uri ) || ( ! uri->port ) ) return default_port; return ( strtoul ( uri->port, NULL, 0 ) ); } /** * Unparse URI * * @v buf Buffer to fill with URI string * @v size Size of buffer * @v uri URI to write into buffer, or NULL * @ret len Length of URI string */ int unparse_uri ( char *buf, size_t size, struct uri *uri ) { int used = 0; DBG ( "URI unparsing" ); dump_uri ( uri ); DBG ( "\n" ); /* Special-case NULL URI */ if ( ! uri ) { if ( size ) buf[0] = '\0'; return 0; } /* Special-case opaque URIs */ if ( uri->opaque ) { return ssnprintf ( ( buf + used ), ( size - used ), "%s:%s", uri->scheme, uri->opaque ); } /* scheme:// */ if ( uri->scheme ) { used += ssnprintf ( ( buf + used ), ( size - used ), "%s://", uri->scheme ); } /* [user[:password]@]host[:port] */ if ( uri->host ) { if ( uri->user ) { used += ssnprintf ( ( buf + used ), ( size - used ), "%s", uri->user ); if ( uri->password ) { used += ssnprintf ( ( buf + used ), ( size - used ), ":%s", uri->password ); } used += ssnprintf ( ( buf + used ), ( size - used ), "@" ); } used += ssnprintf ( ( buf + used ), ( size - used ), "%s", uri->host ); if ( uri->port ) { used += ssnprintf ( ( buf + used ), ( size - used ), ":%s", uri->port ); } } /* /path */ if ( uri->path ) { used += ssnprintf ( ( buf + used ), ( size - used ), "%s", uri->path ); } /* ?query */ if ( uri->query ) { used += ssnprintf ( ( buf + used ), ( size - used ), "?%s", uri->query ); } /* #fragment */ if ( uri->fragment ) { used += ssnprintf ( ( buf + used ), ( size - used ), "#%s", uri->fragment ); } return used; } /** * Duplicate URI * * @v uri URI * @ret uri Duplicate URI * * Creates a modifiable copy of a URI. */ struct uri * uri_dup ( struct uri *uri ) { size_t len = ( unparse_uri ( NULL, 0, uri ) + 1 ); char buf[len]; unparse_uri ( buf, len, uri ); return parse_uri ( buf ); } /** * Resolve base+relative path * * @v base_uri Base path * @v relative_uri Relative path * @ret resolved_uri Resolved path * * Takes a base path (e.g. "/var/lib/tftpboot/vmlinuz" and a relative * path (e.g. "initrd.gz") and produces a new path * (e.g. "/var/lib/tftpboot/initrd.gz"). Note that any non-directory * portion of the base path will automatically be stripped; this * matches the semantics used when resolving the path component of * URIs. */ char * resolve_path ( const char *base_path, const char *relative_path ) { size_t base_len = ( strlen ( base_path ) + 1 ); char base_path_copy[base_len]; char *base_tmp = base_path_copy; /* If relative path is absolute, just re-use it */ if ( relative_path[0] == '/' ) return strdup ( relative_path ); /* Create modifiable copy of path for dirname() */ memcpy ( base_tmp, base_path, base_len ); base_tmp = dirname ( base_tmp ); /* Process "./" and "../" elements */ while ( *relative_path == '.' ) { relative_path++; if ( *relative_path == 0 ) { /* Do nothing */ } else if ( *relative_path == '/' ) { relative_path++; } else if ( *relative_path == '.' ) { relative_path++; if ( *relative_path == 0 ) { base_tmp = dirname ( base_tmp ); } else if ( *relative_path == '/' ) { base_tmp = dirname ( base_tmp ); relative_path++; } else { relative_path -= 2; break; } } else { relative_path--; break; } } /* Create and return new path */ return grub_xasprintf ( "%s%s%s", base_tmp, ( ( base_tmp[ strlen ( base_tmp ) - 1 ] == '/' ) ? "" : "/" ), relative_path ); } /** * Resolve base+relative URI * * @v base_uri Base URI, or NULL * @v relative_uri Relative URI * @ret resolved_uri Resolved URI * * Takes a base URI (e.g. "http://etherboot.org/kernels/vmlinuz" and a * relative URI (e.g. "../initrds/initrd.gz") and produces a new URI * (e.g. "http://etherboot.org/initrds/initrd.gz"). */ struct uri * resolve_uri ( struct uri *base_uri, struct uri *relative_uri ) { struct uri tmp_uri; char *tmp_path = NULL; struct uri *new_uri; /* If relative URI is absolute, just re-use it */ if ( uri_is_absolute ( relative_uri ) || ( ! base_uri ) ) return uri_get ( relative_uri ); /* Mangle URI */ memcpy ( &tmp_uri, base_uri, sizeof ( tmp_uri ) ); if ( relative_uri->path ) { tmp_path = resolve_path ( ( base_uri->path ? base_uri->path : "/" ), relative_uri->path ); tmp_uri.path = tmp_path; tmp_uri.query = relative_uri->query; tmp_uri.fragment = relative_uri->fragment; } else if ( relative_uri->query ) { tmp_uri.query = relative_uri->query; tmp_uri.fragment = relative_uri->fragment; } else if ( relative_uri->fragment ) { tmp_uri.fragment = relative_uri->fragment; } /* Create demangled URI */ new_uri = uri_dup ( &tmp_uri ); free ( tmp_path ); return new_uri; } /** * Test for unreserved URI characters * * @v c Character to test * @ret is_unreserved Character is an unreserved character */ static int is_unreserved_uri_char ( int c ) { /* According to RFC3986, the unreserved character set is * * A-Z a-z 0-9 - _ . ~ */ return ( isupper ( c ) || islower ( c ) || isdigit ( c ) || ( c == '-' ) || ( c == '_' ) || ( c == '.' ) || ( c == '~' ) ); } /** * URI-encode string * * @v raw_string String to be URI-encoded * @v buf Buffer to contain encoded string * @v len Length of buffer * @ret len Length of encoded string (excluding NUL) */ size_t uri_encode ( const char *raw_string, char *buf, size_t len ) { ssize_t remaining = len; size_t used; unsigned char c; if ( len ) buf[0] = '\0'; while ( ( c = *(raw_string++) ) ) { if ( is_unreserved_uri_char ( c ) ) { used = ssnprintf ( buf, remaining, "%c", c ); } else { used = ssnprintf ( buf, remaining, "%%%02X", c ); } buf += used; remaining -= used; } return ( len - remaining ); } /** * Decode URI-encoded string * * @v encoded_string URI-encoded string * @v buf Buffer to contain decoded string * @v len Length of buffer * @ret len Length of decoded string (excluding NUL) */ size_t uri_decode ( const char *encoded_string, char *buf, size_t len ) { ssize_t remaining = len; char hexbuf[3]; char *hexbuf_end; unsigned char c; if ( len ) buf[0] = '\0'; while ( *encoded_string ) { if ( *encoded_string == '%' ) { encoded_string++; snprintf ( hexbuf, sizeof ( hexbuf ), "%s", encoded_string ); c = strtoul ( hexbuf, &hexbuf_end, 16 ); encoded_string += ( hexbuf_end - hexbuf ); } else { c = *(encoded_string++); } ssnprintf ( buf++, remaining--, "%c", c ); } return ( len - remaining ); } debian/grub-extras/disabled/gpxe/src/core/linebuf.c0000664000000000000000000000601112524662415017461 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); /** * @file * * Line buffering * */ #include #include #include #include #include /** * Retrieve buffered-up line * * @v linebuf Line buffer * @ret line Buffered line, or NULL if no line ready to read */ char * buffered_line ( struct line_buffer *linebuf ) { return ( linebuf->ready ? linebuf->data : NULL ); } /** * Discard line buffer contents * * @v linebuf Line buffer */ void empty_line_buffer ( struct line_buffer *linebuf ) { free ( linebuf->data ); linebuf->data = NULL; linebuf->len = 0; linebuf->ready = 0; } /** * Buffer up received data by lines * * @v linebuf Line buffer * @v data New data to add * @v len Length of new data to add * @ret len Consumed length, or negative error number * * After calling line_buffer(), use buffered_line() to determine * whether or not a complete line is available. Carriage returns and * newlines will have been stripped, and the line will be * NUL-terminated. This buffered line is valid only until the next * call to line_buffer() (or to empty_line_buffer()). * * Note that line buffers use dynamically allocated storage; you * should call empty_line_buffer() before freeing a @c struct @c * line_buffer. */ ssize_t line_buffer ( struct line_buffer *linebuf, const char *data, size_t len ) { const char *eol; size_t consume; size_t new_len; char *new_data; /* Free any completed line from previous iteration */ if ( linebuf->ready ) empty_line_buffer ( linebuf ); /* Search for line terminator */ if ( ( eol = memchr ( data, '\n', len ) ) ) { consume = ( eol - data + 1 ); } else { consume = len; } /* Reallocate data buffer and copy in new data */ new_len = ( linebuf->len + consume ); new_data = realloc ( linebuf->data, ( new_len + 1 ) ); if ( ! new_data ) return -ENOMEM; memcpy ( ( new_data + linebuf->len ), data, consume ); new_data[new_len] = '\0'; linebuf->data = new_data; linebuf->len = new_len; /* If we have reached end of line, trim the line and mark as ready */ if ( eol ) { linebuf->data[--linebuf->len] = '\0'; /* trim NL */ if ( linebuf->data[linebuf->len - 1] == '\r' ) linebuf->data[--linebuf->len] = '\0'; /* trim CR */ linebuf->ready = 1; } return consume; } debian/grub-extras/disabled/gpxe/src/core/iobuf.c0000664000000000000000000000464112524662415017150 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include /** @file * * I/O buffers * */ /** * Allocate I/O buffer * * @v len Required length of buffer * @ret iobuf I/O buffer, or NULL if none available * * The I/O buffer will be physically aligned to a multiple of * @c IOBUF_SIZE. */ struct io_buffer * alloc_iob ( size_t len ) { struct io_buffer *iobuf = NULL; void *data; /* Pad to minimum length */ if ( len < IOB_ZLEN ) len = IOB_ZLEN; /* Align buffer length */ len = ( len + __alignof__( *iobuf ) - 1 ) & ~( __alignof__( *iobuf ) - 1 ); /* Allocate memory for buffer plus descriptor */ data = malloc_dma ( len + sizeof ( *iobuf ), IOB_ALIGN ); if ( ! data ) return NULL; iobuf = ( struct io_buffer * ) ( data + len ); iobuf->head = iobuf->data = iobuf->tail = data; iobuf->end = iobuf; return iobuf; } /** * Free I/O buffer * * @v iobuf I/O buffer */ void free_iob ( struct io_buffer *iobuf ) { if ( iobuf ) { assert ( iobuf->head <= iobuf->data ); assert ( iobuf->data <= iobuf->tail ); assert ( iobuf->tail <= iobuf->end ); free_dma ( iobuf->head, ( iobuf->end - iobuf->head ) + sizeof ( *iobuf ) ); } } /** * Ensure I/O buffer has sufficient headroom * * @v iobuf I/O buffer * @v len Required headroom * * This function currently only checks for the required headroom; it * does not reallocate the I/O buffer if required. If we ever have a * code path that requires this functionality, it's a fairly trivial * change to make. */ int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len ) { if ( iob_headroom ( iobuf ) >= len ) return 0; return -ENOBUFS; } debian/grub-extras/disabled/gpxe/src/core/job.c0000664000000000000000000000472212524662415016616 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include /** @file * * Job control interfaces * */ void job_done ( struct job_interface *job, int rc ) { struct job_interface *dest = job_get_dest ( job ); job_unplug ( job ); dest->op->done ( dest, rc ); job_put ( dest ); } void job_kill ( struct job_interface *job ) { struct job_interface *dest = job_get_dest ( job ); job_unplug ( job ); dest->op->kill ( dest ); job_put ( dest ); } void job_progress ( struct job_interface *job, struct job_progress *progress ) { struct job_interface *dest = job_get_dest ( job ); dest->op->progress ( dest, progress ); job_put ( dest ); } /**************************************************************************** * * Helper methods * * These functions are designed to be used as methods in the * job_interface_operations table. * */ void ignore_job_done ( struct job_interface *job __unused, int rc __unused ) { /* Nothing to do */ } void ignore_job_kill ( struct job_interface *job __unused ) { /* Nothing to do */ } void ignore_job_progress ( struct job_interface *job __unused, struct job_progress *progress ) { memset ( progress, 0, sizeof ( *progress ) ); } /** Null job control interface operations */ struct job_interface_operations null_job_ops = { .done = ignore_job_done, .kill = ignore_job_kill, .progress = ignore_job_progress, }; /** * Null job control interface * * This is the interface to which job control interfaces are connected * when unplugged. It will never generate messages, and will silently * absorb all received messages. */ struct job_interface null_job = { .intf = { .dest = &null_job.intf, .refcnt = NULL, }, .op = &null_job_ops, }; debian/grub-extras/disabled/gpxe/src/core/cwuri.c0000664000000000000000000000227112524662415017172 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** @file * * Current working URI * * Somewhat analogous to the current working directory in a POSIX * system. */ /** Current working URI */ struct uri *cwuri = NULL; /** * Change working URI * * @v uri New working URI, or NULL */ void churi ( struct uri *uri ) { struct uri *new_uri; new_uri = resolve_uri ( cwuri, uri ); uri_put ( cwuri ); cwuri = new_uri; } debian/grub-extras/disabled/gpxe/src/core/xfer.c0000664000000000000000000002377012524662415017014 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include /** @file * * Data transfer interfaces * */ /** * Dummy transfer metadata * * This gets passed to xfer_interface::deliver_iob() and equivalents * when no metadata is available. */ static struct xfer_metadata dummy_metadata; /** * Close data transfer interface * * @v xfer Data transfer interface * @v rc Reason for close */ void xfer_close ( struct xfer_interface *xfer, int rc ) { struct xfer_interface *dest = xfer_get_dest ( xfer ); struct xfer_interface_operations *op = xfer->op; DBGC ( xfer, "XFER %p->%p close\n", xfer, dest ); xfer_unplug ( xfer ); xfer_nullify ( xfer ); dest->op->close ( dest, rc ); xfer->op = op; xfer_put ( dest ); } /** * Send redirection event * * @v xfer Data transfer interface * @v type New location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ int xfer_vredirect ( struct xfer_interface *xfer, int type, va_list args ) { struct xfer_interface *dest = xfer_get_dest ( xfer ); int rc; DBGC ( xfer, "XFER %p->%p redirect\n", xfer, dest ); rc = dest->op->vredirect ( dest, type, args ); if ( rc != 0 ) { DBGC ( xfer, "XFER %p<-%p redirect: %s\n", xfer, dest, strerror ( rc ) ); } xfer_put ( dest ); return rc; } /** * Send redirection event * * @v xfer Data transfer interface * @v type New location type * @v ... Remaining arguments depend upon location type * @ret rc Return status code */ int xfer_redirect ( struct xfer_interface *xfer, int type, ... ) { va_list args; int rc; va_start ( args, type ); rc = xfer_vredirect ( xfer, type, args ); va_end ( args ); return rc; } /** * Check flow control window * * @v xfer Data transfer interface * @ret len Length of window */ size_t xfer_window ( struct xfer_interface *xfer ) { struct xfer_interface *dest = xfer_get_dest ( xfer ); size_t len; len = dest->op->window ( dest ); xfer_put ( dest ); return len; } /** * Allocate I/O buffer * * @v xfer Data transfer interface * @v len I/O buffer payload length * @ret iobuf I/O buffer */ struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ) { struct xfer_interface *dest = xfer_get_dest ( xfer ); struct io_buffer *iobuf; DBGC ( xfer, "XFER %p->%p alloc_iob %zd\n", xfer, dest, len ); iobuf = dest->op->alloc_iob ( dest, len ); if ( ! iobuf ) { DBGC ( xfer, "XFER %p<-%p alloc_iob failed\n", xfer, dest ); } xfer_put ( dest ); return iobuf; } /** * Deliver datagram as I/O buffer with metadata * * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ int xfer_deliver_iob_meta ( struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta ) { struct xfer_interface *dest = xfer_get_dest ( xfer ); int rc; DBGC ( xfer, "XFER %p->%p deliver_iob %zd\n", xfer, dest, iob_len ( iobuf ) ); rc = dest->op->deliver_iob ( dest, iobuf, meta ); if ( rc != 0 ) { DBGC ( xfer, "XFER %p<-%p deliver_iob: %s\n", xfer, dest, strerror ( rc ) ); } xfer_put ( dest ); return rc; } /** * Deliver datagram as I/O buffer with metadata * * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @ret rc Return status code */ int xfer_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf ) { return xfer_deliver_iob_meta ( xfer, iobuf, &dummy_metadata ); } /** * Deliver datagram as raw data * * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @ret rc Return status code */ int xfer_deliver_raw ( struct xfer_interface *xfer, const void *data, size_t len ) { struct xfer_interface *dest = xfer_get_dest ( xfer ); int rc; DBGC ( xfer, "XFER %p->%p deliver_raw %p+%zd\n", xfer, dest, data, len ); rc = dest->op->deliver_raw ( dest, data, len ); if ( rc != 0 ) { DBGC ( xfer, "XFER %p<-%p deliver_raw: %s\n", xfer, dest, strerror ( rc ) ); } xfer_put ( dest ); return rc; } /** * Deliver formatted string * * @v xfer Data transfer interface * @v format Format string * @v args Arguments corresponding to the format string * @ret rc Return status code */ int xfer_vprintf ( struct xfer_interface *xfer, const char *format, va_list args ) { size_t len; va_list args_tmp; va_copy ( args_tmp, args ); len = vsnprintf ( NULL, 0, format, args ); { char buf[len + 1]; vsnprintf ( buf, sizeof ( buf ), format, args_tmp ); va_end ( args_tmp ); return xfer_deliver_raw ( xfer, buf, len ); } } /** * Deliver formatted string * * @v xfer Data transfer interface * @v format Format string * @v ... Arguments corresponding to the format string * @ret rc Return status code */ int xfer_printf ( struct xfer_interface *xfer, const char *format, ... ) { va_list args; int rc; va_start ( args, format ); rc = xfer_vprintf ( xfer, format, args ); va_end ( args ); return rc; } /** * Seek to position * * @v xfer Data transfer interface * @v offset Offset to new position * @v whence Basis for new position * @ret rc Return status code */ int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) { struct io_buffer *iobuf; struct xfer_metadata meta = { .offset = offset, .whence = whence, }; DBGC ( xfer, "XFER %p seek %s+%ld\n", xfer, whence_text ( whence ), offset ); /* Allocate and send a zero-length data buffer */ iobuf = xfer_alloc_iob ( xfer, 0 ); if ( ! iobuf ) return -ENOMEM; return xfer_deliver_iob_meta ( xfer, iobuf, &meta ); } /**************************************************************************** * * Helper methods * * These functions are designed to be used as methods in the * xfer_interface_operations table. * */ /** * Ignore close() event * * @v xfer Data transfer interface * @v rc Reason for close */ void ignore_xfer_close ( struct xfer_interface *xfer __unused, int rc __unused ) { /* Nothing to do */ } /** * Ignore vredirect() event * * @v xfer Data transfer interface * @v type New location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ int ignore_xfer_vredirect ( struct xfer_interface *xfer __unused, int type __unused, va_list args __unused ) { return 0; } /** * Unlimited flow control window * * @v xfer Data transfer interface * @ret len Length of window * * This handler indicates that the interface is always ready to accept * data. */ size_t unlimited_xfer_window ( struct xfer_interface *xfer __unused ) { return ~( ( size_t ) 0 ); } /** * No flow control window * * @v xfer Data transfer interface * @ret len Length of window * * This handler indicates that the interface is never ready to accept * data. */ size_t no_xfer_window ( struct xfer_interface *xfer __unused ) { return 0; } /** * Allocate I/O buffer * * @v xfer Data transfer interface * @v len I/O buffer payload length * @ret iobuf I/O buffer */ struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer __unused, size_t len ) { return alloc_iob ( len ); } /** * Deliver datagram as raw data * * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code * * This function is intended to be used as the deliver() method for * data transfer interfaces that prefer to handle raw data. */ int xfer_deliver_as_raw ( struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta __unused ) { int rc; rc = xfer->op->deliver_raw ( xfer, iobuf->data, iob_len ( iobuf ) ); free_iob ( iobuf ); return rc; } /** * Deliver datagram as I/O buffer * * @v xfer Data transfer interface * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code * * This function is intended to be used as the deliver_raw() method * for data transfer interfaces that prefer to handle I/O buffers. */ int xfer_deliver_as_iob ( struct xfer_interface *xfer, const void *data, size_t len ) { struct io_buffer *iobuf; iobuf = xfer->op->alloc_iob ( xfer, len ); if ( ! iobuf ) return -ENOMEM; memcpy ( iob_put ( iobuf, len ), data, len ); return xfer->op->deliver_iob ( xfer, iobuf, &dummy_metadata ); } /** * Ignore datagram as raw data event * * @v xfer Data transfer interface * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code */ int ignore_xfer_deliver_raw ( struct xfer_interface *xfer, const void *data __unused, size_t len ) { DBGC ( xfer, "XFER %p %zd bytes delivered %s\n", xfer, len, ( ( xfer == &null_xfer ) ? "before connection" : "after termination" ) ); return 0; } /** Null data transfer interface operations */ struct xfer_interface_operations null_xfer_ops = { .close = ignore_xfer_close, .vredirect = ignore_xfer_vredirect, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, .deliver_raw = ignore_xfer_deliver_raw, }; /** * Null data transfer interface * * This is the interface to which data transfer interfaces are * connected when unplugged. It will never generate messages, and * will silently absorb all received messages. */ struct xfer_interface null_xfer = XFER_INIT ( &null_xfer_ops ); debian/grub-extras/disabled/gpxe/src/core/interface.c0000664000000000000000000000362212524662415020002 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** @file * * Object communication interfaces * */ /** * Plug an interface into a new destination interface * * @v intf Interface * @v dest New destination interface * * The reference to the existing destination interface is dropped, a * reference to the new destination interface is obtained, and the * interface is updated to point to the new destination interface. * * Note that there is no "unplug" call; instead you must plug the * interface into a null interface. */ void plug ( struct interface *intf, struct interface *dest ) { DBGC ( intf, "INTF %p moving from INTF %p to INTF %p\n", intf, intf->dest, dest ); intf_put ( intf->dest ); intf->dest = intf_get ( dest ); } /** * Plug two interfaces together * * @v a Interface A * @v b Interface B * * Plugs interface A into interface B, and interface B into interface * A. (The basic plug() function is unidirectional; this function is * merely a shorthand for two calls to plug(), hence the name.) */ void plug_plug ( struct interface *a, struct interface *b ) { plug ( a, b ); plug ( b, a ); } debian/grub-extras/disabled/gpxe/src/core/random.c0000664000000000000000000000143312524662415017320 0ustar /** @file * * Random number generation * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include static int32_t rnd_seed = 0; /** * Seed the pseudo-random number generator * * @v seed Seed value */ void srandom ( unsigned int seed ) { rnd_seed = seed; } /** * Generate a pseudo-random number between 0 and 2147483647L or 2147483562? * * @ret rand Pseudo-random number */ long int random ( void ) { int32_t q; if ( ! rnd_seed ) /* Initialize linear congruential generator */ srandom ( currticks() ); /* simplified version of the LCG given in Bruce Schneier's "Applied Cryptography" */ q = ( rnd_seed / 53668 ); rnd_seed = ( 40014 * ( rnd_seed - 53668 * q ) - 12211 * q ); if ( rnd_seed < 0 ) rnd_seed += 2147483563L; return rnd_seed; } debian/grub-extras/disabled/gpxe/src/hci/0000775000000000000000000000000012524676037015513 5ustar debian/grub-extras/disabled/gpxe/src/hci/strerror.c0000664000000000000000000000616212524662415017541 0ustar #include #include #include #include /** @file * * Error descriptions. * * The error numbers used by Etherboot are a superset of those defined * by the PXE specification version 2.1. See errno.h for a listing of * the error values. * * To save space in ROM images, error string tables are optional. Use * the ERRORMSG_XXX options in config.h to select which error string * tables you want to include. If an error string table is omitted, * strerror() will simply return the text "Error 0x". * */ FILE_LICENCE ( GPL2_OR_LATER ); /** * Find error description * * @v errno Error number * @v mask Mask of bits that we care about * @ret errortab Error description, or NULL */ static struct errortab * find_error ( int errno, int mask ) { struct errortab *errortab; for_each_table_entry ( errortab, ERRORTAB ) { if ( ( ( errortab->errno ^ errno ) & mask ) == 0 ) return errortab; } return NULL; } /** * Find closest error description * * @v errno Error number * @ret errortab Error description, or NULL * * */ static struct errortab * find_closest_error ( int errno ) { struct errortab *errortab; /* First, look for an exact match */ if ( ( errortab = find_error ( errno, 0x7fffffff ) ) != NULL ) return errortab; /* Second, try masking off the gPXE-specific bit and seeing if * we have an entry for the generic POSIX error message. */ if ( ( errortab = find_error ( errno, 0x4f0000ff ) ) != NULL ) return errortab; return NULL; } /** * Retrieve string representation of error number. * * @v errno/rc Error number or return status code * @ret strerror Pointer to error text * * If the error is not found in the linked-in error tables, generates * a generic "Error 0x" message. * * The pointer returned by strerror() is valid only until the next * call to strerror(). * */ const char * strerror ( int errno ) { static char errbuf[64]; struct errortab *errortab; /* Allow for strerror(rc) as well as strerror(errno) */ if ( errno < 0 ) errno = -errno; /* Find the error description, if one exists */ errortab = find_closest_error ( errno ); /* Construct the error message */ if ( errortab ) { snprintf ( errbuf, sizeof ( errbuf ), "%s (#%08x)", errortab->text, errno ); } else { snprintf ( errbuf, sizeof ( errbuf ), "Error #%08x", errno ); } return errbuf; } /* Do not include ERRFILE portion in the numbers in the error table */ #undef ERRFILE #define ERRFILE 0 /** The most common errors */ struct errortab common_errors[] __errortab = { { 0, "No error" }, { EACCES, "Permission denied" }, { ECANCELED, "Operation cancelled" }, { ECONNRESET, "Connection reset" }, { EINVAL, "Invalid argument" }, { EIO, "Input/output error" }, { ENETUNREACH, "Network unreachable" }, { ENODEV, "No such device" }, { ENOENT, "File not found" }, { ENOEXEC, "Not an executable image" }, { ENOMEM, "Out of memory" }, { ENOSPC, "No space left on device" }, { ENOTCONN, "Not connected" }, { ENOTSUP, "Not supported" }, { EPERM, "Operation not permitted" }, { ERANGE, "Out of range" }, { ETIMEDOUT, "Connection timed out" }, }; debian/grub-extras/disabled/gpxe/src/net/0000775000000000000000000000000012524676037015536 5ustar debian/grub-extras/disabled/gpxe/src/net/tcp/0000775000000000000000000000000012524676037016324 5ustar debian/grub-extras/disabled/gpxe/src/net/tcp/https.c0000664000000000000000000000264612524662415017635 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); /** * @file * * Secure Hyper Text Transfer Protocol (HTTPS) * */ #include #include #include #include #include FEATURE ( FEATURE_PROTOCOL, "HTTPS", DHCP_EB_FEATURE_HTTPS, 1 ); /** * Initiate an HTTPS connection * * @v xfer Data transfer interface * @v uri Uniform Resource Identifier * @ret rc Return status code */ static int https_open ( struct xfer_interface *xfer, struct uri *uri ) { return http_open_filter ( xfer, uri, HTTPS_PORT, add_tls ); } /** HTTPS URI opener */ struct uri_opener https_uri_opener __uri_opener = { .scheme = "https", .open = https_open, }; debian/grub-extras/disabled/gpxe/src/net/tcp/iscsi.c0000664000000000000000000014727412524662415017614 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * iSCSI protocol * */ FEATURE ( FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1 ); /** iSCSI initiator name (explicitly specified) */ static char *iscsi_explicit_initiator_iqn; /** Default iSCSI initiator name (constructed from hostname) */ static char *iscsi_default_initiator_iqn; /** iSCSI initiator username */ static char *iscsi_initiator_username; /** iSCSI initiator password */ static char *iscsi_initiator_password; /** iSCSI target username */ static char *iscsi_target_username; /** iSCSI target password */ static char *iscsi_target_password; static void iscsi_start_tx ( struct iscsi_session *iscsi ); static void iscsi_start_login ( struct iscsi_session *iscsi ); static void iscsi_start_data_out ( struct iscsi_session *iscsi, unsigned int datasn ); /** * Finish receiving PDU data into buffer * * @v iscsi iSCSI session */ static void iscsi_rx_buffered_data_done ( struct iscsi_session *iscsi ) { free ( iscsi->rx_buffer ); iscsi->rx_buffer = NULL; } /** * Free iSCSI session * * @v refcnt Reference counter */ static void iscsi_free ( struct refcnt *refcnt ) { struct iscsi_session *iscsi = container_of ( refcnt, struct iscsi_session, refcnt ); free ( iscsi->target_address ); free ( iscsi->target_iqn ); free ( iscsi->initiator_username ); free ( iscsi->initiator_password ); free ( iscsi->target_username ); free ( iscsi->target_password ); chap_finish ( &iscsi->chap ); iscsi_rx_buffered_data_done ( iscsi ); free ( iscsi ); } /** * Open iSCSI transport-layer connection * * @v iscsi iSCSI session * @ret rc Return status code */ static int iscsi_open_connection ( struct iscsi_session *iscsi ) { struct sockaddr_tcpip target; int rc; assert ( iscsi->tx_state == ISCSI_TX_IDLE ); assert ( iscsi->rx_state == ISCSI_RX_BHS ); assert ( iscsi->rx_offset == 0 ); /* Open socket */ memset ( &target, 0, sizeof ( target ) ); target.st_port = htons ( iscsi->target_port ); if ( ( rc = xfer_open_named_socket ( &iscsi->socket, SOCK_STREAM, ( struct sockaddr * ) &target, iscsi->target_address, NULL ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not open socket: %s\n", iscsi, strerror ( rc ) ); return rc; } /* Enter security negotiation phase */ iscsi->status = ( ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE | ISCSI_STATUS_STRINGS_SECURITY ); if ( iscsi->target_username ) iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_REQUIRED; /* Assign fresh initiator task tag */ iscsi->itt++; /* Initiate login */ iscsi_start_login ( iscsi ); return 0; } /** * Close iSCSI transport-layer connection * * @v iscsi iSCSI session * @v rc Reason for close * * Closes the transport-layer connection and resets the session state * ready to attempt a fresh login. */ static void iscsi_close_connection ( struct iscsi_session *iscsi, int rc ) { /* Close all data transfer interfaces */ xfer_close ( &iscsi->socket, rc ); /* Clear connection status */ iscsi->status = 0; /* Reset TX and RX state machines */ iscsi->tx_state = ISCSI_TX_IDLE; iscsi->rx_state = ISCSI_RX_BHS; iscsi->rx_offset = 0; /* Free any temporary dynamically allocated memory */ chap_finish ( &iscsi->chap ); iscsi_rx_buffered_data_done ( iscsi ); } /** * Mark iSCSI SCSI operation as complete * * @v iscsi iSCSI session * @v rc Return status code * * Note that iscsi_scsi_done() will not close the connection, and must * therefore be called only when the internal state machines are in an * appropriate state, otherwise bad things may happen on the next call * to iscsi_issue(). The general rule is to call iscsi_scsi_done() * only at the end of receiving a PDU; at this point the TX and RX * engines should both be idle. */ static void iscsi_scsi_done ( struct iscsi_session *iscsi, int rc ) { assert ( iscsi->tx_state == ISCSI_TX_IDLE ); assert ( iscsi->command != NULL ); iscsi->command->rc = rc; iscsi->command = NULL; } /**************************************************************************** * * iSCSI SCSI command issuing * */ /** * Build iSCSI SCSI command BHS * * @v iscsi iSCSI session * * We don't currently support bidirectional commands (i.e. with both * Data-In and Data-Out segments); these would require providing code * to generate an AHS, and there doesn't seem to be any need for it at * the moment. */ static void iscsi_start_command ( struct iscsi_session *iscsi ) { struct iscsi_bhs_scsi_command *command = &iscsi->tx_bhs.scsi_command; assert ( ! ( iscsi->command->data_in && iscsi->command->data_out ) ); /* Construct BHS and initiate transmission */ iscsi_start_tx ( iscsi ); command->opcode = ISCSI_OPCODE_SCSI_COMMAND; command->flags = ( ISCSI_FLAG_FINAL | ISCSI_COMMAND_ATTR_SIMPLE ); if ( iscsi->command->data_in ) command->flags |= ISCSI_COMMAND_FLAG_READ; if ( iscsi->command->data_out ) command->flags |= ISCSI_COMMAND_FLAG_WRITE; /* lengths left as zero */ command->lun = iscsi->lun; command->itt = htonl ( ++iscsi->itt ); command->exp_len = htonl ( iscsi->command->data_in_len | iscsi->command->data_out_len ); command->cmdsn = htonl ( iscsi->cmdsn ); command->expstatsn = htonl ( iscsi->statsn + 1 ); memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb )); DBGC2 ( iscsi, "iSCSI %p start " SCSI_CDB_FORMAT " %s %#zx\n", iscsi, SCSI_CDB_DATA ( command->cdb ), ( iscsi->command->data_in ? "in" : "out" ), ( iscsi->command->data_in ? iscsi->command->data_in_len : iscsi->command->data_out_len ) ); } /** * Receive data segment of an iSCSI SCSI response PDU * * @v iscsi iSCSI session * @v data Received data * @v len Length of received data * @v remaining Data remaining after this data * @ret rc Return status code */ static int iscsi_rx_scsi_response ( struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining ) { struct iscsi_bhs_scsi_response *response = &iscsi->rx_bhs.scsi_response; int sense_offset; /* Capture the sense response code as it floats past, if present */ sense_offset = ISCSI_SENSE_RESPONSE_CODE_OFFSET - iscsi->rx_offset; if ( ( sense_offset >= 0 ) && len ) { iscsi->command->sense_response = * ( ( char * ) data + sense_offset ); } /* Wait for whole SCSI response to arrive */ if ( remaining ) return 0; /* Record SCSI status code */ iscsi->command->status = response->status; /* Check for errors */ if ( response->response != ISCSI_RESPONSE_COMMAND_COMPLETE ) return -EIO; /* Mark as completed */ iscsi_scsi_done ( iscsi, 0 ); return 0; } /** * Receive data segment of an iSCSI data-in PDU * * @v iscsi iSCSI session * @v data Received data * @v len Length of received data * @v remaining Data remaining after this data * @ret rc Return status code */ static int iscsi_rx_data_in ( struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining ) { struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in; unsigned long offset; /* Copy data to data-in buffer */ offset = ntohl ( data_in->offset ) + iscsi->rx_offset; assert ( iscsi->command != NULL ); assert ( iscsi->command->data_in ); assert ( ( offset + len ) <= iscsi->command->data_in_len ); copy_to_user ( iscsi->command->data_in, offset, data, len ); /* Wait for whole SCSI response to arrive */ if ( remaining ) return 0; /* Mark as completed if status is present */ if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) { assert ( ( offset + len ) == iscsi->command->data_in_len ); assert ( data_in->flags & ISCSI_FLAG_FINAL ); iscsi->command->status = data_in->status; /* iSCSI cannot return an error status via a data-in */ iscsi_scsi_done ( iscsi, 0 ); } return 0; } /** * Receive data segment of an iSCSI R2T PDU * * @v iscsi iSCSI session * @v data Received data * @v len Length of received data * @v remaining Data remaining after this data * @ret rc Return status code */ static int iscsi_rx_r2t ( struct iscsi_session *iscsi, const void *data __unused, size_t len __unused, size_t remaining __unused ) { struct iscsi_bhs_r2t *r2t = &iscsi->rx_bhs.r2t; /* Record transfer parameters and trigger first data-out */ iscsi->ttt = ntohl ( r2t->ttt ); iscsi->transfer_offset = ntohl ( r2t->offset ); iscsi->transfer_len = ntohl ( r2t->len ); iscsi_start_data_out ( iscsi, 0 ); return 0; } /** * Build iSCSI data-out BHS * * @v iscsi iSCSI session * @v datasn Data sequence number within the transfer * */ static void iscsi_start_data_out ( struct iscsi_session *iscsi, unsigned int datasn ) { struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; unsigned long offset; unsigned long remaining; unsigned long len; /* We always send 512-byte Data-Out PDUs; this removes the * need to worry about the target's MaxRecvDataSegmentLength. */ offset = datasn * 512; remaining = iscsi->transfer_len - offset; len = remaining; if ( len > 512 ) len = 512; /* Construct BHS and initiate transmission */ iscsi_start_tx ( iscsi ); data_out->opcode = ISCSI_OPCODE_DATA_OUT; if ( len == remaining ) data_out->flags = ( ISCSI_FLAG_FINAL ); ISCSI_SET_LENGTHS ( data_out->lengths, 0, len ); data_out->lun = iscsi->lun; data_out->itt = htonl ( iscsi->itt ); data_out->ttt = htonl ( iscsi->ttt ); data_out->expstatsn = htonl ( iscsi->statsn + 1 ); data_out->datasn = htonl ( datasn ); data_out->offset = htonl ( iscsi->transfer_offset + offset ); DBGC ( iscsi, "iSCSI %p start data out DataSN %#x len %#lx\n", iscsi, datasn, len ); } /** * Complete iSCSI data-out PDU transmission * * @v iscsi iSCSI session * */ static void iscsi_data_out_done ( struct iscsi_session *iscsi ) { struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; /* If we haven't reached the end of the sequence, start * sending the next data-out PDU. */ if ( ! ( data_out->flags & ISCSI_FLAG_FINAL ) ) iscsi_start_data_out ( iscsi, ntohl ( data_out->datasn ) + 1 ); } /** * Send iSCSI data-out data segment * * @v iscsi iSCSI session * @ret rc Return status code */ static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) { struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; struct io_buffer *iobuf; unsigned long offset; size_t len; offset = ntohl ( data_out->offset ); len = ISCSI_DATA_LEN ( data_out->lengths ); assert ( iscsi->command != NULL ); assert ( iscsi->command->data_out ); assert ( ( offset + len ) <= iscsi->command->data_out_len ); iobuf = xfer_alloc_iob ( &iscsi->socket, len ); if ( ! iobuf ) return -ENOMEM; copy_from_user ( iob_put ( iobuf, len ), iscsi->command->data_out, offset, len ); return xfer_deliver_iob ( &iscsi->socket, iobuf ); } /**************************************************************************** * * iSCSI login * */ /** * Build iSCSI login request strings * * @v iscsi iSCSI session * * These are the initial set of strings sent in the first login * request PDU. We want the following settings: * * HeaderDigest=None * DataDigest=None * MaxConnections is irrelevant; we make only one connection anyway * InitialR2T=Yes [1] * ImmediateData is irrelevant; we never send immediate data * MaxRecvDataSegmentLength=8192 (default; we don't care) [3] * MaxBurstLength=262144 (default; we don't care) [3] * FirstBurstLength=262144 (default; we don't care) * DefaultTime2Wait=0 [2] * DefaultTime2Retain=0 [2] * MaxOutstandingR2T=1 * DataPDUInOrder=Yes * DataSequenceInOrder=Yes * ErrorRecoveryLevel=0 * * [1] InitialR2T has an OR resolution function, so the target may * force us to use it. We therefore simplify our logic by always * using it. * * [2] These ensure that we can safely start a new task once we have * reconnected after a failure, without having to manually tidy up * after the old one. * * [3] We are quite happy to use the RFC-defined default values for * these parameters, but some targets (notably OpenSolaris) * incorrectly assume a default value of zero, so we explicitly * specify the default values. */ static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi, void *data, size_t len ) { unsigned int used = 0; unsigned int i; const char *auth_method; if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) { /* Default to allowing no authentication */ auth_method = "None"; /* If we have a credential to supply, permit CHAP */ if ( iscsi->initiator_username ) auth_method = "CHAP,None"; /* If we have a credential to check, force CHAP */ if ( iscsi->target_username ) auth_method = "CHAP"; used += ssnprintf ( data + used, len - used, "InitiatorName=%s%c" "TargetName=%s%c" "SessionType=Normal%c" "AuthMethod=%s%c", iscsi_initiator_iqn(), 0, iscsi->target_iqn, 0, 0, auth_method, 0 ); } if ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_ALGORITHM ) { used += ssnprintf ( data + used, len - used, "CHAP_A=5%c", 0 ); } if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) ) { assert ( iscsi->initiator_username != NULL ); used += ssnprintf ( data + used, len - used, "CHAP_N=%s%cCHAP_R=0x", iscsi->initiator_username, 0 ); for ( i = 0 ; i < iscsi->chap.response_len ; i++ ) { used += ssnprintf ( data + used, len - used, "%02x", iscsi->chap.response[i] ); } used += ssnprintf ( data + used, len - used, "%c", 0 ); } if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_CHALLENGE ) ) { used += ssnprintf ( data + used, len - used, "CHAP_I=%d%cCHAP_C=0x", iscsi->chap_challenge[0], 0 ); for ( i = 1 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) { used += ssnprintf ( data + used, len - used, "%02x", iscsi->chap_challenge[i] ); } used += ssnprintf ( data + used, len - used, "%c", 0 ); } if ( iscsi->status & ISCSI_STATUS_STRINGS_OPERATIONAL ) { used += ssnprintf ( data + used, len - used, "HeaderDigest=None%c" "DataDigest=None%c" "InitialR2T=Yes%c" "MaxRecvDataSegmentLength=8192%c" "MaxBurstLength=262144%c" "DefaultTime2Wait=0%c" "DefaultTime2Retain=0%c" "MaxOutstandingR2T=1%c" "DataPDUInOrder=Yes%c" "DataSequenceInOrder=Yes%c" "ErrorRecoveryLevel=0%c", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); } return used; } /** * Build iSCSI login request BHS * * @v iscsi iSCSI session */ static void iscsi_start_login ( struct iscsi_session *iscsi ) { struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request; int len; /* Construct BHS and initiate transmission */ iscsi_start_tx ( iscsi ); request->opcode = ( ISCSI_OPCODE_LOGIN_REQUEST | ISCSI_FLAG_IMMEDIATE ); request->flags = ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) | ISCSI_LOGIN_FLAG_TRANSITION ); /* version_max and version_min left as zero */ len = iscsi_build_login_request_strings ( iscsi, NULL, 0 ); ISCSI_SET_LENGTHS ( request->lengths, 0, len ); request->isid_iana_en = htonl ( ISCSI_ISID_IANA | IANA_EN_FEN_SYSTEMS ); /* isid_iana_qual left as zero */ request->tsih = htons ( iscsi->tsih ); request->itt = htonl ( iscsi->itt ); /* cid left as zero */ request->cmdsn = htonl ( iscsi->cmdsn ); request->expstatsn = htonl ( iscsi->statsn + 1 ); } /** * Complete iSCSI login request PDU transmission * * @v iscsi iSCSI session * */ static void iscsi_login_request_done ( struct iscsi_session *iscsi ) { /* Clear any "strings to send" flags */ iscsi->status &= ~ISCSI_STATUS_STRINGS_MASK; /* Free any dynamically allocated storage used for login */ chap_finish ( &iscsi->chap ); } /** * Transmit data segment of an iSCSI login request PDU * * @v iscsi iSCSI session * @ret rc Return status code * * For login requests, the data segment consists of the login strings. */ static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) { struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request; struct io_buffer *iobuf; size_t len; len = ISCSI_DATA_LEN ( request->lengths ); iobuf = xfer_alloc_iob ( &iscsi->socket, len ); if ( ! iobuf ) return -ENOMEM; iob_put ( iobuf, len ); iscsi_build_login_request_strings ( iscsi, iobuf->data, len ); return xfer_deliver_iob ( &iscsi->socket, iobuf ); } /** * Handle iSCSI TargetAddress text value * * @v iscsi iSCSI session * @v value TargetAddress value * @ret rc Return status code */ static int iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi, const char *value ) { char *separator; DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value ); /* Replace target address */ free ( iscsi->target_address ); iscsi->target_address = strdup ( value ); if ( ! iscsi->target_address ) return -ENOMEM; /* Replace target port */ iscsi->target_port = htons ( ISCSI_PORT ); separator = strchr ( iscsi->target_address, ':' ); if ( separator ) { *separator = '\0'; iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 ); } return 0; } /** * Handle iSCSI AuthMethod text value * * @v iscsi iSCSI session * @v value AuthMethod value * @ret rc Return status code */ static int iscsi_handle_authmethod_value ( struct iscsi_session *iscsi, const char *value ) { /* If server requests CHAP, send the CHAP_A string */ if ( strcmp ( value, "CHAP" ) == 0 ) { DBGC ( iscsi, "iSCSI %p initiating CHAP authentication\n", iscsi ); iscsi->status |= ( ISCSI_STATUS_STRINGS_CHAP_ALGORITHM | ISCSI_STATUS_AUTH_FORWARD_REQUIRED ); } return 0; } /** * Handle iSCSI CHAP_A text value * * @v iscsi iSCSI session * @v value CHAP_A value * @ret rc Return status code */ static int iscsi_handle_chap_a_value ( struct iscsi_session *iscsi, const char *value ) { /* We only ever offer "5" (i.e. MD5) as an algorithm, so if * the server responds with anything else it is a protocol * violation. */ if ( strcmp ( value, "5" ) != 0 ) { DBGC ( iscsi, "iSCSI %p got invalid CHAP algorithm \"%s\"\n", iscsi, value ); return -EPROTO; } return 0; } /** * Handle iSCSI CHAP_I text value * * @v iscsi iSCSI session * @v value CHAP_I value * @ret rc Return status code */ static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi, const char *value ) { unsigned int identifier; char *endp; int rc; /* The CHAP identifier is an integer value */ identifier = strtoul ( value, &endp, 0 ); if ( *endp != '\0' ) { DBGC ( iscsi, "iSCSI %p saw invalid CHAP identifier \"%s\"\n", iscsi, value ); return -EPROTO; } /* Prepare for CHAP with MD5 */ chap_finish ( &iscsi->chap ); if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n", iscsi, strerror ( rc ) ); return rc; } /* Identifier and secret are the first two components of the * challenge. */ chap_set_identifier ( &iscsi->chap, identifier ); if ( iscsi->initiator_password ) { chap_update ( &iscsi->chap, iscsi->initiator_password, strlen ( iscsi->initiator_password ) ); } return 0; } /** * Handle iSCSI CHAP_C text value * * @v iscsi iSCSI session * @v value CHAP_C value * @ret rc Return status code */ static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi, const char *value ) { char buf[3]; char *endp; uint8_t byte; unsigned int i; /* Check and strip leading "0x" */ if ( ( value[0] != '0' ) || ( value[1] != 'x' ) ) { DBGC ( iscsi, "iSCSI %p saw invalid CHAP challenge \"%s\"\n", iscsi, value ); return -EPROTO; } value += 2; /* Process challenge an octet at a time */ for ( ; ( value[0] && value[1] ) ; value += 2 ) { memcpy ( buf, value, 2 ); buf[2] = 0; byte = strtoul ( buf, &endp, 16 ); if ( *endp != '\0' ) { DBGC ( iscsi, "iSCSI %p saw invalid CHAP challenge " "byte \"%s\"\n", iscsi, buf ); return -EPROTO; } chap_update ( &iscsi->chap, &byte, sizeof ( byte ) ); } /* Build CHAP response */ DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi ); chap_respond ( &iscsi->chap ); iscsi->status |= ISCSI_STATUS_STRINGS_CHAP_RESPONSE; /* Send CHAP challenge, if applicable */ if ( iscsi->target_username ) { iscsi->status |= ISCSI_STATUS_STRINGS_CHAP_CHALLENGE; /* Generate CHAP challenge data */ for ( i = 0 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) { iscsi->chap_challenge[i] = random(); } } return 0; } /** * Handle iSCSI CHAP_N text value * * @v iscsi iSCSI session * @v value CHAP_N value * @ret rc Return status code */ static int iscsi_handle_chap_n_value ( struct iscsi_session *iscsi, const char *value ) { /* The target username isn't actually involved at any point in * the authentication process; it merely serves to identify * which password the target is using to generate the CHAP * response. We unnecessarily verify that the username is as * expected, in order to provide mildly helpful diagnostics if * the target is supplying the wrong username/password * combination. */ if ( iscsi->target_username && ( strcmp ( iscsi->target_username, value ) != 0 ) ) { DBGC ( iscsi, "iSCSI %p target username \"%s\" incorrect " "(wanted \"%s\")\n", iscsi, value, iscsi->target_username ); return -EACCES; } return 0; } /** * Handle iSCSI CHAP_R text value * * @v iscsi iSCSI session * @v value CHAP_R value * @ret rc Return status code */ static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi, const char *value ) { char buf[3]; char *endp; uint8_t byte; unsigned int i; int rc; /* Generate CHAP response for verification */ chap_finish ( &iscsi->chap ); if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n", iscsi, strerror ( rc ) ); return rc; } chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] ); if ( iscsi->target_password ) { chap_update ( &iscsi->chap, iscsi->target_password, strlen ( iscsi->target_password ) ); } chap_update ( &iscsi->chap, &iscsi->chap_challenge[1], ( sizeof ( iscsi->chap_challenge ) - 1 ) ); chap_respond ( &iscsi->chap ); /* Check and strip leading "0x" */ if ( ( value[0] != '0' ) || ( value[1] != 'x' ) ) { DBGC ( iscsi, "iSCSI %p saw invalid CHAP response \"%s\"\n", iscsi, value ); return -EPROTO; } value += 2; /* Check CHAP response length */ if ( strlen ( value ) != ( 2 * iscsi->chap.response_len ) ) { DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n", iscsi ); return -EPROTO; } /* Process response an octet at a time */ for ( i = 0 ; ( value[0] && value[1] ) ; value += 2, i++ ) { memcpy ( buf, value, 2 ); buf[2] = 0; byte = strtoul ( buf, &endp, 16 ); if ( *endp != '\0' ) { DBGC ( iscsi, "iSCSI %p saw invalid CHAP response " "byte \"%s\"\n", iscsi, buf ); return -EPROTO; } if ( byte != iscsi->chap.response[i] ) { DBGC ( iscsi, "iSCSI %p saw incorrect CHAP " "response\n", iscsi ); return -EACCES; } } assert ( i == iscsi->chap.response_len ); /* Mark session as authenticated */ iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_OK; return 0; } /** An iSCSI text string that we want to handle */ struct iscsi_string_type { /** String key * * This is the portion up to and including the "=" sign, * e.g. "InitiatorName=", "CHAP_A=", etc. */ const char *key; /** Handle iSCSI string value * * @v iscsi iSCSI session * @v value iSCSI string value * @ret rc Return status code */ int ( * handle ) ( struct iscsi_session *iscsi, const char *value ); }; /** iSCSI text strings that we want to handle */ static struct iscsi_string_type iscsi_string_types[] = { { "TargetAddress=", iscsi_handle_targetaddress_value }, { "AuthMethod=", iscsi_handle_authmethod_value }, { "CHAP_A=", iscsi_handle_chap_a_value }, { "CHAP_I=", iscsi_handle_chap_i_value }, { "CHAP_C=", iscsi_handle_chap_c_value }, { "CHAP_N=", iscsi_handle_chap_n_value }, { "CHAP_R=", iscsi_handle_chap_r_value }, { NULL, NULL } }; /** * Handle iSCSI string * * @v iscsi iSCSI session * @v string iSCSI string (in "key=value" format) * @ret rc Return status code */ static int iscsi_handle_string ( struct iscsi_session *iscsi, const char *string ) { struct iscsi_string_type *type; size_t key_len; int rc; for ( type = iscsi_string_types ; type->key ; type++ ) { key_len = strlen ( type->key ); if ( strncmp ( string, type->key, key_len ) != 0 ) continue; DBGC ( iscsi, "iSCSI %p handling %s\n", iscsi, string ); if ( ( rc = type->handle ( iscsi, ( string + key_len ) ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not handle %s: %s\n", iscsi, string, strerror ( rc ) ); return rc; } return 0; } DBGC ( iscsi, "iSCSI %p ignoring %s\n", iscsi, string ); return 0; } /** * Handle iSCSI strings * * @v iscsi iSCSI session * @v string iSCSI string buffer * @v len Length of string buffer * @ret rc Return status code */ static int iscsi_handle_strings ( struct iscsi_session *iscsi, const char *strings, size_t len ) { size_t string_len; int rc; /* Handle each string in turn, taking care not to overrun the * data buffer in case of badly-terminated data. */ while ( 1 ) { string_len = ( strnlen ( strings, len ) + 1 ); if ( string_len > len ) break; if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 ) return rc; strings += string_len; len -= string_len; } return 0; } /** * Receive PDU data into buffer * * @v iscsi iSCSI session * @v data Data to receive * @v len Length of data * @ret rc Return status code * * This can be used when the RX PDU type handler wishes to buffer up * all received data and process the PDU as a single unit. The caller * is repsonsible for calling iscsi_rx_buffered_data_done() after * processing the data. */ static int iscsi_rx_buffered_data ( struct iscsi_session *iscsi, const void *data, size_t len ) { /* Allocate buffer on first call */ if ( ! iscsi->rx_buffer ) { iscsi->rx_buffer = malloc ( iscsi->rx_len ); if ( ! iscsi->rx_buffer ) return -ENOMEM; } /* Copy data to buffer */ assert ( ( iscsi->rx_offset + len ) <= iscsi->rx_len ); memcpy ( ( iscsi->rx_buffer + iscsi->rx_offset ), data, len ); return 0; } /** * Convert iSCSI response status to return status code * * @v status_class iSCSI status class * @v status_detail iSCSI status detail * @ret rc Return status code */ static int iscsi_status_to_rc ( unsigned int status_class, unsigned int status_detail ) { switch ( status_class ) { case ISCSI_STATUS_INITIATOR_ERROR : switch ( status_detail ) { case ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION : return -EACCES; case ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION : return -EPERM; case ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND : case ISCSI_STATUS_INITIATOR_ERROR_REMOVED : return -ENODEV; default : return -ENOTSUP; } case ISCSI_STATUS_TARGET_ERROR : return -EIO; default : return -EINVAL; } } /** * Receive data segment of an iSCSI login response PDU * * @v iscsi iSCSI session * @v data Received data * @v len Length of received data * @v remaining Data remaining after this data * @ret rc Return status code */ static int iscsi_rx_login_response ( struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining ) { struct iscsi_bhs_login_response *response = &iscsi->rx_bhs.login_response; int rc; /* Buffer up the PDU data */ if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not buffer login response: %s\n", iscsi, strerror ( rc ) ); return rc; } if ( remaining ) return 0; /* Process string data and discard string buffer */ if ( ( rc = iscsi_handle_strings ( iscsi, iscsi->rx_buffer, iscsi->rx_len ) ) != 0 ) return rc; iscsi_rx_buffered_data_done ( iscsi ); /* Check for login redirection */ if ( response->status_class == ISCSI_STATUS_REDIRECT ) { DBGC ( iscsi, "iSCSI %p redirecting to new server\n", iscsi ); iscsi_close_connection ( iscsi, 0 ); if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not redirect: %s\n ", iscsi, strerror ( rc ) ); return rc; } return 0; } /* Check for fatal errors */ if ( response->status_class != 0 ) { DBGC ( iscsi, "iSCSI login failure: class %02x detail %02x\n", response->status_class, response->status_detail ); rc = iscsi_status_to_rc ( response->status_class, response->status_detail ); iscsi->instant_rc = rc; return rc; } /* Handle login transitions */ if ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) { iscsi->status &= ~( ISCSI_STATUS_PHASE_MASK | ISCSI_STATUS_STRINGS_MASK ); switch ( response->flags & ISCSI_LOGIN_NSG_MASK ) { case ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION: iscsi->status |= ( ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE | ISCSI_STATUS_STRINGS_OPERATIONAL ); break; case ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE: iscsi->status |= ISCSI_STATUS_FULL_FEATURE_PHASE; break; default: DBGC ( iscsi, "iSCSI %p got invalid response flags " "%02x\n", iscsi, response->flags ); return -EIO; } } /* Send next login request PDU if we haven't reached the full * feature phase yet. */ if ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) != ISCSI_STATUS_FULL_FEATURE_PHASE ) { iscsi_start_login ( iscsi ); return 0; } /* Check that target authentication was successful (if required) */ if ( ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) && ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_OK ) ) { DBGC ( iscsi, "iSCSI %p nefarious target tried to bypass " "authentication\n", iscsi ); return -EPROTO; } /* Reset retry count */ iscsi->retry_count = 0; /* Record TSIH for future reference */ iscsi->tsih = ntohl ( response->tsih ); /* Send the actual SCSI command */ iscsi_start_command ( iscsi ); return 0; } /**************************************************************************** * * iSCSI to socket interface * */ /** * Start up a new TX PDU * * @v iscsi iSCSI session * * This initiates the process of sending a new PDU. Only one PDU may * be in transit at any one time. */ static void iscsi_start_tx ( struct iscsi_session *iscsi ) { assert ( iscsi->tx_state == ISCSI_TX_IDLE ); /* Initialise TX BHS */ memset ( &iscsi->tx_bhs, 0, sizeof ( iscsi->tx_bhs ) ); /* Flag TX engine to start transmitting */ iscsi->tx_state = ISCSI_TX_BHS; } /** * Transmit nothing * * @v iscsi iSCSI session * @ret rc Return status code */ static int iscsi_tx_nothing ( struct iscsi_session *iscsi __unused ) { return 0; } /** * Transmit basic header segment of an iSCSI PDU * * @v iscsi iSCSI session * @ret rc Return status code */ static int iscsi_tx_bhs ( struct iscsi_session *iscsi ) { return xfer_deliver_raw ( &iscsi->socket, &iscsi->tx_bhs, sizeof ( iscsi->tx_bhs ) ); } /** * Transmit data segment of an iSCSI PDU * * @v iscsi iSCSI session * @ret rc Return status code * * Handle transmission of part of a PDU data segment. iscsi::tx_bhs * will be valid when this is called. */ static int iscsi_tx_data ( struct iscsi_session *iscsi ) { struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; switch ( common->opcode & ISCSI_OPCODE_MASK ) { case ISCSI_OPCODE_DATA_OUT: return iscsi_tx_data_out ( iscsi ); case ISCSI_OPCODE_LOGIN_REQUEST: return iscsi_tx_login_request ( iscsi ); default: /* Nothing to send in other states */ return 0; } } /** * Transmit data padding of an iSCSI PDU * * @v iscsi iSCSI session * @ret rc Return status code * * Handle transmission of any data padding in a PDU data segment. * iscsi::tx_bhs will be valid when this is called. */ static int iscsi_tx_data_padding ( struct iscsi_session *iscsi ) { static const char pad[] = { '\0', '\0', '\0' }; struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; size_t pad_len; pad_len = ISCSI_DATA_PAD_LEN ( common->lengths ); if ( ! pad_len ) return 0; return xfer_deliver_raw ( &iscsi->socket, pad, pad_len ); } /** * Complete iSCSI PDU transmission * * @v iscsi iSCSI session * * Called when a PDU has been completely transmitted and the TX state * machine is about to enter the idle state. iscsi::tx_bhs will be * valid for the just-completed PDU when this is called. */ static void iscsi_tx_done ( struct iscsi_session *iscsi ) { struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; switch ( common->opcode & ISCSI_OPCODE_MASK ) { case ISCSI_OPCODE_DATA_OUT: iscsi_data_out_done ( iscsi ); case ISCSI_OPCODE_LOGIN_REQUEST: iscsi_login_request_done ( iscsi ); default: /* No action */ break; } } /** * Transmit iSCSI PDU * * @v iscsi iSCSI session * @v buf Temporary data buffer * @v len Length of temporary data buffer * * Constructs data to be sent for the current TX state */ static void iscsi_tx_step ( struct process *process ) { struct iscsi_session *iscsi = container_of ( process, struct iscsi_session, process ); struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; int ( * tx ) ( struct iscsi_session *iscsi ); enum iscsi_tx_state next_state; size_t tx_len; int rc; /* Select fragment to transmit */ while ( 1 ) { switch ( iscsi->tx_state ) { case ISCSI_TX_IDLE: /* Stop processing */ return; case ISCSI_TX_BHS: tx = iscsi_tx_bhs; tx_len = sizeof ( iscsi->tx_bhs ); next_state = ISCSI_TX_AHS; break; case ISCSI_TX_AHS: tx = iscsi_tx_nothing; tx_len = 0; next_state = ISCSI_TX_DATA; break; case ISCSI_TX_DATA: tx = iscsi_tx_data; tx_len = ISCSI_DATA_LEN ( common->lengths ); next_state = ISCSI_TX_DATA_PADDING; break; case ISCSI_TX_DATA_PADDING: tx = iscsi_tx_data_padding; tx_len = ISCSI_DATA_PAD_LEN ( common->lengths ); next_state = ISCSI_TX_IDLE; break; default: assert ( 0 ); return; } /* Check for window availability, if needed */ if ( tx_len && ( xfer_window ( &iscsi->socket ) == 0 ) ) { /* Cannot transmit at this point; stop processing */ return; } /* Transmit data */ if ( ( rc = tx ( iscsi ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not transmit: %s\n", iscsi, strerror ( rc ) ); return; } /* Move to next state */ iscsi->tx_state = next_state; if ( next_state == ISCSI_TX_IDLE ) iscsi_tx_done ( iscsi ); } } /** * Receive basic header segment of an iSCSI PDU * * @v iscsi iSCSI session * @v data Received data * @v len Length of received data * @v remaining Data remaining after this data * @ret rc Return status code * * This fills in iscsi::rx_bhs with the data from the BHS portion of * the received PDU. */ static int iscsi_rx_bhs ( struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining __unused ) { memcpy ( &iscsi->rx_bhs.bytes[iscsi->rx_offset], data, len ); if ( ( iscsi->rx_offset + len ) >= sizeof ( iscsi->rx_bhs ) ) { DBGC2 ( iscsi, "iSCSI %p received PDU opcode %#x len %#x\n", iscsi, iscsi->rx_bhs.common.opcode, ISCSI_DATA_LEN ( iscsi->rx_bhs.common.lengths ) ); } return 0; } /** * Discard portion of an iSCSI PDU. * * @v iscsi iSCSI session * @v data Received data * @v len Length of received data * @v remaining Data remaining after this data * @ret rc Return status code * * This discards data from a portion of a received PDU. */ static int iscsi_rx_discard ( struct iscsi_session *iscsi __unused, const void *data __unused, size_t len __unused, size_t remaining __unused ) { /* Do nothing */ return 0; } /** * Receive data segment of an iSCSI PDU * * @v iscsi iSCSI session * @v data Received data * @v len Length of received data * @v remaining Data remaining after this data * @ret rc Return status code * * Handle processing of part of a PDU data segment. iscsi::rx_bhs * will be valid when this is called. */ static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining ) { struct iscsi_bhs_common_response *response = &iscsi->rx_bhs.common_response; /* Update cmdsn and statsn */ iscsi->cmdsn = ntohl ( response->expcmdsn ); iscsi->statsn = ntohl ( response->statsn ); switch ( response->opcode & ISCSI_OPCODE_MASK ) { case ISCSI_OPCODE_LOGIN_RESPONSE: return iscsi_rx_login_response ( iscsi, data, len, remaining ); case ISCSI_OPCODE_SCSI_RESPONSE: return iscsi_rx_scsi_response ( iscsi, data, len, remaining ); case ISCSI_OPCODE_DATA_IN: return iscsi_rx_data_in ( iscsi, data, len, remaining ); case ISCSI_OPCODE_R2T: return iscsi_rx_r2t ( iscsi, data, len, remaining ); default: if ( remaining ) return 0; DBGC ( iscsi, "iSCSI %p unknown opcode %02x\n", iscsi, response->opcode ); return -ENOTSUP; } } /** * Receive new data * * @v socket Transport layer interface * @v data Received data * @v len Length of received data * @ret rc Return status code * * This handles received PDUs. The receive strategy is to fill in * iscsi::rx_bhs with the contents of the BHS portion of the PDU, * throw away any AHS portion, and then process each part of the data * portion as it arrives. The data processing routine therefore * always has a full copy of the BHS available, even for portions of * the data in different packets to the BHS. */ static int iscsi_socket_deliver_raw ( struct xfer_interface *socket, const void *data, size_t len ) { struct iscsi_session *iscsi = container_of ( socket, struct iscsi_session, socket ); struct iscsi_bhs_common *common = &iscsi->rx_bhs.common; int ( * rx ) ( struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining ); enum iscsi_rx_state next_state; size_t frag_len; size_t remaining; int rc; while ( 1 ) { switch ( iscsi->rx_state ) { case ISCSI_RX_BHS: rx = iscsi_rx_bhs; iscsi->rx_len = sizeof ( iscsi->rx_bhs ); next_state = ISCSI_RX_AHS; break; case ISCSI_RX_AHS: rx = iscsi_rx_discard; iscsi->rx_len = 4 * ISCSI_AHS_LEN ( common->lengths ); next_state = ISCSI_RX_DATA; break; case ISCSI_RX_DATA: rx = iscsi_rx_data; iscsi->rx_len = ISCSI_DATA_LEN ( common->lengths ); next_state = ISCSI_RX_DATA_PADDING; break; case ISCSI_RX_DATA_PADDING: rx = iscsi_rx_discard; iscsi->rx_len = ISCSI_DATA_PAD_LEN ( common->lengths ); next_state = ISCSI_RX_BHS; break; default: assert ( 0 ); return -EINVAL; } frag_len = iscsi->rx_len - iscsi->rx_offset; if ( frag_len > len ) frag_len = len; remaining = iscsi->rx_len - iscsi->rx_offset - frag_len; if ( ( rc = rx ( iscsi, data, frag_len, remaining ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not process received " "data: %s\n", iscsi, strerror ( rc ) ); iscsi_close_connection ( iscsi, rc ); iscsi_scsi_done ( iscsi, rc ); return rc; } iscsi->rx_offset += frag_len; data += frag_len; len -= frag_len; /* If all the data for this state has not yet been * received, stay in this state for now. */ if ( iscsi->rx_offset != iscsi->rx_len ) return 0; iscsi->rx_state = next_state; iscsi->rx_offset = 0; } return 0; } /** * Handle stream connection closure * * @v socket Transport layer interface * @v rc Reason for close * */ static void iscsi_socket_close ( struct xfer_interface *socket, int rc ) { struct iscsi_session *iscsi = container_of ( socket, struct iscsi_session, socket ); /* Even a graceful close counts as an error for iSCSI */ if ( ! rc ) rc = -ECONNRESET; /* Close session cleanly */ iscsi_close_connection ( iscsi, rc ); /* Retry connection if within the retry limit, otherwise fail */ if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) { DBGC ( iscsi, "iSCSI %p retrying connection (retry #%d)\n", iscsi, iscsi->retry_count ); if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not reconnect: %s\n", iscsi, strerror ( rc ) ); iscsi_scsi_done ( iscsi, rc ); } } else { DBGC ( iscsi, "iSCSI %p retry count exceeded\n", iscsi ); iscsi->instant_rc = rc; iscsi_scsi_done ( iscsi, rc ); } } /** * Handle redirection event * * @v socket Transport layer interface * @v type Location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ static int iscsi_vredirect ( struct xfer_interface *socket, int type, va_list args ) { struct iscsi_session *iscsi = container_of ( socket, struct iscsi_session, socket ); va_list tmp; struct sockaddr *peer; /* Intercept redirects to a LOCATION_SOCKET and record the IP * address for the iBFT. This is a bit of a hack, but avoids * inventing an ioctl()-style call to retrieve the socket * address from a data-xfer interface. */ if ( type == LOCATION_SOCKET ) { va_copy ( tmp, args ); ( void ) va_arg ( tmp, int ); /* Discard "semantics" */ peer = va_arg ( tmp, struct sockaddr * ); memcpy ( &iscsi->target_sockaddr, peer, sizeof ( iscsi->target_sockaddr ) ); va_end ( tmp ); } return xfer_vreopen ( socket, type, args ); } /** iSCSI socket operations */ static struct xfer_interface_operations iscsi_socket_operations = { .close = iscsi_socket_close, .vredirect = iscsi_vredirect, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, .deliver_raw = iscsi_socket_deliver_raw, }; /**************************************************************************** * * iSCSI command issuing * */ /** * Issue SCSI command * * @v scsi SCSI device * @v command SCSI command * @ret rc Return status code */ static int iscsi_command ( struct scsi_device *scsi, struct scsi_command *command ) { struct iscsi_session *iscsi = container_of ( scsi->backend, struct iscsi_session, refcnt ); int rc; /* Abort immediately if we have a recorded permanent failure */ if ( iscsi->instant_rc ) return iscsi->instant_rc; /* Record SCSI command */ iscsi->command = command; /* Issue command or open connection as appropriate */ if ( iscsi->status ) { iscsi_start_command ( iscsi ); } else { if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) { iscsi->command = NULL; return rc; } } return 0; } /** * Shut down iSCSI interface * * @v scsi SCSI device */ void iscsi_detach ( struct scsi_device *scsi ) { struct iscsi_session *iscsi = container_of ( scsi->backend, struct iscsi_session, refcnt ); xfer_nullify ( &iscsi->socket ); iscsi_close_connection ( iscsi, 0 ); process_del ( &iscsi->process ); scsi->command = scsi_detached_command; ref_put ( scsi->backend ); scsi->backend = NULL; } /**************************************************************************** * * Instantiator * */ /** iSCSI root path components (as per RFC4173) */ enum iscsi_root_path_component { RP_LITERAL = 0, RP_SERVERNAME, RP_PROTOCOL, RP_PORT, RP_LUN, RP_TARGETNAME, NUM_RP_COMPONENTS }; /** * Parse iSCSI root path * * @v iscsi iSCSI session * @v root_path iSCSI root path (as per RFC4173) * @ret rc Return status code */ static int iscsi_parse_root_path ( struct iscsi_session *iscsi, const char *root_path ) { char rp_copy[ strlen ( root_path ) + 1 ]; char *rp_comp[NUM_RP_COMPONENTS]; char *rp = rp_copy; int i = 0; int rc; /* Split root path into component parts */ strcpy ( rp_copy, root_path ); while ( 1 ) { rp_comp[i++] = rp; if ( i == NUM_RP_COMPONENTS ) break; for ( ; *rp != ':' ; rp++ ) { if ( ! *rp ) { DBGC ( iscsi, "iSCSI %p root path \"%s\" " "too short\n", iscsi, root_path ); return -EINVAL; } } *(rp++) = '\0'; } /* Use root path components to configure iSCSI session */ iscsi->target_address = strdup ( rp_comp[RP_SERVERNAME] ); if ( ! iscsi->target_address ) return -ENOMEM; iscsi->target_port = strtoul ( rp_comp[RP_PORT], NULL, 10 ); if ( ! iscsi->target_port ) iscsi->target_port = ISCSI_PORT; if ( ( rc = scsi_parse_lun ( rp_comp[RP_LUN], &iscsi->lun ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p invalid LUN \"%s\"\n", iscsi, rp_comp[RP_LUN] ); return rc; } iscsi->target_iqn = strdup ( rp_comp[RP_TARGETNAME] ); if ( ! iscsi->target_iqn ) return -ENOMEM; return 0; } /** * Set iSCSI authentication details * * @v iscsi iSCSI session * @v initiator_username Initiator username, if any * @v initiator_password Initiator password, if any * @v target_username Target username, if any * @v target_password Target password, if any * @ret rc Return status code */ static int iscsi_set_auth ( struct iscsi_session *iscsi, const char *initiator_username, const char *initiator_password, const char *target_username, const char *target_password ) { /* Check for initiator or target credentials */ if ( initiator_username || initiator_password || target_username || target_password ) { /* We must have at least an initiator username+password */ if ( ! ( initiator_username && initiator_password ) ) goto invalid_auth; /* Store initiator credentials */ iscsi->initiator_username = strdup ( initiator_username ); if ( ! iscsi->initiator_username ) return -ENOMEM; iscsi->initiator_password = strdup ( initiator_password ); if ( ! iscsi->initiator_password ) return -ENOMEM; /* Check for target credentials */ if ( target_username || target_password ) { /* We must have target username+password */ if ( ! ( target_username && target_password ) ) goto invalid_auth; /* Store target credentials */ iscsi->target_username = strdup ( target_username ); if ( ! iscsi->target_username ) return -ENOMEM; iscsi->target_password = strdup ( target_password ); if ( ! iscsi->target_password ) return -ENOMEM; } } return 0; invalid_auth: DBGC ( iscsi, "iSCSI %p invalid credentials: initiator " "%sname,%spw, target %sname,%spw\n", iscsi, ( initiator_username ? "" : "no " ), ( initiator_password ? "" : "no " ), ( target_username ? "" : "no " ), ( target_password ? "" : "no " ) ); return -EINVAL; } /** * Attach iSCSI interface * * @v scsi SCSI device * @v root_path iSCSI root path (as per RFC4173) * @ret rc Return status code */ int iscsi_attach ( struct scsi_device *scsi, const char *root_path ) { struct iscsi_session *iscsi; int rc; /* Allocate and initialise structure */ iscsi = zalloc ( sizeof ( *iscsi ) ); if ( ! iscsi ) return -ENOMEM; iscsi->refcnt.free = iscsi_free; xfer_init ( &iscsi->socket, &iscsi_socket_operations, &iscsi->refcnt ); process_init ( &iscsi->process, iscsi_tx_step, &iscsi->refcnt ); /* Parse root path */ if ( ( rc = iscsi_parse_root_path ( iscsi, root_path ) ) != 0 ) goto err; /* Set fields not specified by root path */ if ( ( rc = iscsi_set_auth ( iscsi, iscsi_initiator_username, iscsi_initiator_password, iscsi_target_username, iscsi_target_password ) ) != 0 ) goto err; /* Sanity checks */ if ( ! iscsi->target_address ) { DBGC ( iscsi, "iSCSI %p does not yet support discovery\n", iscsi ); rc = -ENOTSUP; goto err; } if ( ! iscsi->target_iqn ) { DBGC ( iscsi, "iSCSI %p no target address supplied in %s\n", iscsi, root_path ); rc = -EINVAL; goto err; } /* Attach parent interface, mortalise self, and return */ scsi->backend = ref_get ( &iscsi->refcnt ); scsi->command = iscsi_command; ref_put ( &iscsi->refcnt ); return 0; err: ref_put ( &iscsi->refcnt ); return rc; } /**************************************************************************** * * Settings * */ /** iSCSI initiator IQN setting */ struct setting initiator_iqn_setting __setting = { .name = "initiator-iqn", .description = "iSCSI initiator name", .tag = DHCP_ISCSI_INITIATOR_IQN, .type = &setting_type_string, }; /** iSCSI reverse username setting */ struct setting reverse_username_setting __setting = { .name = "reverse-username", .description = "Reverse user name", .tag = DHCP_EB_REVERSE_USERNAME, .type = &setting_type_string, }; /** iSCSI reverse password setting */ struct setting reverse_password_setting __setting = { .name = "reverse-password", .description = "Reverse password", .tag = DHCP_EB_REVERSE_PASSWORD, .type = &setting_type_string, }; /** An iSCSI string setting */ struct iscsi_string_setting { /** Setting */ struct setting *setting; /** String to update */ char **string; /** String prefix */ const char *prefix; }; /** iSCSI string settings */ static struct iscsi_string_setting iscsi_string_settings[] = { { .setting = &initiator_iqn_setting, .string = &iscsi_explicit_initiator_iqn, .prefix = "", }, { .setting = &username_setting, .string = &iscsi_initiator_username, .prefix = "", }, { .setting = &password_setting, .string = &iscsi_initiator_password, .prefix = "", }, { .setting = &reverse_username_setting, .string = &iscsi_target_username, .prefix = "", }, { .setting = &reverse_password_setting, .string = &iscsi_target_password, .prefix = "", }, { .setting = &hostname_setting, .string = &iscsi_default_initiator_iqn, .prefix = "iqn.2000-01.org.etherboot:", }, }; /** * Apply iSCSI setting * * @v setting iSCSI string setting * @ret rc Return status code */ static int apply_iscsi_string_setting ( struct iscsi_string_setting *setting ){ size_t prefix_len; int setting_len; size_t len; int check_len; char *p; /* Free old string */ free ( *setting->string ); *setting->string = NULL; /* Allocate new string */ prefix_len = strlen ( setting->prefix ); setting_len = fetch_setting_len ( NULL, setting->setting ); if ( setting_len < 0 ) { /* Missing settings are not errors; leave strings as NULL */ return 0; } len = ( prefix_len + setting_len + 1 ); p = *setting->string = malloc ( len ); if ( ! p ) return -ENOMEM; /* Fill new string */ strcpy ( p, setting->prefix ); check_len = fetch_string_setting ( NULL, setting->setting, ( p + prefix_len ), ( len - prefix_len ) ); assert ( check_len == setting_len ); return 0; } /** * Apply iSCSI settings * * @ret rc Return status code */ static int apply_iscsi_settings ( void ) { struct iscsi_string_setting *setting; unsigned int i; int rc; for ( i = 0 ; i < ( sizeof ( iscsi_string_settings ) / sizeof ( iscsi_string_settings[0] ) ) ; i++ ) { setting = &iscsi_string_settings[i]; if ( ( rc = apply_iscsi_string_setting ( setting ) ) != 0 ) { DBG ( "iSCSI could not apply setting %s\n", setting->setting->name ); return rc; } } return 0; } /** iSCSI settings applicator */ struct settings_applicator iscsi_settings_applicator __settings_applicator = { .apply = apply_iscsi_settings, }; /**************************************************************************** * * Initiator name * */ /** * Get iSCSI initiator IQN * * @v iscsi iSCSI session * @ret rc Return status code */ const char * iscsi_initiator_iqn ( void ) { if ( iscsi_explicit_initiator_iqn ) return iscsi_explicit_initiator_iqn; if ( iscsi_default_initiator_iqn ) return iscsi_default_initiator_iqn; return "iqn.2000-09.org.etherboot:UNKNOWN"; } debian/grub-extras/disabled/gpxe/src/net/tcp/http.c0000664000000000000000000003472012524662415017450 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); /** * @file * * Hyper Text Transfer Protocol (HTTP) * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include FEATURE ( FEATURE_PROTOCOL, "HTTP", DHCP_EB_FEATURE_HTTP, 1 ); /** HTTP receive state */ enum http_rx_state { HTTP_RX_RESPONSE = 0, HTTP_RX_HEADER, HTTP_RX_DATA, HTTP_RX_DEAD, }; /** * An HTTP request * */ struct http_request { /** Reference count */ struct refcnt refcnt; /** Data transfer interface */ struct xfer_interface xfer; /** URI being fetched */ struct uri *uri; /** Transport layer interface */ struct xfer_interface socket; /** TX process */ struct process process; /** HTTP response code */ unsigned int response; /** HTTP Content-Length */ size_t content_length; /** Received length */ size_t rx_len; /** RX state */ enum http_rx_state rx_state; /** Line buffer for received header lines */ struct line_buffer linebuf; }; /** * Free HTTP request * * @v refcnt Reference counter */ static void http_free ( struct refcnt *refcnt ) { struct http_request *http = container_of ( refcnt, struct http_request, refcnt ); uri_put ( http->uri ); empty_line_buffer ( &http->linebuf ); free ( http ); }; /** * Mark HTTP request as complete * * @v http HTTP request * @v rc Return status code */ static void http_done ( struct http_request *http, int rc ) { /* Prevent further processing of any current packet */ http->rx_state = HTTP_RX_DEAD; /* If we had a Content-Length, and the received content length * isn't correct, flag an error */ if ( http->content_length && ( http->content_length != http->rx_len ) ) { DBGC ( http, "HTTP %p incorrect length %zd, should be %zd\n", http, http->rx_len, http->content_length ); rc = -EIO; } /* Remove process */ process_del ( &http->process ); /* Close all data transfer interfaces */ xfer_nullify ( &http->socket ); xfer_close ( &http->socket, rc ); xfer_nullify ( &http->xfer ); xfer_close ( &http->xfer, rc ); } /** * Convert HTTP response code to return status code * * @v response HTTP response code * @ret rc Return status code */ static int http_response_to_rc ( unsigned int response ) { switch ( response ) { case 200: case 301: case 302: return 0; case 404: return -ENOENT; case 403: return -EPERM; case 401: return -EACCES; default: return -EIO; } } /** * Handle HTTP response * * @v http HTTP request * @v response HTTP response * @ret rc Return status code */ static int http_rx_response ( struct http_request *http, char *response ) { char *spc; int rc; DBGC ( http, "HTTP %p response \"%s\"\n", http, response ); /* Check response starts with "HTTP/" */ if ( strncmp ( response, "HTTP/", 5 ) != 0 ) return -EIO; /* Locate and check response code */ spc = strchr ( response, ' ' ); if ( ! spc ) return -EIO; http->response = strtoul ( spc, NULL, 10 ); if ( ( rc = http_response_to_rc ( http->response ) ) != 0 ) return rc; /* Move to received headers */ http->rx_state = HTTP_RX_HEADER; return 0; } /** * Handle HTTP Location header * * @v http HTTP request * @v value HTTP header value * @ret rc Return status code */ static int http_rx_location ( struct http_request *http, const char *value ) { int rc; /* Redirect to new location */ DBGC ( http, "HTTP %p redirecting to %s\n", http, value ); if ( ( rc = xfer_redirect ( &http->xfer, LOCATION_URI_STRING, value ) ) != 0 ) { DBGC ( http, "HTTP %p could not redirect: %s\n", http, strerror ( rc ) ); return rc; } return 0; } /** * Handle HTTP Content-Length header * * @v http HTTP request * @v value HTTP header value * @ret rc Return status code */ static int http_rx_content_length ( struct http_request *http, const char *value ) { char *endp; http->content_length = strtoul ( value, &endp, 10 ); if ( *endp != '\0' ) { DBGC ( http, "HTTP %p invalid Content-Length \"%s\"\n", http, value ); return -EIO; } /* Use seek() to notify recipient of filesize */ xfer_seek ( &http->xfer, http->content_length, SEEK_SET ); xfer_seek ( &http->xfer, 0, SEEK_SET ); return 0; } /** An HTTP header handler */ struct http_header_handler { /** Name (e.g. "Content-Length") */ const char *header; /** Handle received header * * @v http HTTP request * @v value HTTP header value * @ret rc Return status code * * If an error is returned, the download will be aborted. */ int ( * rx ) ( struct http_request *http, const char *value ); }; /** List of HTTP header handlers */ static struct http_header_handler http_header_handlers[] = { { .header = "Location", .rx = http_rx_location, }, { .header = "Content-Length", .rx = http_rx_content_length, }, { NULL, NULL } }; /** * Handle HTTP header * * @v http HTTP request * @v header HTTP header * @ret rc Return status code */ static int http_rx_header ( struct http_request *http, char *header ) { struct http_header_handler *handler; char *separator; char *value; int rc; /* An empty header line marks the transition to the data phase */ if ( ! header[0] ) { DBGC ( http, "HTTP %p start of data\n", http ); empty_line_buffer ( &http->linebuf ); http->rx_state = HTTP_RX_DATA; return 0; } DBGC ( http, "HTTP %p header \"%s\"\n", http, header ); /* Split header at the ": " */ separator = strstr ( header, ": " ); if ( ! separator ) { DBGC ( http, "HTTP %p malformed header\n", http ); return -EIO; } *separator = '\0'; value = ( separator + 2 ); /* Hand off to header handler, if one exists */ for ( handler = http_header_handlers ; handler->header ; handler++ ) { if ( strcasecmp ( header, handler->header ) == 0 ) { if ( ( rc = handler->rx ( http, value ) ) != 0 ) return rc; break; } } return 0; } /** An HTTP line-based data handler */ struct http_line_handler { /** Handle line * * @v http HTTP request * @v line Line to handle * @ret rc Return status code */ int ( * rx ) ( struct http_request *http, char *line ); }; /** List of HTTP line-based data handlers */ static struct http_line_handler http_line_handlers[] = { [HTTP_RX_RESPONSE] = { .rx = http_rx_response }, [HTTP_RX_HEADER] = { .rx = http_rx_header }, }; /** * Handle new data arriving via HTTP connection in the data phase * * @v http HTTP request * @v iobuf I/O buffer * @ret rc Return status code */ static int http_rx_data ( struct http_request *http, struct io_buffer *iobuf ) { int rc; /* Update received length */ http->rx_len += iob_len ( iobuf ); /* Hand off data buffer */ if ( ( rc = xfer_deliver_iob ( &http->xfer, iobuf ) ) != 0 ) return rc; /* If we have reached the content-length, stop now */ if ( http->content_length && ( http->rx_len >= http->content_length ) ) { http_done ( http, 0 ); } return 0; } /** * Handle new data arriving via HTTP connection * * @v socket Transport layer interface * @v iobuf I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ static int http_socket_deliver_iob ( struct xfer_interface *socket, struct io_buffer *iobuf, struct xfer_metadata *meta __unused ) { struct http_request *http = container_of ( socket, struct http_request, socket ); struct http_line_handler *lh; char *line; ssize_t len; int rc = 0; while ( iob_len ( iobuf ) ) { switch ( http->rx_state ) { case HTTP_RX_DEAD: /* Do no further processing */ goto done; case HTTP_RX_DATA: /* Once we're into the data phase, just fill * the data buffer */ rc = http_rx_data ( http, iob_disown ( iobuf ) ); goto done; case HTTP_RX_RESPONSE: case HTTP_RX_HEADER: /* In the other phases, buffer and process a * line at a time */ len = line_buffer ( &http->linebuf, iobuf->data, iob_len ( iobuf ) ); if ( len < 0 ) { rc = len; DBGC ( http, "HTTP %p could not buffer line: " "%s\n", http, strerror ( rc ) ); goto done; } iob_pull ( iobuf, len ); line = buffered_line ( &http->linebuf ); if ( line ) { lh = &http_line_handlers[http->rx_state]; if ( ( rc = lh->rx ( http, line ) ) != 0 ) goto done; } break; default: assert ( 0 ); break; } } done: if ( rc ) http_done ( http, rc ); free_iob ( iobuf ); return rc; } /** * HTTP process * * @v process Process */ static void http_step ( struct process *process ) { struct http_request *http = container_of ( process, struct http_request, process ); const char *path = http->uri->path; const char *host = http->uri->host; const char *query = http->uri->query; const char *user = http->uri->user; const char *password = ( http->uri->password ? http->uri->password : "" ); size_t user_pw_len = ( user ? ( strlen ( user ) + 1 /* ":" */ + strlen ( password ) ) : 0 ); size_t user_pw_base64_len = base64_encoded_len ( user_pw_len ); char user_pw[ user_pw_len + 1 /* NUL */ ]; char user_pw_base64[ user_pw_base64_len + 1 /* NUL */ ]; int rc; if ( xfer_window ( &http->socket ) ) { /* We want to execute only once */ process_del ( &http->process ); /* Construct authorisation, if applicable */ if ( user ) { char *buf = user_pw; ssize_t remaining = sizeof ( user_pw ); size_t len; /* URI-decode the username and password */ len = uri_decode ( user, buf, remaining ); buf += len; remaining -= len; *(remaining--, buf++) = ':'; len = uri_decode ( password, buf, remaining ); buf += len; remaining -= len; assert ( remaining >= 0 ); /* Base64-encode the "user:password" string */ base64_encode ( user_pw, user_pw_base64 ); } /* Send GET request */ if ( ( rc = xfer_printf ( &http->socket, "GET %s%s%s HTTP/1.0\r\n" "User-Agent: gPXE/" VERSION "\r\n" "%s%s%s" "Host: %s\r\n" "\r\n", ( path ? path : "/" ), ( query ? "?" : "" ), ( query ? query : "" ), ( user ? "Authorization: Basic " : "" ), ( user ? user_pw_base64 : "" ), ( user ? "\r\n" : "" ), host ) ) != 0 ) { http_done ( http, rc ); } } } /** * HTTP connection closed by network stack * * @v socket Transport layer interface * @v rc Reason for close */ static void http_socket_close ( struct xfer_interface *socket, int rc ) { struct http_request *http = container_of ( socket, struct http_request, socket ); DBGC ( http, "HTTP %p socket closed: %s\n", http, strerror ( rc ) ); http_done ( http, rc ); } /** HTTP socket operations */ static struct xfer_interface_operations http_socket_operations = { .close = http_socket_close, .vredirect = xfer_vreopen, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = http_socket_deliver_iob, .deliver_raw = xfer_deliver_as_iob, }; /** * Close HTTP data transfer interface * * @v xfer Data transfer interface * @v rc Reason for close */ static void http_xfer_close ( struct xfer_interface *xfer, int rc ) { struct http_request *http = container_of ( xfer, struct http_request, xfer ); DBGC ( http, "HTTP %p interface closed: %s\n", http, strerror ( rc ) ); http_done ( http, rc ); } /** HTTP data transfer interface operations */ static struct xfer_interface_operations http_xfer_operations = { .close = http_xfer_close, .vredirect = ignore_xfer_vredirect, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, .deliver_raw = ignore_xfer_deliver_raw, }; /** * Initiate an HTTP connection, with optional filter * * @v xfer Data transfer interface * @v uri Uniform Resource Identifier * @v default_port Default port number * @v filter Filter to apply to socket, or NULL * @ret rc Return status code */ int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, unsigned int default_port, int ( * filter ) ( struct xfer_interface *xfer, struct xfer_interface **next ) ) { struct http_request *http; struct sockaddr_tcpip server; struct xfer_interface *socket; int rc; /* Sanity checks */ if ( ! uri->host ) return -EINVAL; /* Allocate and populate HTTP structure */ http = zalloc ( sizeof ( *http ) ); if ( ! http ) return -ENOMEM; http->refcnt.free = http_free; xfer_init ( &http->xfer, &http_xfer_operations, &http->refcnt ); http->uri = uri_get ( uri ); xfer_init ( &http->socket, &http_socket_operations, &http->refcnt ); process_init ( &http->process, http_step, &http->refcnt ); /* Open socket */ memset ( &server, 0, sizeof ( server ) ); server.st_port = htons ( uri_port ( http->uri, default_port ) ); socket = &http->socket; if ( filter ) { if ( ( rc = filter ( socket, &socket ) ) != 0 ) goto err; } if ( ( rc = xfer_open_named_socket ( socket, SOCK_STREAM, ( struct sockaddr * ) &server, uri->host, NULL ) ) != 0 ) goto err; /* Attach to parent interface, mortalise self, and return */ xfer_plug_plug ( &http->xfer, xfer ); ref_put ( &http->refcnt ); return 0; err: DBGC ( http, "HTTP %p could not create request: %s\n", http, strerror ( rc ) ); http_done ( http, rc ); ref_put ( &http->refcnt ); return rc; } /** * Initiate an HTTP connection * * @v xfer Data transfer interface * @v uri Uniform Resource Identifier * @ret rc Return status code */ static int http_open ( struct xfer_interface *xfer, struct uri *uri ) { return http_open_filter ( xfer, uri, HTTP_PORT, NULL ); } /** HTTP URI opener */ struct uri_opener http_uri_opener __uri_opener = { .scheme = "http", .open = http_open, }; debian/grub-extras/disabled/gpxe/src/net/fakedhcp.c0000664000000000000000000001300412524662415017440 0ustar /* * Copyright (C) 2008 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include /** @file * * Fake DHCP packets * */ /** * Copy settings to DHCP packet * * @v dest Destination DHCP packet * @v source Source settings block * @v encapsulator Encapsulating setting tag number, or zero * @ret rc Return status code */ static int copy_encap_settings ( struct dhcp_packet *dest, struct settings *source, unsigned int encapsulator ) { struct setting setting = { .name = "" }; unsigned int subtag; unsigned int tag; int len; int check_len; int rc; for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) { tag = DHCP_ENCAP_OPT ( encapsulator, subtag ); switch ( tag ) { case DHCP_EB_ENCAP: case DHCP_VENDOR_ENCAP: /* Process encapsulated settings */ if ( ( rc = copy_encap_settings ( dest, source, tag ) ) != 0 ) return rc; break; default: /* Copy setting, if present */ setting.tag = tag; len = fetch_setting_len ( source, &setting ); if ( len < 0 ) break; { char buf[len]; check_len = fetch_setting ( source, &setting, buf, sizeof (buf)); assert ( check_len == len ); if ( ( rc = dhcppkt_store ( dest, tag, buf, sizeof(buf) )) !=0) return rc; } break; } } return 0; } /** * Copy settings to DHCP packet * * @v dest Destination DHCP packet * @v source Source settings block * @ret rc Return status code */ static int copy_settings ( struct dhcp_packet *dest, struct settings *source ) { return copy_encap_settings ( dest, source, 0 ); } /** * Create fake DHCPDISCOVER packet * * @v netdev Network device * @v data Buffer for DHCP packet * @v max_len Size of DHCP packet buffer * @ret rc Return status code * * Used by external code. */ int create_fakedhcpdiscover ( struct net_device *netdev, void *data, size_t max_len ) { struct dhcp_packet dhcppkt; struct in_addr ciaddr = { 0 }; int rc; if ( ( rc = dhcp_create_request ( &dhcppkt, netdev, DHCPDISCOVER, ciaddr, data, max_len ) ) != 0 ) { DBG ( "Could not create DHCPDISCOVER: %s\n", strerror ( rc ) ); return rc; } return 0; } /** * Create fake DHCPACK packet * * @v netdev Network device * @v data Buffer for DHCP packet * @v max_len Size of DHCP packet buffer * @ret rc Return status code * * Used by external code. */ int create_fakedhcpack ( struct net_device *netdev, void *data, size_t max_len ) { struct dhcp_packet dhcppkt; int rc; /* Create base DHCPACK packet */ if ( ( rc = dhcp_create_packet ( &dhcppkt, netdev, DHCPACK, NULL, 0, data, max_len ) ) != 0 ) { DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) ); return rc; } /* Merge in globally-scoped settings, then netdev-specific * settings. Do it in this order so that netdev-specific * settings take precedence regardless of stated priorities. */ if ( ( rc = copy_settings ( &dhcppkt, NULL ) ) != 0 ) { DBG ( "Could not set DHCPACK global settings: %s\n", strerror ( rc ) ); return rc; } if ( ( rc = copy_settings ( &dhcppkt, netdev_settings ( netdev ) ) ) != 0 ) { DBG ( "Could not set DHCPACK netdev settings: %s\n", strerror ( rc ) ); return rc; } return 0; } /** * Create fake PXE Boot Server ACK packet * * @v netdev Network device * @v data Buffer for DHCP packet * @v max_len Size of DHCP packet buffer * @ret rc Return status code * * Used by external code. */ int create_fakepxebsack ( struct net_device *netdev, void *data, size_t max_len ) { struct dhcp_packet dhcppkt; struct settings *proxy_settings; struct settings *pxebs_settings; int rc; /* Identify available settings */ proxy_settings = find_settings ( PROXYDHCP_SETTINGS_NAME ); pxebs_settings = find_settings ( PXEBS_SETTINGS_NAME ); if ( ( ! proxy_settings ) && ( ! pxebs_settings ) ) { /* No PXE boot server; return the regular DHCPACK */ return create_fakedhcpack ( netdev, data, max_len ); } /* Create base DHCPACK packet */ if ( ( rc = dhcp_create_packet ( &dhcppkt, netdev, DHCPACK, NULL, 0, data, max_len ) ) != 0 ) { DBG ( "Could not create PXE BS ACK: %s\n", strerror ( rc ) ); return rc; } /* Merge in ProxyDHCP options */ if ( proxy_settings && ( ( rc = copy_settings ( &dhcppkt, proxy_settings ) ) != 0 ) ) { DBG ( "Could not copy ProxyDHCP settings: %s\n", strerror ( rc ) ); return rc; } /* Merge in BootServerDHCP options, if present */ if ( pxebs_settings && ( ( rc = copy_settings ( &dhcppkt, pxebs_settings ) ) != 0 ) ) { DBG ( "Could not copy PXE BS settings: %s\n", strerror ( rc ) ); return rc; } return 0; } debian/grub-extras/disabled/gpxe/src/net/infiniband/0000775000000000000000000000000012524676037017637 5ustar debian/grub-extras/disabled/gpxe/src/net/infiniband/ib_cmrc.c0000664000000000000000000002751412524662415021405 0ustar /* * Copyright (C) 2009 Fen Systems Ltd . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ FILE_LICENCE ( BSD2 ); #include #include #include #include #include #include #include #include #include /** * @file * * Infiniband Communication-managed Reliable Connections * */ /** CMRC number of send WQEs * * This is a policy decision. */ #define IB_CMRC_NUM_SEND_WQES 4 /** CMRC number of receive WQEs * * This is a policy decision. */ #define IB_CMRC_NUM_RECV_WQES 2 /** CMRC number of completion queue entries * * This is a policy decision */ #define IB_CMRC_NUM_CQES 8 /** An Infiniband Communication-Managed Reliable Connection */ struct ib_cmrc_connection { /** Reference count */ struct refcnt refcnt; /** Data transfer interface */ struct xfer_interface xfer; /** Infiniband device */ struct ib_device *ibdev; /** Completion queue */ struct ib_completion_queue *cq; /** Queue pair */ struct ib_queue_pair *qp; /** Connection */ struct ib_connection *conn; /** Destination GID */ struct ib_gid dgid; /** Service ID */ struct ib_gid_half service_id; /** QP is connected */ int connected; /** Shutdown process */ struct process shutdown; }; /** * Shut down CMRC connection gracefully * * @v process Process * * The Infiniband data structures are not reference-counted or * guarded. It is therefore unsafe to shut them down while we may be * in the middle of a callback from the Infiniband stack (e.g. in a * receive completion handler). * * This shutdown process will run some time after the call to * ib_cmrc_close(), after control has returned out of the Infiniband * core, and will shut down the Infiniband interfaces cleanly. * * The shutdown process holds an implicit reference on the CMRC * connection, ensuring that the structure is not freed before the * shutdown process has run. */ static void ib_cmrc_shutdown ( struct process *process ) { struct ib_cmrc_connection *cmrc = container_of ( process, struct ib_cmrc_connection, shutdown ); DBGC ( cmrc, "CMRC %p shutting down\n", cmrc ); /* Shut down Infiniband interface */ ib_destroy_conn ( cmrc->ibdev, cmrc->qp, cmrc->conn ); ib_destroy_qp ( cmrc->ibdev, cmrc->qp ); ib_destroy_cq ( cmrc->ibdev, cmrc->cq ); ib_close ( cmrc->ibdev ); /* Remove process from run queue */ process_del ( &cmrc->shutdown ); /* Drop the remaining reference */ ref_put ( &cmrc->refcnt ); } /** * Close CMRC connection * * @v cmrc Communication-Managed Reliable Connection * @v rc Reason for close */ static void ib_cmrc_close ( struct ib_cmrc_connection *cmrc, int rc ) { /* Close data transfer interface */ xfer_nullify ( &cmrc->xfer ); xfer_close ( &cmrc->xfer, rc ); /* Schedule shutdown process */ process_add ( &cmrc->shutdown ); } /** * Handle change of CMRC connection status * * @v ibdev Infiniband device * @v qp Queue pair * @v conn Connection * @v rc_cm Connection status code * @v private_data Private data, if available * @v private_data_len Length of private data */ static void ib_cmrc_changed ( struct ib_device *ibdev __unused, struct ib_queue_pair *qp, struct ib_connection *conn __unused, int rc_cm, void *private_data, size_t private_data_len ) { struct ib_cmrc_connection *cmrc = ib_qp_get_ownerdata ( qp ); int rc_xfer; /* Record connection status */ if ( rc_cm == 0 ) { DBGC ( cmrc, "CMRC %p connected\n", cmrc ); cmrc->connected = 1; } else { DBGC ( cmrc, "CMRC %p disconnected: %s\n", cmrc, strerror ( rc_cm ) ); cmrc->connected = 0; } /* Pass up any private data */ DBGC2 ( cmrc, "CMRC %p received private data:\n", cmrc ); DBGC2_HDA ( cmrc, 0, private_data, private_data_len ); if ( private_data && ( rc_xfer = xfer_deliver_raw ( &cmrc->xfer, private_data, private_data_len ) ) != 0 ) { DBGC ( cmrc, "CMRC %p could not deliver private data: %s\n", cmrc, strerror ( rc_xfer ) ); ib_cmrc_close ( cmrc, rc_xfer ); return; } /* If we are disconnected, close the upper connection */ if ( rc_cm != 0 ) { ib_cmrc_close ( cmrc, rc_cm ); return; } } /** CMRC connection operations */ static struct ib_connection_operations ib_cmrc_conn_op = { .changed = ib_cmrc_changed, }; /** * Handle CMRC send completion * * @v ibdev Infiniband device * @v qp Queue pair * @v iobuf I/O buffer * @v rc Completion status code */ static void ib_cmrc_complete_send ( struct ib_device *ibdev __unused, struct ib_queue_pair *qp, struct io_buffer *iobuf, int rc ) { struct ib_cmrc_connection *cmrc = ib_qp_get_ownerdata ( qp ); /* Free the completed I/O buffer */ free_iob ( iobuf ); /* Close the connection on any send errors */ if ( rc != 0 ) { DBGC ( cmrc, "CMRC %p send error: %s\n", cmrc, strerror ( rc ) ); ib_cmrc_close ( cmrc, rc ); return; } } /** * Handle CMRC receive completion * * @v ibdev Infiniband device * @v qp Queue pair * @v av Address vector, or NULL * @v iobuf I/O buffer * @v rc Completion status code */ static void ib_cmrc_complete_recv ( struct ib_device *ibdev __unused, struct ib_queue_pair *qp, struct ib_address_vector *av __unused, struct io_buffer *iobuf, int rc ) { struct ib_cmrc_connection *cmrc = ib_qp_get_ownerdata ( qp ); /* Close the connection on any receive errors */ if ( rc != 0 ) { DBGC ( cmrc, "CMRC %p receive error: %s\n", cmrc, strerror ( rc ) ); free_iob ( iobuf ); ib_cmrc_close ( cmrc, rc ); return; } DBGC2 ( cmrc, "CMRC %p received:\n", cmrc ); DBGC2_HDA ( cmrc, 0, iobuf->data, iob_len ( iobuf ) ); /* Pass up data */ if ( ( rc = xfer_deliver_iob ( &cmrc->xfer, iobuf ) ) != 0 ) { DBGC ( cmrc, "CMRC %p could not deliver data: %s\n", cmrc, strerror ( rc ) ); ib_cmrc_close ( cmrc, rc ); return; } } /** Infiniband CMRC completion operations */ static struct ib_completion_queue_operations ib_cmrc_completion_ops = { .complete_send = ib_cmrc_complete_send, .complete_recv = ib_cmrc_complete_recv, }; /** * Send data via CMRC * * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ static int ib_cmrc_xfer_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta __unused ) { struct ib_cmrc_connection *cmrc = container_of ( xfer, struct ib_cmrc_connection, xfer ); int rc; /* If no connection has yet been attempted, send this datagram * as the CM REQ private data. Otherwise, send it via the QP. */ if ( ! cmrc->connected ) { /* Abort if we have already sent a CM connection request */ if ( cmrc->conn ) { DBGC ( cmrc, "CMRC %p attempt to send before " "connection is complete\n", cmrc ); rc = -EIO; goto out; } /* Send via CM connection request */ cmrc->conn = ib_create_conn ( cmrc->ibdev, cmrc->qp, &cmrc->dgid, &cmrc->service_id, iobuf->data, iob_len ( iobuf ), &ib_cmrc_conn_op ); if ( ! cmrc->conn ) { DBGC ( cmrc, "CMRC %p could not connect\n", cmrc ); rc = -ENOMEM; goto out; } } else { /* Send via QP */ if ( ( rc = ib_post_send ( cmrc->ibdev, cmrc->qp, NULL, iob_disown ( iobuf ) ) ) != 0 ) { DBGC ( cmrc, "CMRC %p could not send: %s\n", cmrc, strerror ( rc ) ); goto out; } } return 0; out: /* Free the I/O buffer if necessary */ free_iob ( iobuf ); /* Close the connection on any errors */ if ( rc != 0 ) ib_cmrc_close ( cmrc, rc ); return rc; } /** * Check CMRC flow control window * * @v xfer Data transfer interface * @ret len Length of window */ static size_t ib_cmrc_xfer_window ( struct xfer_interface *xfer ) { struct ib_cmrc_connection *cmrc = container_of ( xfer, struct ib_cmrc_connection, xfer ); /* We indicate a window only when we are successfully * connected. */ return ( cmrc->connected ? IB_MAX_PAYLOAD_SIZE : 0 ); } /** * Close CMRC data-transfer interface * * @v xfer Data transfer interface * @v rc Reason for close */ static void ib_cmrc_xfer_close ( struct xfer_interface *xfer, int rc ) { struct ib_cmrc_connection *cmrc = container_of ( xfer, struct ib_cmrc_connection, xfer ); DBGC ( cmrc, "CMRC %p closed: %s\n", cmrc, strerror ( rc ) ); ib_cmrc_close ( cmrc, rc ); } /** CMRC data transfer interface operations */ static struct xfer_interface_operations ib_cmrc_xfer_operations = { .close = ib_cmrc_xfer_close, .vredirect = ignore_xfer_vredirect, .window = ib_cmrc_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = ib_cmrc_xfer_deliver_iob, .deliver_raw = xfer_deliver_as_iob, }; /** * Open CMRC connection * * @v xfer Data transfer interface * @v ibdev Infiniband device * @v dgid Destination GID * @v service_id Service ID * @ret rc Returns status code */ int ib_cmrc_open ( struct xfer_interface *xfer, struct ib_device *ibdev, struct ib_gid *dgid, struct ib_gid_half *service_id ) { struct ib_cmrc_connection *cmrc; int rc; /* Allocate and initialise structure */ cmrc = zalloc ( sizeof ( *cmrc ) ); if ( ! cmrc ) { rc = -ENOMEM; goto err_alloc; } xfer_init ( &cmrc->xfer, &ib_cmrc_xfer_operations, &cmrc->refcnt ); cmrc->ibdev = ibdev; memcpy ( &cmrc->dgid, dgid, sizeof ( cmrc->dgid ) ); memcpy ( &cmrc->service_id, service_id, sizeof ( cmrc->service_id ) ); process_init_stopped ( &cmrc->shutdown, ib_cmrc_shutdown, &cmrc->refcnt ); /* Open Infiniband device */ if ( ( rc = ib_open ( ibdev ) ) != 0 ) { DBGC ( cmrc, "CMRC %p could not open device: %s\n", cmrc, strerror ( rc ) ); goto err_open; } /* Create completion queue */ cmrc->cq = ib_create_cq ( ibdev, IB_CMRC_NUM_CQES, &ib_cmrc_completion_ops ); if ( ! cmrc->cq ) { DBGC ( cmrc, "CMRC %p could not create completion queue\n", cmrc ); rc = -ENOMEM; goto err_create_cq; } /* Create queue pair */ cmrc->qp = ib_create_qp ( ibdev, IB_QPT_RC, IB_CMRC_NUM_SEND_WQES, cmrc->cq, IB_CMRC_NUM_RECV_WQES, cmrc->cq ); if ( ! cmrc->qp ) { DBGC ( cmrc, "CMRC %p could not create queue pair\n", cmrc ); rc = -ENOMEM; goto err_create_qp; } ib_qp_set_ownerdata ( cmrc->qp, cmrc ); DBGC ( cmrc, "CMRC %p using QPN %lx\n", cmrc, cmrc->qp->qpn ); /* Attach to parent interface, transfer reference (implicitly) * to our shutdown process, and return. */ xfer_plug_plug ( &cmrc->xfer, xfer ); return 0; ib_destroy_qp ( ibdev, cmrc->qp ); err_create_qp: ib_destroy_cq ( ibdev, cmrc->cq ); err_create_cq: ib_close ( ibdev ); err_open: ref_put ( &cmrc->refcnt ); err_alloc: return rc; } debian/grub-extras/disabled/gpxe/src/net/infiniband/ib_srp.c0000664000000000000000000002567512524662415021273 0ustar /* * Copyright (C) 2009 Fen Systems Ltd . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ FILE_LICENCE ( BSD2 ); #include #include #include #include #include #include /** * @file * * SCSI RDMA Protocol over Infiniband * */ /* Disambiguate the various possible EINVALs */ #define EINVAL_BYTE_STRING_LEN ( EINVAL | EUNIQ_01 ) #define EINVAL_BYTE_STRING ( EINVAL | EUNIQ_02 ) #define EINVAL_INTEGER ( EINVAL | EUNIQ_03 ) #define EINVAL_RP_TOO_SHORT ( EINVAL | EUNIQ_04 ) /** IB SRP parse flags */ enum ib_srp_parse_flags { IB_SRP_PARSE_REQUIRED = 0x0000, IB_SRP_PARSE_OPTIONAL = 0x8000, IB_SRP_PARSE_FLAG_MASK = 0xf000, }; /** IB SRP root path parameters */ struct ib_srp_root_path { /** SCSI LUN */ struct scsi_lun *lun; /** SRP port IDs */ struct srp_port_ids *port_ids; /** IB SRP parameters */ struct ib_srp_parameters *ib; }; /** * Parse IB SRP root path byte-string value * * @v rp_comp Root path component string * @v default_value Default value to use if component string is empty * @ret value Value */ static int ib_srp_parse_byte_string ( const char *rp_comp, uint8_t *bytes, unsigned int size_flags ) { size_t size = ( size_flags & ~IB_SRP_PARSE_FLAG_MASK ); size_t rp_comp_len = strlen ( rp_comp ); char buf[3]; char *buf_end; /* Allow optional components to be empty */ if ( ( rp_comp_len == 0 ) && ( size_flags & IB_SRP_PARSE_OPTIONAL ) ) return 0; /* Check string length */ if ( rp_comp_len != ( 2 * size ) ) return -EINVAL_BYTE_STRING_LEN; /* Parse byte string */ for ( ; size ; size--, rp_comp += 2, bytes++ ) { memcpy ( buf, rp_comp, 2 ); buf[2] = '\0'; *bytes = strtoul ( buf, &buf_end, 16 ); if ( buf_end != &buf[2] ) return -EINVAL_BYTE_STRING; } return 0; } /** * Parse IB SRP root path integer value * * @v rp_comp Root path component string * @v default_value Default value to use if component string is empty * @ret value Value */ static int ib_srp_parse_integer ( const char *rp_comp, int default_value ) { int value; char *end; value = strtoul ( rp_comp, &end, 16 ); if ( *end ) return -EINVAL_INTEGER; if ( end == rp_comp ) return default_value; return value; } /** * Parse IB SRP root path literal component * * @v rp_comp Root path component string * @v rp IB SRP root path * @ret rc Return status code */ static int ib_srp_parse_literal ( const char *rp_comp __unused, struct ib_srp_root_path *rp __unused ) { /* Ignore */ return 0; } /** * Parse IB SRP root path source GID * * @v rp_comp Root path component string * @v rp IB SRP root path * @ret rc Return status code */ static int ib_srp_parse_sgid ( const char *rp_comp, struct ib_srp_root_path *rp ) { struct ib_device *ibdev; /* Default to the GID of the last opened Infiniband device */ if ( ( ibdev = last_opened_ibdev() ) != NULL ) memcpy ( &rp->ib->sgid, &ibdev->gid, sizeof ( rp->ib->sgid ) ); return ib_srp_parse_byte_string ( rp_comp, rp->ib->sgid.u.bytes, ( sizeof ( rp->ib->sgid ) | IB_SRP_PARSE_OPTIONAL ) ); } /** * Parse IB SRP root path initiator identifier extension * * @v rp_comp Root path component string * @v rp IB SRP root path * @ret rc Return status code */ static int ib_srp_parse_initiator_id_ext ( const char *rp_comp, struct ib_srp_root_path *rp ) { struct ib_srp_initiator_port_id *port_id = ib_srp_initiator_port_id ( rp->port_ids ); return ib_srp_parse_byte_string ( rp_comp, port_id->id_ext.u.bytes, ( sizeof ( port_id->id_ext ) | IB_SRP_PARSE_OPTIONAL ) ); } /** * Parse IB SRP root path initiator HCA GUID * * @v rp_comp Root path component string * @v rp IB SRP root path * @ret rc Return status code */ static int ib_srp_parse_initiator_hca_guid ( const char *rp_comp, struct ib_srp_root_path *rp ) { struct ib_srp_initiator_port_id *port_id = ib_srp_initiator_port_id ( rp->port_ids ); /* Default to the GUID portion of the source GID */ memcpy ( &port_id->hca_guid, &rp->ib->sgid.u.half[1], sizeof ( port_id->hca_guid ) ); return ib_srp_parse_byte_string ( rp_comp, port_id->hca_guid.u.bytes, ( sizeof ( port_id->hca_guid ) | IB_SRP_PARSE_OPTIONAL ) ); } /** * Parse IB SRP root path destination GID * * @v rp_comp Root path component string * @v rp IB SRP root path * @ret rc Return status code */ static int ib_srp_parse_dgid ( const char *rp_comp, struct ib_srp_root_path *rp ) { return ib_srp_parse_byte_string ( rp_comp, rp->ib->dgid.u.bytes, ( sizeof ( rp->ib->dgid ) | IB_SRP_PARSE_REQUIRED ) ); } /** * Parse IB SRP root path partition key * * @v rp_comp Root path component string * @v rp IB SRP root path * @ret rc Return status code */ static int ib_srp_parse_pkey ( const char *rp_comp, struct ib_srp_root_path *rp ) { int pkey; if ( ( pkey = ib_srp_parse_integer ( rp_comp, IB_PKEY_NONE ) ) < 0 ) return pkey; rp->ib->pkey = pkey; return 0; } /** * Parse IB SRP root path service ID * * @v rp_comp Root path component string * @v rp IB SRP root path * @ret rc Return status code */ static int ib_srp_parse_service_id ( const char *rp_comp, struct ib_srp_root_path *rp ) { return ib_srp_parse_byte_string ( rp_comp, rp->ib->service_id.u.bytes, ( sizeof ( rp->ib->service_id ) | IB_SRP_PARSE_REQUIRED ) ); } /** * Parse IB SRP root path LUN * * @v rp_comp Root path component string * @v rp IB SRP root path * @ret rc Return status code */ static int ib_srp_parse_lun ( const char *rp_comp, struct ib_srp_root_path *rp ) { return scsi_parse_lun ( rp_comp, rp->lun ); } /** * Parse IB SRP root path target identifier extension * * @v rp_comp Root path component string * @v rp IB SRP root path * @ret rc Return status code */ static int ib_srp_parse_target_id_ext ( const char *rp_comp, struct ib_srp_root_path *rp ) { struct ib_srp_target_port_id *port_id = ib_srp_target_port_id ( rp->port_ids ); return ib_srp_parse_byte_string ( rp_comp, port_id->id_ext.u.bytes, ( sizeof ( port_id->id_ext ) | IB_SRP_PARSE_REQUIRED ) ); } /** * Parse IB SRP root path target I/O controller GUID * * @v rp_comp Root path component string * @v rp IB SRP root path * @ret rc Return status code */ static int ib_srp_parse_target_ioc_guid ( const char *rp_comp, struct ib_srp_root_path *rp ) { struct ib_srp_target_port_id *port_id = ib_srp_target_port_id ( rp->port_ids ); return ib_srp_parse_byte_string ( rp_comp, port_id->ioc_guid.u.bytes, ( sizeof ( port_id->ioc_guid ) | IB_SRP_PARSE_REQUIRED ) ); } /** IB SRP root path component parser */ struct ib_srp_root_path_parser { /** * Parse IB SRP root path component * * @v rp_comp Root path component string * @v rp IB SRP root path * @ret rc Return status code */ int ( * parse ) ( const char *rp_comp, struct ib_srp_root_path *rp ); }; /** IB SRP root path components */ static struct ib_srp_root_path_parser ib_srp_rp_parser[] = { { ib_srp_parse_literal }, { ib_srp_parse_sgid }, { ib_srp_parse_initiator_id_ext }, { ib_srp_parse_initiator_hca_guid }, { ib_srp_parse_dgid }, { ib_srp_parse_pkey }, { ib_srp_parse_service_id }, { ib_srp_parse_lun }, { ib_srp_parse_target_id_ext }, { ib_srp_parse_target_ioc_guid }, }; /** Number of IB SRP root path components */ #define IB_SRP_NUM_RP_COMPONENTS \ ( sizeof ( ib_srp_rp_parser ) / sizeof ( ib_srp_rp_parser[0] ) ) /** * Parse IB SRP root path * * @v srp SRP device * @v rp_string Root path * @ret rc Return status code */ static int ib_srp_parse_root_path ( struct srp_device *srp, const char *rp_string ) { struct ib_srp_parameters *ib_params = ib_srp_params ( srp ); struct ib_srp_root_path rp = { .lun = &srp->lun, .port_ids = &srp->port_ids, .ib = ib_params, }; char rp_string_copy[ strlen ( rp_string ) + 1 ]; char *rp_comp[IB_SRP_NUM_RP_COMPONENTS]; char *rp_string_tmp = rp_string_copy; unsigned int i = 0; int rc; /* Split root path into component parts */ strcpy ( rp_string_copy, rp_string ); while ( 1 ) { rp_comp[i++] = rp_string_tmp; if ( i == IB_SRP_NUM_RP_COMPONENTS ) break; for ( ; *rp_string_tmp != ':' ; rp_string_tmp++ ) { if ( ! *rp_string_tmp ) { DBGC ( srp, "SRP %p root path \"%s\" too " "short\n", srp, rp_string ); return -EINVAL_RP_TOO_SHORT; } } *(rp_string_tmp++) = '\0'; } /* Parse root path components */ for ( i = 0 ; i < IB_SRP_NUM_RP_COMPONENTS ; i++ ) { if ( ( rc = ib_srp_rp_parser[i].parse ( rp_comp[i], &rp ) ) != 0 ) { DBGC ( srp, "SRP %p could not parse \"%s\" in root " "path \"%s\": %s\n", srp, rp_comp[i], rp_string, strerror ( rc ) ); return rc; } } return 0; } /** * Connect IB SRP session * * @v srp SRP device * @ret rc Return status code */ static int ib_srp_connect ( struct srp_device *srp ) { struct ib_srp_parameters *ib_params = ib_srp_params ( srp ); struct ib_device *ibdev; int rc; /* Identify Infiniband device */ ibdev = find_ibdev ( &ib_params->sgid ); if ( ! ibdev ) { DBGC ( srp, "SRP %p could not identify Infiniband device\n", srp ); return -ENODEV; } /* Configure remaining SRP parameters */ srp->memory_handle = ibdev->rdma_key; /* Open CMRC socket */ if ( ( rc = ib_cmrc_open ( &srp->socket, ibdev, &ib_params->dgid, &ib_params->service_id ) ) != 0 ) { DBGC ( srp, "SRP %p could not open CMRC socket: %s\n", srp, strerror ( rc ) ); return rc; } return 0; } /** IB SRP transport type */ struct srp_transport_type ib_srp_transport = { .priv_len = sizeof ( struct ib_srp_parameters ), .parse_root_path = ib_srp_parse_root_path, .connect = ib_srp_connect, }; debian/grub-extras/disabled/gpxe/src/net/infiniband/ib_mcast.c0000664000000000000000000001535612524662415021571 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include /** @file * * Infiniband multicast groups * */ /** * Generate multicast membership MAD * * @v ibdev Infiniband device * @v gid Multicast GID * @v join Join (rather than leave) group * @v mad MAD to fill in */ static void ib_mcast_mad ( struct ib_device *ibdev, struct ib_gid *gid, int join, union ib_mad *mad ) { struct ib_mad_sa *sa = &mad->sa; /* Construct multicast membership record request */ memset ( sa, 0, sizeof ( *sa ) ); sa->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM; sa->mad_hdr.class_version = IB_SA_CLASS_VERSION; sa->mad_hdr.method = ( join ? IB_MGMT_METHOD_SET : IB_MGMT_METHOD_DELETE ); sa->mad_hdr.attr_id = htons ( IB_SA_ATTR_MC_MEMBER_REC ); sa->sa_hdr.comp_mask[1] = htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID | IB_SA_MCMEMBER_REC_JOIN_STATE ); sa->sa_data.mc_member_record.scope__join_state = 1; memcpy ( &sa->sa_data.mc_member_record.mgid, gid, sizeof ( sa->sa_data.mc_member_record.mgid ) ); memcpy ( &sa->sa_data.mc_member_record.port_gid, &ibdev->gid, sizeof ( sa->sa_data.mc_member_record.port_gid ) ); } /** * Handle multicast membership record join response * * @v ibdev Infiniband device * @v mi Management interface * @v madx Management transaction * @v rc Status code * @v mad Received MAD (or NULL on error) * @v av Source address vector (or NULL on error) */ static void ib_mcast_complete ( struct ib_device *ibdev, struct ib_mad_interface *mi __unused, struct ib_mad_transaction *madx, int rc, union ib_mad *mad, struct ib_address_vector *av __unused ) { struct ib_mc_membership *membership = ib_madx_get_ownerdata ( madx ); struct ib_queue_pair *qp = membership->qp; struct ib_gid *gid = &membership->gid; struct ib_mc_member_record *mc_member_record = &mad->sa.sa_data.mc_member_record; int joined; unsigned long qkey; /* Report failures */ if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) )) rc = -ENOTCONN; if ( rc != 0 ) { DBGC ( ibdev, "IBDEV %p QPN %lx join failed: %s\n", ibdev, qp->qpn, strerror ( rc ) ); goto out; } /* Extract values from MAD */ joined = ( mad->hdr.method == IB_MGMT_METHOD_GET_RESP ); qkey = ntohl ( mc_member_record->qkey ); DBGC ( ibdev, "IBDEV %p QPN %lx %s %08x:%08x:%08x:%08x qkey %lx\n", ibdev, qp->qpn, ( joined ? "joined" : "left" ), ntohl ( gid->u.dwords[0] ), ntohl ( gid->u.dwords[1] ), ntohl ( gid->u.dwords[2] ), ntohl ( gid->u.dwords[3] ), qkey ); /* Set queue key */ qp->qkey = qkey; if ( ( rc = ib_modify_qp ( ibdev, qp ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p QPN %lx could not modify qkey: %s\n", ibdev, qp->qpn, strerror ( rc ) ); goto out; } out: /* Destroy the completed transaction */ ib_destroy_madx ( ibdev, mi, madx ); membership->madx = NULL; /* Hand off to upper completion handler */ membership->complete ( ibdev, qp, membership, rc, mad ); } /** Multicast membership management transaction completion operations */ static struct ib_mad_transaction_operations ib_mcast_op = { .complete = ib_mcast_complete, }; /** * Join multicast group * * @v ibdev Infiniband device * @v qp Queue pair * @v membership Multicast group membership * @v gid Multicast GID to join * @v joined Join completion handler * @ret rc Return status code */ int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_mc_membership *membership, struct ib_gid *gid, void ( * complete ) ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_mc_membership *membership, int rc, union ib_mad *mad ) ) { union ib_mad mad; int rc; DBGC ( ibdev, "IBDEV %p QPN %lx joining %08x:%08x:%08x:%08x\n", ibdev, qp->qpn, ntohl ( gid->u.dwords[0] ), ntohl ( gid->u.dwords[1] ), ntohl ( gid->u.dwords[2] ), ntohl ( gid->u.dwords[3] ) ); /* Initialise structure */ membership->qp = qp; memcpy ( &membership->gid, gid, sizeof ( membership->gid ) ); membership->complete = complete; /* Attach queue pair to multicast GID */ if ( ( rc = ib_mcast_attach ( ibdev, qp, gid ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p QPN %lx could not attach: %s\n", ibdev, qp->qpn, strerror ( rc ) ); goto err_mcast_attach; } /* Initiate multicast membership join */ ib_mcast_mad ( ibdev, gid, 1, &mad ); membership->madx = ib_create_madx ( ibdev, ibdev->gsi, &mad, NULL, &ib_mcast_op ); if ( ! membership->madx ) { DBGC ( ibdev, "IBDEV %p QPN %lx could not create join " "transaction\n", ibdev, qp->qpn ); rc = -ENOMEM; goto err_create_madx; } ib_madx_set_ownerdata ( membership->madx, membership ); return 0; ib_destroy_madx ( ibdev, ibdev->gsi, membership->madx ); err_create_madx: ib_mcast_detach ( ibdev, qp, gid ); err_mcast_attach: return rc; } /** * Leave multicast group * * @v ibdev Infiniband device * @v qp Queue pair * @v membership Multicast group membership */ void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_mc_membership *membership ) { struct ib_gid *gid = &membership->gid; union ib_mad mad; int rc; DBGC ( ibdev, "IBDEV %p QPN %lx leaving %08x:%08x:%08x:%08x\n", ibdev, qp->qpn, ntohl ( gid->u.dwords[0] ), ntohl ( gid->u.dwords[1] ), ntohl ( gid->u.dwords[2] ), ntohl ( gid->u.dwords[3] ) ); /* Detach from multicast GID */ ib_mcast_detach ( ibdev, qp, &membership->gid ); /* Cancel multicast membership join, if applicable */ if ( membership->madx ) { ib_destroy_madx ( ibdev, ibdev->gsi, membership->madx ); membership->madx = NULL; } /* Send a single group leave MAD */ ib_mcast_mad ( ibdev, &membership->gid, 0, &mad ); if ( ( rc = ib_mi_send ( ibdev, ibdev->gsi, &mad, NULL ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p QPN %lx could not send leave request: " "%s\n", ibdev, qp->qpn, strerror ( rc ) ); } } debian/grub-extras/disabled/gpxe/src/net/infiniband/ib_pathrec.c0000664000000000000000000002014312524662415022076 0ustar /* * Copyright (C) 2009 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include /** @file * * Infiniband path lookups * */ /** * Handle path transaction completion * * @v ibdev Infiniband device * @v mi Management interface * @v madx Management transaction * @v rc Status code * @v mad Received MAD (or NULL on error) * @v av Source address vector (or NULL on error) */ static void ib_path_complete ( struct ib_device *ibdev, struct ib_mad_interface *mi, struct ib_mad_transaction *madx, int rc, union ib_mad *mad, struct ib_address_vector *av __unused ) { struct ib_path *path = ib_madx_get_ownerdata ( madx ); struct ib_gid *dgid = &path->av.gid; struct ib_path_record *pathrec = &mad->sa.sa_data.path_record; /* Report failures */ if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) )) rc = -ENETUNREACH; if ( rc != 0 ) { DBGC ( ibdev, "IBDEV %p path lookup for %08x:%08x:%08x:%08x " "failed: %s\n", ibdev, htonl ( dgid->u.dwords[0] ), htonl ( dgid->u.dwords[1] ), htonl ( dgid->u.dwords[2] ), htonl ( dgid->u.dwords[3] ), strerror ( rc ) ); goto out; } /* Extract values from MAD */ path->av.lid = ntohs ( pathrec->dlid ); path->av.sl = ( pathrec->reserved__sl & 0x0f ); path->av.rate = ( pathrec->rate_selector__rate & 0x3f ); DBGC ( ibdev, "IBDEV %p path to %08x:%08x:%08x:%08x is %04x sl %d " "rate %d\n", ibdev, htonl ( dgid->u.dwords[0] ), htonl ( dgid->u.dwords[1] ), htonl ( dgid->u.dwords[2] ), htonl ( dgid->u.dwords[3] ), path->av.lid, path->av.sl, path->av.rate ); out: /* Destroy the completed transaction */ ib_destroy_madx ( ibdev, mi, madx ); path->madx = NULL; /* Hand off to upper completion handler */ path->op->complete ( ibdev, path, rc, &path->av ); } /** Path transaction completion operations */ static struct ib_mad_transaction_operations ib_path_op = { .complete = ib_path_complete, }; /** * Create path * * @v ibdev Infiniband device * @v av Address vector to complete * @v op Path operations * @ret path Path */ struct ib_path * ib_create_path ( struct ib_device *ibdev, struct ib_address_vector *av, struct ib_path_operations *op ) { struct ib_path *path; union ib_mad mad; struct ib_mad_sa *sa = &mad.sa; /* Allocate and initialise structure */ path = zalloc ( sizeof ( *path ) ); if ( ! path ) goto err_alloc_path; path->ibdev = ibdev; memcpy ( &path->av, av, sizeof ( path->av ) ); path->op = op; /* Construct path request */ memset ( sa, 0, sizeof ( *sa ) ); sa->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM; sa->mad_hdr.class_version = IB_SA_CLASS_VERSION; sa->mad_hdr.method = IB_MGMT_METHOD_GET; sa->mad_hdr.attr_id = htons ( IB_SA_ATTR_PATH_REC ); sa->sa_hdr.comp_mask[1] = htonl ( IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID ); memcpy ( &sa->sa_data.path_record.dgid, &path->av.gid, sizeof ( sa->sa_data.path_record.dgid ) ); memcpy ( &sa->sa_data.path_record.sgid, &ibdev->gid, sizeof ( sa->sa_data.path_record.sgid ) ); /* Create management transaction */ path->madx = ib_create_madx ( ibdev, ibdev->gsi, &mad, NULL, &ib_path_op ); if ( ! path->madx ) goto err_create_madx; ib_madx_set_ownerdata ( path->madx, path ); return path; ib_destroy_madx ( ibdev, ibdev->gsi, path->madx ); err_create_madx: free ( path ); err_alloc_path: return NULL; } /** * Destroy path * * @v ibdev Infiniband device * @v path Path */ void ib_destroy_path ( struct ib_device *ibdev, struct ib_path *path ) { if ( path->madx ) ib_destroy_madx ( ibdev, ibdev->gsi, path->madx ); free ( path ); } /** Number of path cache entries * * Must be a power of two. */ #define IB_NUM_CACHED_PATHS 4 /** A cached path */ struct ib_cached_path { /** Path */ struct ib_path *path; }; /** Path cache */ static struct ib_cached_path ib_path_cache[IB_NUM_CACHED_PATHS]; /** Oldest path cache entry index */ static unsigned int ib_path_cache_idx; /** * Find path cache entry * * @v ibdev Infiniband device * @v dgid Destination GID * @ret path Path cache entry, or NULL */ static struct ib_cached_path * ib_find_path_cache_entry ( struct ib_device *ibdev, struct ib_gid *dgid ) { struct ib_cached_path *cached; unsigned int i; for ( i = 0 ; i < IB_NUM_CACHED_PATHS ; i++ ) { cached = &ib_path_cache[i]; if ( ! cached->path ) continue; if ( cached->path->ibdev != ibdev ) continue; if ( memcmp ( &cached->path->av.gid, dgid, sizeof ( cached->path->av.gid ) ) != 0 ) continue; return cached; } return NULL; } /** * Handle cached path transaction completion * * @v ibdev Infiniband device * @v path Path * @v rc Status code * @v av Address vector, or NULL on error */ static void ib_cached_path_complete ( struct ib_device *ibdev, struct ib_path *path, int rc, struct ib_address_vector *av __unused ) { struct ib_cached_path *cached = ib_path_get_ownerdata ( path ); /* If the transaction failed, erase the cache entry */ if ( rc != 0 ) { /* Destroy the old cache entry */ ib_destroy_path ( ibdev, path ); memset ( cached, 0, sizeof ( *cached ) ); return; } /* Do not destroy the completed transaction; we still need to * refer to the resolved path. */ } /** Cached path transaction completion operations */ static struct ib_path_operations ib_cached_path_op = { .complete = ib_cached_path_complete, }; /** * Resolve path * * @v ibdev Infiniband device * @v av Address vector to complete * @ret rc Return status code * * This provides a non-transactional way to resolve a path, via a * cache similar to ARP. */ int ib_resolve_path ( struct ib_device *ibdev, struct ib_address_vector *av ) { struct ib_gid *gid = &av->gid; struct ib_cached_path *cached; unsigned int cache_idx; /* Sanity check */ if ( ! av->gid_present ) { DBGC ( ibdev, "IBDEV %p attempt to look up path " "without GID\n", ibdev ); return -EINVAL; } /* Look in cache for a matching entry */ cached = ib_find_path_cache_entry ( ibdev, gid ); if ( cached && cached->path->av.lid ) { /* Populated entry found */ av->lid = cached->path->av.lid; av->rate = cached->path->av.rate; av->sl = cached->path->av.sl; DBGC2 ( ibdev, "IBDEV %p cache hit for %08x:%08x:%08x:%08x\n", ibdev, htonl ( gid->u.dwords[0] ), htonl ( gid->u.dwords[1] ), htonl ( gid->u.dwords[2] ), htonl ( gid->u.dwords[3] ) ); return 0; } DBGC ( ibdev, "IBDEV %p cache miss for %08x:%08x:%08x:%08x%s\n", ibdev, htonl ( gid->u.dwords[0] ), htonl ( gid->u.dwords[1] ), htonl ( gid->u.dwords[2] ), htonl ( gid->u.dwords[3] ), ( cached ? " (in progress)" : "" ) ); /* If lookup is already in progress, do nothing */ if ( cached ) return -ENOENT; /* Locate a new cache entry to use */ cache_idx = ( (ib_path_cache_idx++) % IB_NUM_CACHED_PATHS ); cached = &ib_path_cache[cache_idx]; /* Destroy the old cache entry */ if ( cached->path ) ib_destroy_path ( ibdev, cached->path ); memset ( cached, 0, sizeof ( *cached ) ); /* Create new path */ cached->path = ib_create_path ( ibdev, av, &ib_cached_path_op ); if ( ! cached->path ) { DBGC ( ibdev, "IBDEV %p could not create path\n", ibdev ); return -ENOMEM; } ib_path_set_ownerdata ( cached->path, cached ); /* Not found yet */ return -ENOENT; } debian/grub-extras/disabled/gpxe/src/net/infiniband/ib_cm.c0000664000000000000000000003030512524662415021050 0ustar /* * Copyright (C) 2009 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include /** * @file * * Infiniband communication management * */ /** List of connections */ static LIST_HEAD ( ib_cm_conns ); /** * Send "ready to use" response * * @v ibdev Infiniband device * @v mi Management interface * @v conn Connection * @v av Address vector * @ret rc Return status code */ static int ib_cm_send_rtu ( struct ib_device *ibdev, struct ib_mad_interface *mi, struct ib_connection *conn, struct ib_address_vector *av ) { union ib_mad mad; struct ib_cm_ready_to_use *ready = &mad.cm.cm_data.ready_to_use; int rc; /* Construct "ready to use" response */ memset ( &mad, 0, sizeof ( mad ) ); mad.hdr.mgmt_class = IB_MGMT_CLASS_CM; mad.hdr.class_version = IB_CM_CLASS_VERSION; mad.hdr.method = IB_MGMT_METHOD_SEND; mad.hdr.attr_id = htons ( IB_CM_ATTR_READY_TO_USE ); ready->local_id = htonl ( conn->local_id ); ready->remote_id = htonl ( conn->remote_id ); if ( ( rc = ib_mi_send ( ibdev, mi, &mad, av ) ) != 0 ){ DBGC ( conn, "CM %p could not send RTU: %s\n", conn, strerror ( rc ) ); return rc; } return 0; } /** * Handle duplicate connection replies * * @v ibdev Infiniband device * @v mi Management interface * @v mad Received MAD * @v av Source address vector * @ret rc Return status code * * If a "ready to use" MAD is lost, the peer may resend the connection * reply. We have to respond to these with duplicate "ready to use" * MADs, otherwise the peer may time out and drop the connection. */ static void ib_cm_connect_rep ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av ) { struct ib_cm_connect_reply *connect_rep = &mad->cm.cm_data.connect_reply; struct ib_connection *conn; int rc; /* Identify connection */ list_for_each_entry ( conn, &ib_cm_conns, list ) { if ( ntohl ( connect_rep->remote_id ) != conn->local_id ) continue; /* Try to send "ready to use" reply */ if ( ( rc = ib_cm_send_rtu ( ibdev, mi, conn, av ) ) != 0 ) { /* Ignore errors */ return; } return; } DBG ( "CM unidentified connection %08x\n", ntohl ( connect_rep->remote_id ) ); } /** Communication management agents */ struct ib_mad_agent ib_cm_agent[] __ib_mad_agent = { { .mgmt_class = IB_MGMT_CLASS_CM, .class_version = IB_CM_CLASS_VERSION, .attr_id = htons ( IB_CM_ATTR_CONNECT_REPLY ), .handle = ib_cm_connect_rep, }, }; /** * Convert connection rejection reason to return status code * * @v reason Rejection reason (in network byte order) * @ret rc Return status code */ static int ib_cm_rejection_reason_to_rc ( uint16_t reason ) { switch ( reason ) { case htons ( IB_CM_REJECT_BAD_SERVICE_ID ) : return -ENODEV; case htons ( IB_CM_REJECT_STALE_CONN ) : return -EALREADY; case htons ( IB_CM_REJECT_CONSUMER ) : return -ENOTTY; default: return -EPERM; } } /** * Handle connection request transaction completion * * @v ibdev Infiniband device * @v mi Management interface * @v madx Management transaction * @v rc Status code * @v mad Received MAD (or NULL on error) * @v av Source address vector (or NULL on error) */ static void ib_cm_req_complete ( struct ib_device *ibdev, struct ib_mad_interface *mi, struct ib_mad_transaction *madx, int rc, union ib_mad *mad, struct ib_address_vector *av ) { struct ib_connection *conn = ib_madx_get_ownerdata ( madx ); struct ib_queue_pair *qp = conn->qp; struct ib_cm_common *common = &mad->cm.cm_data.common; struct ib_cm_connect_reply *connect_rep = &mad->cm.cm_data.connect_reply; struct ib_cm_connect_reject *connect_rej = &mad->cm.cm_data.connect_reject; void *private_data = NULL; size_t private_data_len = 0; /* Report failures */ if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) )) rc = -EIO; if ( rc != 0 ) { DBGC ( conn, "CM %p connection request failed: %s\n", conn, strerror ( rc ) ); goto out; } /* Record remote communication ID */ conn->remote_id = ntohl ( common->local_id ); /* Handle response */ switch ( mad->hdr.attr_id ) { case htons ( IB_CM_ATTR_CONNECT_REPLY ) : /* Extract fields */ qp->av.qpn = ( ntohl ( connect_rep->local_qpn ) >> 8 ); qp->send.psn = ( ntohl ( connect_rep->starting_psn ) >> 8 ); private_data = &connect_rep->private_data; private_data_len = sizeof ( connect_rep->private_data ); DBGC ( conn, "CM %p connected to QPN %lx PSN %x\n", conn, qp->av.qpn, qp->send.psn ); /* Modify queue pair */ if ( ( rc = ib_modify_qp ( ibdev, qp ) ) != 0 ) { DBGC ( conn, "CM %p could not modify queue pair: %s\n", conn, strerror ( rc ) ); goto out; } /* Send "ready to use" reply */ if ( ( rc = ib_cm_send_rtu ( ibdev, mi, conn, av ) ) != 0 ) { /* Treat as non-fatal */ rc = 0; } break; case htons ( IB_CM_ATTR_CONNECT_REJECT ) : /* Extract fields */ DBGC ( conn, "CM %p connection rejected (reason %d)\n", conn, ntohs ( connect_rej->reason ) ); /* Private data is valid only for a Consumer Reject */ if ( connect_rej->reason == htons ( IB_CM_REJECT_CONSUMER ) ) { private_data = &connect_rej->private_data; private_data_len = sizeof (connect_rej->private_data); } rc = ib_cm_rejection_reason_to_rc ( connect_rej->reason ); break; default: DBGC ( conn, "CM %p unexpected response (attribute %04x)\n", conn, ntohs ( mad->hdr.attr_id ) ); rc = -ENOTSUP; break; } out: /* Destroy the completed transaction */ ib_destroy_madx ( ibdev, ibdev->gsi, madx ); conn->madx = NULL; /* Hand off to the upper completion handler */ conn->op->changed ( ibdev, qp, conn, rc, private_data, private_data_len ); } /** Connection request operations */ static struct ib_mad_transaction_operations ib_cm_req_op = { .complete = ib_cm_req_complete, }; /** * Handle connection path transaction completion * * @v ibdev Infiniband device * @v path Path * @v rc Status code * @v av Address vector, or NULL on error */ static void ib_cm_path_complete ( struct ib_device *ibdev, struct ib_path *path, int rc, struct ib_address_vector *av ) { struct ib_connection *conn = ib_path_get_ownerdata ( path ); struct ib_queue_pair *qp = conn->qp; union ib_mad mad; struct ib_cm_connect_request *connect_req = &mad.cm.cm_data.connect_request; size_t private_data_len; /* Report failures */ if ( rc != 0 ) { DBGC ( conn, "CM %p path lookup failed: %s\n", conn, strerror ( rc ) ); conn->op->changed ( ibdev, qp, conn, rc, NULL, 0 ); goto out; } /* Update queue pair peer path */ memcpy ( &qp->av, av, sizeof ( qp->av ) ); /* Construct connection request */ memset ( &mad, 0, sizeof ( mad ) ); mad.hdr.mgmt_class = IB_MGMT_CLASS_CM; mad.hdr.class_version = IB_CM_CLASS_VERSION; mad.hdr.method = IB_MGMT_METHOD_SEND; mad.hdr.attr_id = htons ( IB_CM_ATTR_CONNECT_REQUEST ); connect_req->local_id = htonl ( conn->local_id ); memcpy ( &connect_req->service_id, &conn->service_id, sizeof ( connect_req->service_id ) ); ib_get_hca_info ( ibdev, &connect_req->local_ca ); connect_req->local_qpn__responder_resources = htonl ( ( qp->qpn << 8 ) | 1 ); connect_req->local_eecn__initiator_depth = htonl ( ( 0 << 8 ) | 1 ); connect_req->remote_eecn__remote_timeout__service_type__ee_flow_ctrl = htonl ( ( 0x14 << 3 ) | ( IB_CM_TRANSPORT_RC << 1 ) | ( 0 << 0 ) ); connect_req->starting_psn__local_timeout__retry_count = htonl ( ( qp->recv.psn << 8 ) | ( 0x14 << 3 ) | ( 0x07 << 0 ) ); connect_req->pkey = htons ( ibdev->pkey ); connect_req->payload_mtu__rdc_exists__rnr_retry = ( ( IB_MTU_2048 << 4 ) | ( 1 << 3 ) | ( 0x07 << 0 ) ); connect_req->max_cm_retries__srq = ( ( 0x0f << 4 ) | ( 0 << 3 ) ); connect_req->primary.local_lid = htons ( ibdev->lid ); connect_req->primary.remote_lid = htons ( conn->qp->av.lid ); memcpy ( &connect_req->primary.local_gid, &ibdev->gid, sizeof ( connect_req->primary.local_gid ) ); memcpy ( &connect_req->primary.remote_gid, &conn->qp->av.gid, sizeof ( connect_req->primary.remote_gid ) ); connect_req->primary.flow_label__rate = htonl ( ( 0 << 12 ) | ( conn->qp->av.rate << 0 ) ); connect_req->primary.hop_limit = 0; connect_req->primary.sl__subnet_local = ( ( conn->qp->av.sl << 4 ) | ( 1 << 3 ) ); connect_req->primary.local_ack_timeout = ( 0x13 << 3 ); private_data_len = conn->private_data_len; if ( private_data_len > sizeof ( connect_req->private_data ) ) private_data_len = sizeof ( connect_req->private_data ); memcpy ( &connect_req->private_data, &conn->private_data, private_data_len ); /* Create connection request */ conn->madx = ib_create_madx ( ibdev, ibdev->gsi, &mad, NULL, &ib_cm_req_op ); if ( ! conn->madx ) { DBGC ( conn, "CM %p could not create connection request\n", conn ); conn->op->changed ( ibdev, qp, conn, rc, NULL, 0 ); goto out; } ib_madx_set_ownerdata ( conn->madx, conn ); out: /* Destroy the completed transaction */ ib_destroy_path ( ibdev, path ); conn->path = NULL; } /** Connection path operations */ static struct ib_path_operations ib_cm_path_op = { .complete = ib_cm_path_complete, }; /** * Create connection to remote QP * * @v ibdev Infiniband device * @v qp Queue pair * @v dgid Target GID * @v service_id Target service ID * @v private_data Connection request private data * @v private_data_len Length of connection request private data * @v op Connection operations * @ret conn Connection */ struct ib_connection * ib_create_conn ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_gid *dgid, struct ib_gid_half *service_id, void *private_data, size_t private_data_len, struct ib_connection_operations *op ) { struct ib_connection *conn; /* Allocate and initialise request */ conn = zalloc ( sizeof ( *conn ) + private_data_len ); if ( ! conn ) goto err_alloc_conn; conn->ibdev = ibdev; conn->qp = qp; memset ( &qp->av, 0, sizeof ( qp->av ) ); qp->av.gid_present = 1; memcpy ( &qp->av.gid, dgid, sizeof ( qp->av.gid ) ); conn->local_id = random(); memcpy ( &conn->service_id, service_id, sizeof ( conn->service_id ) ); conn->op = op; conn->private_data_len = private_data_len; memcpy ( &conn->private_data, private_data, private_data_len ); /* Create path */ conn->path = ib_create_path ( ibdev, &qp->av, &ib_cm_path_op ); if ( ! conn->path ) goto err_create_path; ib_path_set_ownerdata ( conn->path, conn ); /* Add to list of connections */ list_add ( &conn->list, &ib_cm_conns ); DBGC ( conn, "CM %p created for IBDEV %p QPN %lx\n", conn, ibdev, qp->qpn ); DBGC ( conn, "CM %p connecting to %08x:%08x:%08x:%08x %08x:%08x\n", conn, ntohl ( dgid->u.dwords[0] ), ntohl ( dgid->u.dwords[1] ), ntohl ( dgid->u.dwords[2] ), ntohl ( dgid->u.dwords[3] ), ntohl ( service_id->u.dwords[0] ), ntohl ( service_id->u.dwords[1] ) ); return conn; ib_destroy_path ( ibdev, conn->path ); err_create_path: free ( conn ); err_alloc_conn: return NULL; } /** * Destroy connection to remote QP * * @v ibdev Infiniband device * @v qp Queue pair * @v conn Connection */ void ib_destroy_conn ( struct ib_device *ibdev, struct ib_queue_pair *qp __unused, struct ib_connection *conn ) { list_del ( &conn->list ); if ( conn->madx ) ib_destroy_madx ( ibdev, ibdev->gsi, conn->madx ); if ( conn->path ) ib_destroy_path ( ibdev, conn->path ); free ( conn ); } debian/grub-extras/disabled/gpxe/src/net/infiniband/ib_sma.c0000664000000000000000000002510212524662415021230 0ustar /* * Copyright (C) 2009 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include /** * @file * * Infiniband Subnet Management Agent * */ /** * Node information * * @v ibdev Infiniband device * @v mi Management interface * @v mad Received MAD * @v av Source address vector */ static void ib_sma_node_info ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av ) { struct ib_node_info *node_info = &mad->smp.smp_data.node_info; int rc; /* Fill in information */ memset ( node_info, 0, sizeof ( *node_info ) ); node_info->base_version = IB_MGMT_BASE_VERSION; node_info->class_version = IB_SMP_CLASS_VERSION; node_info->node_type = IB_NODE_TYPE_HCA; node_info->num_ports = ib_get_hca_info ( ibdev, &node_info->sys_guid ); memcpy ( &node_info->node_guid, &node_info->sys_guid, sizeof ( node_info->node_guid ) ); memcpy ( &node_info->port_guid, &ibdev->gid.u.half[1], sizeof ( node_info->port_guid ) ); node_info->partition_cap = htons ( 1 ); node_info->local_port_num = ibdev->port; /* Send GetResponse */ mad->hdr.method = IB_MGMT_METHOD_GET_RESP; if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) { DBGC ( mi, "SMA %p could not send NodeInfo GetResponse: %s\n", mi, strerror ( rc ) ); return; } } /** * Node description * * @v ibdev Infiniband device * @v mi Management interface * @v mad Received MAD * @v av Source address vector */ static void ib_sma_node_desc ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av ) { struct ib_node_desc *node_desc = &mad->smp.smp_data.node_desc; struct ib_gid_half *guid = &ibdev->gid.u.half[1]; int rc; /* Fill in information */ memset ( node_desc, 0, sizeof ( *node_desc ) ); snprintf ( node_desc->node_string, sizeof ( node_desc->node_string ), "gPXE %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x (%s)", guid->u.bytes[0], guid->u.bytes[1], guid->u.bytes[2], guid->u.bytes[3], guid->u.bytes[4], guid->u.bytes[5], guid->u.bytes[6], guid->u.bytes[7], ibdev->dev->name ); /* Send GetResponse */ mad->hdr.method = IB_MGMT_METHOD_GET_RESP; if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) { DBGC ( mi, "SMA %p could not send NodeDesc GetResponse: %s\n", mi, strerror ( rc ) ); return; } } /** * GUID information * * @v ibdev Infiniband device * @v mi Management interface * @v mad Received MAD * @v av Source address vector */ static void ib_sma_guid_info ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av ) { struct ib_guid_info *guid_info = &mad->smp.smp_data.guid_info; int rc; /* Fill in information */ memset ( guid_info, 0, sizeof ( *guid_info ) ); memcpy ( guid_info->guid[0], &ibdev->gid.u.half[1], sizeof ( guid_info->guid[0] ) ); /* Send GetResponse */ mad->hdr.method = IB_MGMT_METHOD_GET_RESP; if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) { DBGC ( mi, "SMA %p could not send GuidInfo GetResponse: %s\n", mi, strerror ( rc ) ); return; } } /** * Set port information * * @v ibdev Infiniband device * @v mi Management interface * @v mad Received MAD * @ret rc Return status code */ static int ib_sma_set_port_info ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad ) { const struct ib_port_info *port_info = &mad->smp.smp_data.port_info; unsigned int link_width_enabled; unsigned int link_speed_enabled; int rc; /* Set parameters */ memcpy ( &ibdev->gid.u.half[0], port_info->gid_prefix, sizeof ( ibdev->gid.u.half[0] ) ); ibdev->lid = ntohs ( port_info->lid ); ibdev->sm_lid = ntohs ( port_info->mastersm_lid ); if ( ( link_width_enabled = port_info->link_width_enabled ) ) ibdev->link_width_enabled = link_width_enabled; if ( ( link_speed_enabled = ( port_info->link_speed_active__link_speed_enabled & 0xf ) ) ) ibdev->link_speed_enabled = link_speed_enabled; ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf ); DBGC ( mi, "SMA %p set LID %04x SMLID %04x link width %02x speed " "%02x\n", mi, ibdev->lid, ibdev->sm_lid, ibdev->link_width_enabled, ibdev->link_speed_enabled ); /* Update parameters on device */ if ( ( rc = ib_set_port_info ( ibdev, mad ) ) != 0 ) { DBGC ( mi, "SMA %p could not set port information: %s\n", mi, strerror ( rc ) ); return rc; } return 0; } /** * Port information * * @v ibdev Infiniband device * @v mi Management interface * @v mad Received MAD * @v av Source address vector */ static void ib_sma_port_info ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av ) { struct ib_port_info *port_info = &mad->smp.smp_data.port_info; int rc; /* Set parameters if applicable */ if ( mad->hdr.method == IB_MGMT_METHOD_SET ) { if ( ( rc = ib_sma_set_port_info ( ibdev, mi, mad ) ) != 0 ) { mad->hdr.status = htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR ); /* Fall through to generate GetResponse */ } } /* Fill in information */ memset ( port_info, 0, sizeof ( *port_info ) ); memcpy ( port_info->gid_prefix, &ibdev->gid.u.half[0], sizeof ( port_info->gid_prefix ) ); port_info->lid = ntohs ( ibdev->lid ); port_info->mastersm_lid = ntohs ( ibdev->sm_lid ); port_info->local_port_num = ibdev->port; port_info->link_width_enabled = ibdev->link_width_enabled; port_info->link_width_supported = ibdev->link_width_supported; port_info->link_width_active = ibdev->link_width_active; port_info->link_speed_supported__port_state = ( ( ibdev->link_speed_supported << 4 ) | ibdev->port_state ); port_info->port_phys_state__link_down_def_state = ( ( IB_PORT_PHYS_STATE_POLLING << 4 ) | IB_PORT_PHYS_STATE_POLLING ); port_info->link_speed_active__link_speed_enabled = ( ( ibdev->link_speed_active << 4 ) | ibdev->link_speed_enabled ); port_info->neighbour_mtu__mastersm_sl = ( ( IB_MTU_2048 << 4 ) | ibdev->sm_sl ); port_info->vl_cap__init_type = ( IB_VL_0 << 4 ); port_info->init_type_reply__mtu_cap = IB_MTU_2048; port_info->operational_vls__enforcement = ( IB_VL_0 << 4 ); port_info->guid_cap = 1; /* Send GetResponse */ mad->hdr.method = IB_MGMT_METHOD_GET_RESP; if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) { DBGC ( mi, "SMA %p could not send PortInfo GetResponse: %s\n", mi, strerror ( rc ) ); return; } } /** * Set partition key table * * @v ibdev Infiniband device * @v mi Management interface * @v mad Received MAD * @ret rc Return status code */ static int ib_sma_set_pkey_table ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad ) { struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table; int rc; /* Set parameters */ ibdev->pkey = ntohs ( pkey_table->pkey[0] ); DBGC ( mi, "SMA %p set pkey %04x\n", mi, ibdev->pkey ); /* Update parameters on device */ if ( ( rc = ib_set_pkey_table ( ibdev, mad ) ) != 0 ) { DBGC ( mi, "SMA %p could not set pkey table: %s\n", mi, strerror ( rc ) ); return rc; } return 0; } /** * Partition key table * * @v ibdev Infiniband device * @v mi Management interface * @v mad Received MAD * @v av Source address vector */ static void ib_sma_pkey_table ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av ) { struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table; int rc; /* Set parameters, if applicable */ if ( mad->hdr.method == IB_MGMT_METHOD_SET ) { if ( ( rc = ib_sma_set_pkey_table ( ibdev, mi, mad ) ) != 0 ) { mad->hdr.status = htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR ); /* Fall through to generate GetResponse */ } } /* Fill in information */ mad->hdr.method = IB_MGMT_METHOD_GET_RESP; memset ( pkey_table, 0, sizeof ( *pkey_table ) ); pkey_table->pkey[0] = htons ( ibdev->pkey ); /* Send GetResponse */ mad->hdr.method = IB_MGMT_METHOD_GET_RESP; if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) { DBGC ( mi, "SMA %p could not send PKeyTable GetResponse: %s\n", mi, strerror ( rc ) ); return; } } /** Subnet management agent */ struct ib_mad_agent ib_sma_agent[] __ib_mad_agent = { { .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, .class_version = IB_SMP_CLASS_VERSION, .attr_id = htons ( IB_SMP_ATTR_NODE_INFO ), .handle = ib_sma_node_info, }, { .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, .class_version = IB_SMP_CLASS_VERSION, .attr_id = htons ( IB_SMP_ATTR_NODE_DESC ), .handle = ib_sma_node_desc, }, { .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, .class_version = IB_SMP_CLASS_VERSION, .attr_id = htons ( IB_SMP_ATTR_GUID_INFO ), .handle = ib_sma_guid_info, }, { .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, .class_version = IB_SMP_CLASS_VERSION, .attr_id = htons ( IB_SMP_ATTR_PORT_INFO ), .handle = ib_sma_port_info, }, { .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, .class_version = IB_SMP_CLASS_VERSION, .attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE ), .handle = ib_sma_pkey_table, }, }; /** * Create subnet management agent and interface * * @v ibdev Infiniband device * @v mi Management interface * @ret rc Return status code */ int ib_create_sma ( struct ib_device *ibdev, struct ib_mad_interface *mi ) { /* Nothing to do */ DBGC ( ibdev, "IBDEV %p SMA using SMI %p\n", ibdev, mi ); return 0; } /** * Destroy subnet management agent and interface * * @v ibdev Infiniband device * @v mi Management interface */ void ib_destroy_sma ( struct ib_device *ibdev __unused, struct ib_mad_interface *mi __unused ) { /* Nothing to do */ } debian/grub-extras/disabled/gpxe/src/net/infiniband/ib_packet.c0000664000000000000000000001601512524662415021722 0ustar /* * Copyright (C) 2008 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include /** * @file * * Infiniband Packet Formats * */ /** * Add IB headers * * @v ibdev Infiniband device * @v iobuf I/O buffer to contain headers * @v qp Queue pair * @v payload_len Payload length * @v av Address vector */ int ib_push ( struct ib_device *ibdev, struct io_buffer *iobuf, struct ib_queue_pair *qp, size_t payload_len, const struct ib_address_vector *av ) { struct ib_local_route_header *lrh; struct ib_global_route_header *grh; struct ib_base_transport_header *bth; struct ib_datagram_extended_transport_header *deth; size_t orig_iob_len = iob_len ( iobuf ); size_t pad_len; size_t lrh_len; size_t grh_len; unsigned int vl; unsigned int lnh; DBGC2 ( ibdev, "IBDEV %p TX %04x:%08lx => %04x:%08lx (key %08lx)\n", ibdev, ibdev->lid, qp->ext_qpn, av->lid, av->qpn, av->qkey ); /* Calculate packet length */ pad_len = ( (-payload_len) & 0x3 ); payload_len += pad_len; payload_len += 4; /* ICRC */ /* Reserve space for headers */ orig_iob_len = iob_len ( iobuf ); deth = iob_push ( iobuf, sizeof ( *deth ) ); bth = iob_push ( iobuf, sizeof ( *bth ) ); grh_len = ( payload_len + iob_len ( iobuf ) - orig_iob_len ); grh = ( av->gid_present ? iob_push ( iobuf, sizeof ( *grh ) ) : NULL ); lrh = iob_push ( iobuf, sizeof ( *lrh ) ); lrh_len = ( payload_len + iob_len ( iobuf ) - orig_iob_len ); /* Construct LRH */ vl = ( ( qp->ext_qpn == IB_QPN_SMI ) ? IB_VL_SMP : IB_VL_DEFAULT ); lrh->vl__lver = ( vl << 4 ); lnh = ( grh ? IB_LNH_GRH : IB_LNH_BTH ); lrh->sl__lnh = ( ( av->sl << 4 ) | lnh ); lrh->dlid = htons ( av->lid ); lrh->length = htons ( lrh_len >> 2 ); lrh->slid = htons ( ibdev->lid ); /* Construct GRH, if required */ if ( grh ) { grh->ipver__tclass__flowlabel = htonl ( IB_GRH_IPVER_IPv6 << 28 ); grh->paylen = htons ( grh_len ); grh->nxthdr = IB_GRH_NXTHDR_IBA; grh->hoplmt = 0; memcpy ( &grh->sgid, &ibdev->gid, sizeof ( grh->sgid ) ); memcpy ( &grh->dgid, &av->gid, sizeof ( grh->dgid ) ); } /* Construct BTH */ bth->opcode = BTH_OPCODE_UD_SEND; bth->se__m__padcnt__tver = ( pad_len << 4 ); bth->pkey = htons ( ibdev->pkey ); bth->dest_qp = htonl ( av->qpn ); bth->ack__psn = htonl ( ( qp->send.psn++ ) & 0xffffffUL ); /* Construct DETH */ deth->qkey = htonl ( av->qkey ); deth->src_qp = htonl ( qp->ext_qpn ); DBGCP_HDA ( ibdev, 0, iobuf->data, ( iob_len ( iobuf ) - orig_iob_len ) ); return 0; } /** * Remove IB headers * * @v ibdev Infiniband device * @v iobuf I/O buffer containing headers * @v qp Queue pair to fill in, or NULL * @v payload_len Payload length to fill in, or NULL * @v av Address vector to fill in */ int ib_pull ( struct ib_device *ibdev, struct io_buffer *iobuf, struct ib_queue_pair **qp, size_t *payload_len, struct ib_address_vector *av ) { struct ib_local_route_header *lrh; struct ib_global_route_header *grh; struct ib_base_transport_header *bth; struct ib_datagram_extended_transport_header *deth; size_t orig_iob_len = iob_len ( iobuf ); unsigned int lnh; size_t pad_len; unsigned long qpn; unsigned int lid; /* Clear return values */ if ( qp ) *qp = NULL; if ( payload_len ) *payload_len = 0; memset ( av, 0, sizeof ( *av ) ); /* Extract LRH */ if ( iob_len ( iobuf ) < sizeof ( *lrh ) ) { DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) for LRH\n", ibdev, iob_len ( iobuf ) ); return -EINVAL; } lrh = iobuf->data; iob_pull ( iobuf, sizeof ( *lrh ) ); av->lid = ntohs ( lrh->slid ); av->sl = ( lrh->sl__lnh >> 4 ); lnh = ( lrh->sl__lnh & 0x3 ); lid = ntohs ( lrh->dlid ); /* Reject unsupported packets */ if ( ! ( ( lnh == IB_LNH_BTH ) || ( lnh == IB_LNH_GRH ) ) ) { DBGC ( ibdev, "IBDEV %p RX unsupported LNH %x\n", ibdev, lnh ); return -ENOTSUP; } /* Extract GRH, if present */ if ( lnh == IB_LNH_GRH ) { if ( iob_len ( iobuf ) < sizeof ( *grh ) ) { DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) " "for GRH\n", ibdev, iob_len ( iobuf ) ); return -EINVAL; } grh = iobuf->data; iob_pull ( iobuf, sizeof ( *grh ) ); av->gid_present = 1; memcpy ( &av->gid, &grh->sgid, sizeof ( av->gid ) ); } else { grh = NULL; } /* Extract BTH */ if ( iob_len ( iobuf ) < sizeof ( *bth ) ) { DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) for BTH\n", ibdev, iob_len ( iobuf ) ); return -EINVAL; } bth = iobuf->data; iob_pull ( iobuf, sizeof ( *bth ) ); if ( bth->opcode != BTH_OPCODE_UD_SEND ) { DBGC ( ibdev, "IBDEV %p unsupported BTH opcode %x\n", ibdev, bth->opcode ); return -ENOTSUP; } qpn = ntohl ( bth->dest_qp ); /* Extract DETH */ if ( iob_len ( iobuf ) < sizeof ( *deth ) ) { DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) for DETH\n", ibdev, iob_len ( iobuf ) ); return -EINVAL; } deth = iobuf->data; iob_pull ( iobuf, sizeof ( *deth ) ); av->qpn = ntohl ( deth->src_qp ); av->qkey = ntohl ( deth->qkey ); /* Calculate payload length, if applicable */ if ( payload_len ) { pad_len = ( ( bth->se__m__padcnt__tver >> 4 ) & 0x3 ); *payload_len = ( ( ntohs ( lrh->length ) << 2 ) - ( orig_iob_len - iob_len ( iobuf ) ) - pad_len - 4 /* ICRC */ ); } /* Determine destination QP, if applicable */ if ( qp ) { if ( IB_LID_MULTICAST ( lid ) && grh ) { if ( ! ( *qp = ib_find_qp_mgid ( ibdev, &grh->dgid ))){ DBGC ( ibdev, "IBDEV %p RX for unknown MGID " "%08x:%08x:%08x:%08x\n", ibdev, ntohl ( grh->dgid.u.dwords[0] ), ntohl ( grh->dgid.u.dwords[1] ), ntohl ( grh->dgid.u.dwords[2] ), ntohl ( grh->dgid.u.dwords[3] ) ); return -ENODEV; } } else { if ( ! ( *qp = ib_find_qp_qpn ( ibdev, qpn ) ) ) { DBGC ( ibdev, "IBDEV %p RX for nonexistent " "QPN %lx\n", ibdev, qpn ); return -ENODEV; } } assert ( *qp ); } DBGC2 ( ibdev, "IBDEV %p RX %04x:%08lx <= %04x:%08lx (key %08x)\n", ibdev, lid, ( IB_LID_MULTICAST( lid ) ? ( qp ? (*qp)->ext_qpn : -1UL ) : qpn ), av->lid, av->qpn, ntohl ( deth->qkey ) ); DBGCP_HDA ( ibdev, 0, ( iobuf->data - ( orig_iob_len - iob_len ( iobuf ) ) ), ( orig_iob_len - iob_len ( iobuf ) ) ); return 0; } debian/grub-extras/disabled/gpxe/src/net/infiniband/ib_mi.c0000664000000000000000000002606312524662415021064 0ustar /* * Copyright (C) 2009 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include /** * @file * * Infiniband management interfaces * */ /** Management interface number of send WQEs * * This is a policy decision. */ #define IB_MI_NUM_SEND_WQES 4 /** Management interface number of receive WQEs * * This is a policy decision. */ #define IB_MI_NUM_RECV_WQES 2 /** Management interface number of completion queue entries * * This is a policy decision */ #define IB_MI_NUM_CQES 8 /** TID magic signature */ #define IB_MI_TID_MAGIC ( ( 'g' << 24 ) | ( 'P' << 16 ) | ( 'X' << 8 ) | 'E' ) /** TID to use for next MAD */ static unsigned int next_tid; /** * Handle received MAD * * @v ibdev Infiniband device * @v mi Management interface * @v mad Received MAD * @v av Source address vector * @ret rc Return status code */ static int ib_mi_handle ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av ) { struct ib_mad_hdr *hdr = &mad->hdr; struct ib_mad_transaction *madx; struct ib_mad_agent *agent; /* Look for a matching transaction by TID */ list_for_each_entry ( madx, &mi->madx, list ) { if ( memcmp ( &hdr->tid, &madx->mad.hdr.tid, sizeof ( hdr->tid ) ) != 0 ) continue; /* Found a matching transaction */ madx->op->complete ( ibdev, mi, madx, 0, mad, av ); return 0; } /* If there is no matching transaction, look for a listening agent */ for_each_table_entry ( agent, IB_MAD_AGENTS ) { if ( ( ( agent->mgmt_class & IB_MGMT_CLASS_MASK ) != ( hdr->mgmt_class & IB_MGMT_CLASS_MASK ) ) || ( agent->class_version != hdr->class_version ) || ( agent->attr_id != hdr->attr_id ) ) continue; /* Found a matching agent */ agent->handle ( ibdev, mi, mad, av ); return 0; } /* Otherwise, ignore it */ DBGC ( mi, "MI %p RX TID %08x%08x ignored\n", mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ) ); return -ENOTSUP; } /** * Complete receive via management interface * * * @v ibdev Infiniband device * @v qp Queue pair * @v av Address vector * @v iobuf I/O buffer * @v rc Completion status code */ static void ib_mi_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf, int rc ) { struct ib_mad_interface *mi = ib_qp_get_ownerdata ( qp ); union ib_mad *mad; struct ib_mad_hdr *hdr; /* Ignore errors */ if ( rc != 0 ) { DBGC ( mi, "MI %p RX error: %s\n", mi, strerror ( rc ) ); goto out; } /* Sanity checks */ if ( iob_len ( iobuf ) != sizeof ( *mad ) ) { DBGC ( mi, "MI %p RX bad size (%zd bytes)\n", mi, iob_len ( iobuf ) ); DBGC_HDA ( mi, 0, iobuf->data, iob_len ( iobuf ) ); goto out; } mad = iobuf->data; hdr = &mad->hdr; if ( hdr->base_version != IB_MGMT_BASE_VERSION ) { DBGC ( mi, "MI %p RX unsupported base version %x\n", mi, hdr->base_version ); DBGC_HDA ( mi, 0, mad, sizeof ( *mad ) ); goto out; } DBGC ( mi, "MI %p RX TID %08x%08x (%02x,%02x,%02x,%04x) status " "%04x\n", mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ), hdr->mgmt_class, hdr->class_version, hdr->method, ntohs ( hdr->attr_id ), ntohs ( hdr->status ) ); DBGC2_HDA ( mi, 0, mad, sizeof ( *mad ) ); /* Handle MAD */ if ( ( rc = ib_mi_handle ( ibdev, mi, mad, av ) ) != 0 ) goto out; out: free_iob ( iobuf ); } /** Management interface completion operations */ static struct ib_completion_queue_operations ib_mi_completion_ops = { .complete_recv = ib_mi_complete_recv, }; /** * Transmit MAD * * @v ibdev Infiniband device * @v mi Management interface * @v mad MAD * @v av Destination address vector * @ret rc Return status code */ int ib_mi_send ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av ) { struct ib_mad_hdr *hdr = &mad->hdr; struct io_buffer *iobuf; int rc; /* Set common fields */ hdr->base_version = IB_MGMT_BASE_VERSION; if ( ( hdr->tid[0] == 0 ) && ( hdr->tid[1] == 0 ) ) { hdr->tid[0] = htonl ( IB_MI_TID_MAGIC ); hdr->tid[1] = htonl ( ++next_tid ); } DBGC ( mi, "MI %p TX TID %08x%08x (%02x,%02x,%02x,%04x) status " "%04x\n", mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ), hdr->mgmt_class, hdr->class_version, hdr->method, ntohs ( hdr->attr_id ), ntohs ( hdr->status ) ); DBGC2_HDA ( mi, 0, mad, sizeof ( *mad ) ); /* Construct directed route portion of response, if necessary */ if ( hdr->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE ) { struct ib_mad_smp *smp = &mad->smp; unsigned int hop_pointer; unsigned int hop_count; smp->mad_hdr.status |= htons ( IB_SMP_STATUS_D_INBOUND ); hop_pointer = smp->mad_hdr.class_specific.smp.hop_pointer; hop_count = smp->mad_hdr.class_specific.smp.hop_count; assert ( hop_count == hop_pointer ); if ( hop_pointer < ( sizeof ( smp->return_path.hops ) / sizeof ( smp->return_path.hops[0] ) ) ) { smp->return_path.hops[hop_pointer] = ibdev->port; } else { DBGC ( mi, "MI %p TX TID %08x%08x invalid hop pointer " "%d\n", mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ), hop_pointer ); return -EINVAL; } } /* Construct I/O buffer */ iobuf = alloc_iob ( sizeof ( *mad ) ); if ( ! iobuf ) { DBGC ( mi, "MI %p could not allocate buffer for TID " "%08x%08x\n", mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ) ); return -ENOMEM; } memcpy ( iob_put ( iobuf, sizeof ( *mad ) ), mad, sizeof ( *mad ) ); /* Send I/O buffer */ if ( ( rc = ib_post_send ( ibdev, mi->qp, av, iobuf ) ) != 0 ) { DBGC ( mi, "MI %p TX TID %08x%08x failed: %s\n", mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ), strerror ( rc ) ); free_iob ( iobuf ); return rc; } return 0; } /** * Handle management transaction timer expiry * * @v timer Retry timer * @v expired Failure indicator */ static void ib_mi_timer_expired ( struct retry_timer *timer, int expired ) { struct ib_mad_transaction *madx = container_of ( timer, struct ib_mad_transaction, timer ); struct ib_mad_interface *mi = madx->mi; struct ib_device *ibdev = mi->ibdev; struct ib_mad_hdr *hdr = &madx->mad.hdr; /* Abandon transaction if we have tried too many times */ if ( expired ) { DBGC ( mi, "MI %p abandoning TID %08x%08x\n", mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ) ); madx->op->complete ( ibdev, mi, madx, -ETIMEDOUT, NULL, NULL ); return; } /* Restart retransmission timer */ start_timer ( timer ); /* Resend MAD */ ib_mi_send ( ibdev, mi, &madx->mad, &madx->av ); } /** * Create management transaction * * @v ibdev Infiniband device * @v mi Management interface * @v mad MAD to send * @v av Destination address, or NULL to use SM's GSI * @v op Management transaction operations * @ret madx Management transaction, or NULL */ struct ib_mad_transaction * ib_create_madx ( struct ib_device *ibdev, struct ib_mad_interface *mi, union ib_mad *mad, struct ib_address_vector *av, struct ib_mad_transaction_operations *op ) { struct ib_mad_transaction *madx; /* Allocate and initialise structure */ madx = zalloc ( sizeof ( *madx ) ); if ( ! madx ) return NULL; madx->mi = mi; madx->timer.expired = ib_mi_timer_expired; madx->op = op; /* Determine address vector */ if ( av ) { memcpy ( &madx->av, av, sizeof ( madx->av ) ); } else { madx->av.lid = ibdev->sm_lid; madx->av.sl = ibdev->sm_sl; madx->av.qpn = IB_QPN_GSI; madx->av.qkey = IB_QKEY_GSI; } /* Copy MAD */ memcpy ( &madx->mad, mad, sizeof ( madx->mad ) ); /* Add to list and start timer to send initial MAD */ list_add ( &madx->list, &mi->madx ); start_timer_nodelay ( &madx->timer ); return madx; } /** * Destroy management transaction * * @v ibdev Infiniband device * @v mi Management interface * @v madx Management transaction */ void ib_destroy_madx ( struct ib_device *ibdev __unused, struct ib_mad_interface *mi __unused, struct ib_mad_transaction *madx ) { /* Stop timer and remove from list */ stop_timer ( &madx->timer ); list_del ( &madx->list ); /* Free transaction */ free ( madx ); } /** * Create management interface * * @v ibdev Infiniband device * @v type Queue pair type * @ret mi Management agent, or NULL */ struct ib_mad_interface * ib_create_mi ( struct ib_device *ibdev, enum ib_queue_pair_type type ) { struct ib_mad_interface *mi; int rc; /* Allocate and initialise fields */ mi = zalloc ( sizeof ( *mi ) ); if ( ! mi ) goto err_alloc; mi->ibdev = ibdev; INIT_LIST_HEAD ( &mi->madx ); /* Create completion queue */ mi->cq = ib_create_cq ( ibdev, IB_MI_NUM_CQES, &ib_mi_completion_ops ); if ( ! mi->cq ) { DBGC ( mi, "MI %p could not allocate completion queue\n", mi ); goto err_create_cq; } /* Create queue pair */ mi->qp = ib_create_qp ( ibdev, type, IB_MI_NUM_SEND_WQES, mi->cq, IB_MI_NUM_RECV_WQES, mi->cq ); if ( ! mi->qp ) { DBGC ( mi, "MI %p could not allocate queue pair\n", mi ); goto err_create_qp; } ib_qp_set_ownerdata ( mi->qp, mi ); DBGC ( mi, "MI %p (%s) running on QPN %#lx\n", mi, ( ( type == IB_QPT_SMI ) ? "SMI" : "GSI" ), mi->qp->qpn ); /* Set queue key */ mi->qp->qkey = ( ( type == IB_QPT_SMI ) ? IB_QKEY_SMI : IB_QKEY_GSI ); if ( ( rc = ib_modify_qp ( ibdev, mi->qp ) ) != 0 ) { DBGC ( mi, "MI %p could not set queue key: %s\n", mi, strerror ( rc ) ); goto err_modify_qp; } /* Fill receive ring */ ib_refill_recv ( ibdev, mi->qp ); return mi; err_modify_qp: ib_destroy_qp ( ibdev, mi->qp ); err_create_qp: ib_destroy_cq ( ibdev, mi->cq ); err_create_cq: free ( mi ); err_alloc: return NULL; } /** * Destroy management interface * * @v mi Management interface */ void ib_destroy_mi ( struct ib_device *ibdev, struct ib_mad_interface *mi ) { struct ib_mad_transaction *madx; struct ib_mad_transaction *tmp; /* Flush any outstanding requests */ list_for_each_entry_safe ( madx, tmp, &mi->madx, list ) { DBGC ( mi, "MI %p destroyed while TID %08x%08x in progress\n", mi, ntohl ( madx->mad.hdr.tid[0] ), ntohl ( madx->mad.hdr.tid[1] ) ); madx->op->complete ( ibdev, mi, madx, -ECANCELED, NULL, NULL ); } ib_destroy_qp ( ibdev, mi->qp ); ib_destroy_cq ( ibdev, mi->cq ); free ( mi ); } debian/grub-extras/disabled/gpxe/src/net/infiniband/ib_smc.c0000664000000000000000000001245112524662415021235 0ustar /* * Copyright (C) 2008 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include /** * @file * * Infiniband Subnet Management Client * */ /** * Get port information * * @v ibdev Infiniband device * @v local_mad Method for issuing local MADs * @v mad Management datagram to fill in * @ret rc Return status code */ static int ib_smc_get_port_info ( struct ib_device *ibdev, ib_local_mad_t local_mad, union ib_mad *mad ) { int rc; /* Construct MAD */ memset ( mad, 0, sizeof ( *mad ) ); mad->hdr.base_version = IB_MGMT_BASE_VERSION; mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; mad->hdr.class_version = 1; mad->hdr.method = IB_MGMT_METHOD_GET; mad->hdr.attr_id = htons ( IB_SMP_ATTR_PORT_INFO ); mad->hdr.attr_mod = htonl ( ibdev->port ); if ( ( rc = local_mad ( ibdev, mad ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not get port info: %s\n", ibdev, strerror ( rc ) ); return rc; } return 0; } /** * Get GUID information * * @v ibdev Infiniband device * @v local_mad Method for issuing local MADs * @v mad Management datagram to fill in * @ret rc Return status code */ static int ib_smc_get_guid_info ( struct ib_device *ibdev, ib_local_mad_t local_mad, union ib_mad *mad ) { int rc; /* Construct MAD */ memset ( mad, 0, sizeof ( *mad ) ); mad->hdr.base_version = IB_MGMT_BASE_VERSION; mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; mad->hdr.class_version = 1; mad->hdr.method = IB_MGMT_METHOD_GET; mad->hdr.attr_id = htons ( IB_SMP_ATTR_GUID_INFO ); if ( ( rc = local_mad ( ibdev, mad ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not get GUID info: %s\n", ibdev, strerror ( rc ) ); return rc; } return 0; } /** * Get partition key table * * @v ibdev Infiniband device * @v local_mad Method for issuing local MADs * @v mad Management datagram to fill in * @ret rc Return status code */ static int ib_smc_get_pkey_table ( struct ib_device *ibdev, ib_local_mad_t local_mad, union ib_mad *mad ) { int rc; /* Construct MAD */ memset ( mad, 0, sizeof ( *mad ) ); mad->hdr.base_version = IB_MGMT_BASE_VERSION; mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; mad->hdr.class_version = 1; mad->hdr.method = IB_MGMT_METHOD_GET; mad->hdr.attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE ); if ( ( rc = local_mad ( ibdev, mad ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not get pkey table: %s\n", ibdev, strerror ( rc ) ); return rc; } return 0; } /** * Get MAD parameters * * @v ibdev Infiniband device * @v local_mad Method for issuing local MADs * @ret rc Return status code */ int ib_smc_update ( struct ib_device *ibdev, ib_local_mad_t local_mad ) { union ib_mad mad; struct ib_port_info *port_info = &mad.smp.smp_data.port_info; struct ib_guid_info *guid_info = &mad.smp.smp_data.guid_info; struct ib_pkey_table *pkey_table = &mad.smp.smp_data.pkey_table; int rc; /* Port info gives us the link state, the first half of the * port GID and the SM LID. */ if ( ( rc = ib_smc_get_port_info ( ibdev, local_mad, &mad ) ) != 0 ) return rc; memcpy ( &ibdev->gid.u.half[0], port_info->gid_prefix, sizeof ( ibdev->gid.u.half[0] ) ); ibdev->lid = ntohs ( port_info->lid ); ibdev->sm_lid = ntohs ( port_info->mastersm_lid ); ibdev->link_width_enabled = port_info->link_width_enabled; ibdev->link_width_supported = port_info->link_width_supported; ibdev->link_width_active = port_info->link_width_active; ibdev->link_speed_supported = ( port_info->link_speed_supported__port_state >> 4 ); ibdev->port_state = ( port_info->link_speed_supported__port_state & 0xf ); ibdev->link_speed_active = ( port_info->link_speed_active__link_speed_enabled >> 4 ); ibdev->link_speed_enabled = ( port_info->link_speed_active__link_speed_enabled & 0xf ); ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf ); /* GUID info gives us the second half of the port GID */ if ( ( rc = ib_smc_get_guid_info ( ibdev, local_mad, &mad ) ) != 0 ) return rc; memcpy ( &ibdev->gid.u.half[1], guid_info->guid[0], sizeof ( ibdev->gid.u.half[1] ) ); /* Get partition key */ if ( ( rc = ib_smc_get_pkey_table ( ibdev, local_mad, &mad ) ) != 0 ) return rc; ibdev->pkey = ntohs ( pkey_table->pkey[0] ); DBGC ( ibdev, "IBDEV %p port GID is %08x:%08x:%08x:%08x\n", ibdev, htonl ( ibdev->gid.u.dwords[0] ), htonl ( ibdev->gid.u.dwords[1] ), htonl ( ibdev->gid.u.dwords[2] ), htonl ( ibdev->gid.u.dwords[3] ) ); return 0; } debian/grub-extras/disabled/gpxe/src/net/arp.c0000664000000000000000000002154212524662415016463 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include /** @file * * Address Resolution Protocol * * This file implements the address resolution protocol as defined in * RFC826. The implementation is media-independent and * protocol-independent; it is not limited to Ethernet or to IPv4. * */ /** An ARP cache entry */ struct arp_entry { /** Network-layer protocol */ struct net_protocol *net_protocol; /** Link-layer protocol */ struct ll_protocol *ll_protocol; /** Network-layer address */ uint8_t net_addr[MAX_NET_ADDR_LEN]; /** Link-layer address */ uint8_t ll_addr[MAX_LL_ADDR_LEN]; }; /** Number of entries in the ARP cache * * This is a global cache, covering all network interfaces, * network-layer protocols and link-layer protocols. */ #define NUM_ARP_ENTRIES 4 /** The ARP cache */ static struct arp_entry arp_table[NUM_ARP_ENTRIES]; #define arp_table_end &arp_table[NUM_ARP_ENTRIES] static unsigned int next_new_arp_entry = 0; struct net_protocol arp_protocol; /** * Find entry in the ARP cache * * @v ll_protocol Link-layer protocol * @v net_protocol Network-layer protocol * @v net_addr Network-layer address * @ret arp ARP cache entry, or NULL if not found * */ static struct arp_entry * arp_find_entry ( struct ll_protocol *ll_protocol, struct net_protocol *net_protocol, const void *net_addr ) { struct arp_entry *arp; for ( arp = arp_table ; arp < arp_table_end ; arp++ ) { if ( ( arp->ll_protocol == ll_protocol ) && ( arp->net_protocol == net_protocol ) && ( memcmp ( arp->net_addr, net_addr, net_protocol->net_addr_len ) == 0 ) ) return arp; } return NULL; } /** * Look up media-specific link-layer address in the ARP cache * * @v netdev Network device * @v net_protocol Network-layer protocol * @v dest_net_addr Destination network-layer address * @v source_net_addr Source network-layer address * @ret dest_ll_addr Destination link layer address * @ret rc Return status code * * This function will use the ARP cache to look up the link-layer * address for the link-layer protocol associated with the network * device and the given network-layer protocol and addresses. If * found, the destination link-layer address will be filled in in @c * dest_ll_addr. * * If no address is found in the ARP cache, an ARP request will be * transmitted on the specified network device and -ENOENT will be * returned. */ int arp_resolve ( struct net_device *netdev, struct net_protocol *net_protocol, const void *dest_net_addr, const void *source_net_addr, void *dest_ll_addr ) { struct ll_protocol *ll_protocol = netdev->ll_protocol; const struct arp_entry *arp; struct io_buffer *iobuf; struct arphdr *arphdr; int rc; /* Look for existing entry in ARP table */ arp = arp_find_entry ( ll_protocol, net_protocol, dest_net_addr ); if ( arp ) { DBG ( "ARP cache hit: %s %s => %s %s\n", net_protocol->name, net_protocol->ntoa ( arp->net_addr ), ll_protocol->name, ll_protocol->ntoa ( arp->ll_addr ) ); memcpy ( dest_ll_addr, arp->ll_addr, ll_protocol->ll_addr_len); return 0; } DBG ( "ARP cache miss: %s %s\n", net_protocol->name, net_protocol->ntoa ( dest_net_addr ) ); /* Allocate ARP packet */ iobuf = alloc_iob ( MAX_LL_HEADER_LEN + sizeof ( *arphdr ) + 2 * ( MAX_LL_ADDR_LEN + MAX_NET_ADDR_LEN ) ); if ( ! iobuf ) return -ENOMEM; iob_reserve ( iobuf, MAX_LL_HEADER_LEN ); /* Build up ARP request */ arphdr = iob_put ( iobuf, sizeof ( *arphdr ) ); arphdr->ar_hrd = ll_protocol->ll_proto; arphdr->ar_hln = ll_protocol->ll_addr_len; arphdr->ar_pro = net_protocol->net_proto; arphdr->ar_pln = net_protocol->net_addr_len; arphdr->ar_op = htons ( ARPOP_REQUEST ); memcpy ( iob_put ( iobuf, ll_protocol->ll_addr_len ), netdev->ll_addr, ll_protocol->ll_addr_len ); memcpy ( iob_put ( iobuf, net_protocol->net_addr_len ), source_net_addr, net_protocol->net_addr_len ); memset ( iob_put ( iobuf, ll_protocol->ll_addr_len ), 0, ll_protocol->ll_addr_len ); memcpy ( iob_put ( iobuf, net_protocol->net_addr_len ), dest_net_addr, net_protocol->net_addr_len ); /* Transmit ARP request */ if ( ( rc = net_tx ( iobuf, netdev, &arp_protocol, netdev->ll_broadcast ) ) != 0 ) return rc; return -ENOENT; } /** * Identify ARP protocol * * @v net_proto Network-layer protocol, in network-endian order * @ret arp_net_protocol ARP protocol, or NULL * */ static struct arp_net_protocol * arp_find_protocol ( uint16_t net_proto ) { struct arp_net_protocol *arp_net_protocol; for_each_table_entry ( arp_net_protocol, ARP_NET_PROTOCOLS ) { if ( arp_net_protocol->net_protocol->net_proto == net_proto ) { return arp_net_protocol; } } return NULL; } /** * Process incoming ARP packets * * @v iobuf I/O buffer * @v netdev Network device * @v ll_source Link-layer source address * @ret rc Return status code * * This handles ARP requests and responses as detailed in RFC826. The * method detailed within the RFC is pretty optimised, handling * requests and responses with basically a single code path and * avoiding the need for extraneous ARP requests; read the RFC for * details. */ static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev, const void *ll_source __unused ) { struct arphdr *arphdr = iobuf->data; struct arp_net_protocol *arp_net_protocol; struct net_protocol *net_protocol; struct ll_protocol *ll_protocol; struct arp_entry *arp; int merge = 0; /* Identify network-layer and link-layer protocols */ arp_net_protocol = arp_find_protocol ( arphdr->ar_pro ); if ( ! arp_net_protocol ) goto done; net_protocol = arp_net_protocol->net_protocol; ll_protocol = netdev->ll_protocol; /* Sanity checks */ if ( ( arphdr->ar_hrd != ll_protocol->ll_proto ) || ( arphdr->ar_hln != ll_protocol->ll_addr_len ) || ( arphdr->ar_pln != net_protocol->net_addr_len ) ) goto done; /* See if we have an entry for this sender, and update it if so */ arp = arp_find_entry ( ll_protocol, net_protocol, arp_sender_pa ( arphdr ) ); if ( arp ) { memcpy ( arp->ll_addr, arp_sender_ha ( arphdr ), arphdr->ar_hln ); merge = 1; DBG ( "ARP cache update: %s %s => %s %s\n", net_protocol->name, net_protocol->ntoa ( arp->net_addr ), ll_protocol->name, ll_protocol->ntoa ( arp->ll_addr ) ); } /* See if we own the target protocol address */ if ( arp_net_protocol->check ( netdev, arp_target_pa ( arphdr ) ) != 0) goto done; /* Create new ARP table entry if necessary */ if ( ! merge ) { arp = &arp_table[next_new_arp_entry++ % NUM_ARP_ENTRIES]; arp->ll_protocol = ll_protocol; arp->net_protocol = net_protocol; memcpy ( arp->ll_addr, arp_sender_ha ( arphdr ), arphdr->ar_hln ); memcpy ( arp->net_addr, arp_sender_pa ( arphdr ), arphdr->ar_pln); DBG ( "ARP cache add: %s %s => %s %s\n", net_protocol->name, net_protocol->ntoa ( arp->net_addr ), ll_protocol->name, ll_protocol->ntoa ( arp->ll_addr ) ); } /* If it's not a request, there's nothing more to do */ if ( arphdr->ar_op != htons ( ARPOP_REQUEST ) ) goto done; /* Change request to a reply */ DBG ( "ARP reply: %s %s => %s %s\n", net_protocol->name, net_protocol->ntoa ( arp_target_pa ( arphdr ) ), ll_protocol->name, ll_protocol->ntoa ( netdev->ll_addr ) ); arphdr->ar_op = htons ( ARPOP_REPLY ); memswap ( arp_sender_ha ( arphdr ), arp_target_ha ( arphdr ), arphdr->ar_hln + arphdr->ar_pln ); memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln ); /* Send reply */ net_tx ( iob_disown ( iobuf ), netdev, &arp_protocol, arp_target_ha ( arphdr ) ); done: free_iob ( iobuf ); return 0; } /** * Transcribe ARP address * * @v net_addr ARP address * @ret string "" * * This operation is meaningless for the ARP protocol. */ static const char * arp_ntoa ( const void *net_addr __unused ) { return ""; } /** ARP protocol */ struct net_protocol arp_protocol __net_protocol = { .name = "ARP", .net_proto = htons ( ETH_P_ARP ), .rx = arp_rx, .ntoa = arp_ntoa, }; debian/grub-extras/disabled/gpxe/src/net/udp.c0000664000000000000000000002702412524662415016472 0ustar #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * UDP protocol */ FILE_LICENCE ( GPL2_OR_LATER ); /** * A UDP connection * */ struct udp_connection { /** Reference counter */ struct refcnt refcnt; /** List of UDP connections */ struct list_head list; /** Data transfer interface */ struct xfer_interface xfer; /** Local socket address */ struct sockaddr_tcpip local; /** Remote socket address */ struct sockaddr_tcpip peer; }; /** * List of registered UDP connections */ static LIST_HEAD ( udp_conns ); /* Forward declatations */ static struct xfer_interface_operations udp_xfer_operations; struct tcpip_protocol udp_protocol; /** * Bind UDP connection to local port * * @v udp UDP connection * @ret rc Return status code * * Opens the UDP connection and binds to the specified local port. If * no local port is specified, the first available port will be used. */ static int udp_bind ( struct udp_connection *udp ) { struct udp_connection *existing; static uint16_t try_port = 1023; /* If no port specified, find the first available port */ if ( ! udp->local.st_port ) { while ( try_port ) { try_port++; if ( try_port < 1024 ) continue; udp->local.st_port = htons ( try_port ); if ( udp_bind ( udp ) == 0 ) return 0; } return -EADDRINUSE; } /* Attempt bind to local port */ list_for_each_entry ( existing, &udp_conns, list ) { if ( existing->local.st_port == udp->local.st_port ) { DBGC ( udp, "UDP %p could not bind: port %d in use\n", udp, ntohs ( udp->local.st_port ) ); return -EADDRINUSE; } } /* Add to UDP connection list */ DBGC ( udp, "UDP %p bound to port %d\n", udp, ntohs ( udp->local.st_port ) ); return 0; } /** * Open a UDP connection * * @v xfer Data transfer interface * @v peer Peer socket address, or NULL * @v local Local socket address, or NULL * @v promisc Socket is promiscuous * @ret rc Return status code */ static int udp_open_common ( struct xfer_interface *xfer, struct sockaddr *peer, struct sockaddr *local, int promisc ) { struct sockaddr_tcpip *st_peer = ( struct sockaddr_tcpip * ) peer; struct sockaddr_tcpip *st_local = ( struct sockaddr_tcpip * ) local; struct udp_connection *udp; int rc; /* Allocate and initialise structure */ udp = zalloc ( sizeof ( *udp ) ); if ( ! udp ) return -ENOMEM; DBGC ( udp, "UDP %p allocated\n", udp ); xfer_init ( &udp->xfer, &udp_xfer_operations, &udp->refcnt ); if ( st_peer ) memcpy ( &udp->peer, st_peer, sizeof ( udp->peer ) ); if ( st_local ) memcpy ( &udp->local, st_local, sizeof ( udp->local ) ); /* Bind to local port */ if ( ! promisc ) { if ( ( rc = udp_bind ( udp ) ) != 0 ) goto err; } /* Attach parent interface, transfer reference to connection * list and return */ xfer_plug_plug ( &udp->xfer, xfer ); list_add ( &udp->list, &udp_conns ); return 0; err: ref_put ( &udp->refcnt ); return rc; } /** * Open a UDP connection * * @v xfer Data transfer interface * @v peer Peer socket address * @v local Local socket address, or NULL * @ret rc Return status code */ int udp_open ( struct xfer_interface *xfer, struct sockaddr *peer, struct sockaddr *local ) { return udp_open_common ( xfer, peer, local, 0 ); } /** * Open a promiscuous UDP connection * * @v xfer Data transfer interface * @ret rc Return status code * * Promiscuous UDP connections are required in order to support the * PXE API. */ int udp_open_promisc ( struct xfer_interface *xfer ) { return udp_open_common ( xfer, NULL, NULL, 1 ); } /** * Close a UDP connection * * @v udp UDP connection * @v rc Reason for close */ static void udp_close ( struct udp_connection *udp, int rc ) { /* Close data transfer interface */ xfer_nullify ( &udp->xfer ); xfer_close ( &udp->xfer, rc ); /* Remove from list of connections and drop list's reference */ list_del ( &udp->list ); ref_put ( &udp->refcnt ); DBGC ( udp, "UDP %p closed\n", udp ); } /** * Transmit data via a UDP connection to a specified address * * @v udp UDP connection * @v iobuf I/O buffer * @v src Source address, or NULL to use default * @v dest Destination address, or NULL to use default * @v netdev Network device, or NULL to use default * @ret rc Return status code */ static int udp_tx ( struct udp_connection *udp, struct io_buffer *iobuf, struct sockaddr_tcpip *src, struct sockaddr_tcpip *dest, struct net_device *netdev ) { struct udp_header *udphdr; size_t len; int rc; /* Check we can accommodate the header */ if ( ( rc = iob_ensure_headroom ( iobuf, UDP_MAX_HLEN ) ) != 0 ) { free_iob ( iobuf ); return rc; } /* Fill in default values if not explicitly provided */ if ( ! src ) src = &udp->local; if ( ! dest ) dest = &udp->peer; /* Add the UDP header */ udphdr = iob_push ( iobuf, sizeof ( *udphdr ) ); len = iob_len ( iobuf ); udphdr->dest = dest->st_port; udphdr->src = src->st_port; udphdr->len = htons ( len ); udphdr->chksum = 0; udphdr->chksum = tcpip_chksum ( udphdr, len ); /* Dump debugging information */ DBGC ( udp, "UDP %p TX %d->%d len %d\n", udp, ntohs ( udphdr->src ), ntohs ( udphdr->dest ), ntohs ( udphdr->len ) ); /* Send it to the next layer for processing */ if ( ( rc = tcpip_tx ( iobuf, &udp_protocol, src, dest, netdev, &udphdr->chksum ) ) != 0 ) { DBGC ( udp, "UDP %p could not transmit packet: %s\n", udp, strerror ( rc ) ); return rc; } return 0; } /** * Identify UDP connection by local address * * @v local Local address * @ret udp UDP connection, or NULL */ static struct udp_connection * udp_demux ( struct sockaddr_tcpip *local ) { static const struct sockaddr_tcpip empty_sockaddr = { .pad = { 0, } }; struct udp_connection *udp; list_for_each_entry ( udp, &udp_conns, list ) { if ( ( ( udp->local.st_family == local->st_family ) || ( udp->local.st_family == 0 ) ) && ( ( udp->local.st_port == local->st_port ) || ( udp->local.st_port == 0 ) ) && ( ( memcmp ( udp->local.pad, local->pad, sizeof ( udp->local.pad ) ) == 0 ) || ( memcmp ( udp->local.pad, empty_sockaddr.pad, sizeof ( udp->local.pad ) ) == 0 ) ) ) { return udp; } } return NULL; } /** * Process a received packet * * @v iobuf I/O buffer * @v st_src Partially-filled source address * @v st_dest Partially-filled destination address * @v pshdr_csum Pseudo-header checksum * @ret rc Return status code */ static int udp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ) { struct udp_header *udphdr = iobuf->data; struct udp_connection *udp; struct xfer_metadata meta; size_t ulen; unsigned int csum; int rc = 0; /* Sanity check packet */ if ( iob_len ( iobuf ) < sizeof ( *udphdr ) ) { DBG ( "UDP packet too short at %zd bytes (min %zd bytes)\n", iob_len ( iobuf ), sizeof ( *udphdr ) ); rc = -EINVAL; goto done; } ulen = ntohs ( udphdr->len ); if ( ulen < sizeof ( *udphdr ) ) { DBG ( "UDP length too short at %zd bytes " "(header is %zd bytes)\n", ulen, sizeof ( *udphdr ) ); rc = -EINVAL; goto done; } if ( ulen > iob_len ( iobuf ) ) { DBG ( "UDP length too long at %zd bytes (packet is %zd " "bytes)\n", ulen, iob_len ( iobuf ) ); rc = -EINVAL; goto done; } if ( udphdr->chksum ) { csum = tcpip_continue_chksum ( pshdr_csum, iobuf->data, ulen ); if ( csum != 0 ) { DBG ( "UDP checksum incorrect (is %04x including " "checksum field, should be 0000)\n", csum ); rc = -EINVAL; goto done; } } /* Parse parameters from header and strip header */ st_src->st_port = udphdr->src; st_dest->st_port = udphdr->dest; udp = udp_demux ( st_dest ); iob_unput ( iobuf, ( iob_len ( iobuf ) - ulen ) ); iob_pull ( iobuf, sizeof ( *udphdr ) ); /* Dump debugging information */ DBGC ( udp, "UDP %p RX %d<-%d len %zd\n", udp, ntohs ( udphdr->dest ), ntohs ( udphdr->src ), ulen ); /* Ignore if no matching connection found */ if ( ! udp ) { DBG ( "No UDP connection listening on port %d\n", ntohs ( udphdr->dest ) ); rc = -ENOTCONN; goto done; } /* Pass data to application */ memset ( &meta, 0, sizeof ( meta ) ); meta.src = ( struct sockaddr * ) st_src; meta.dest = ( struct sockaddr * ) st_dest; rc = xfer_deliver_iob_meta ( &udp->xfer, iob_disown ( iobuf ), &meta ); done: free_iob ( iobuf ); return rc; } struct tcpip_protocol udp_protocol __tcpip_protocol = { .name = "UDP", .rx = udp_rx, .tcpip_proto = IP_UDP, }; /*************************************************************************** * * Data transfer interface * *************************************************************************** */ /** * Close interface * * @v xfer Data transfer interface * @v rc Reason for close */ static void udp_xfer_close ( struct xfer_interface *xfer, int rc ) { struct udp_connection *udp = container_of ( xfer, struct udp_connection, xfer ); /* Close connection */ udp_close ( udp, rc ); } /** * Allocate I/O buffer for UDP * * @v xfer Data transfer interface * @v len Payload size * @ret iobuf I/O buffer, or NULL */ static struct io_buffer * udp_alloc_iob ( struct xfer_interface *xfer, size_t len ) { struct udp_connection *udp = container_of ( xfer, struct udp_connection, xfer ); struct io_buffer *iobuf; iobuf = alloc_iob ( UDP_MAX_HLEN + len ); if ( ! iobuf ) { DBGC ( udp, "UDP %p cannot allocate buffer of length %zd\n", udp, len ); return NULL; } iob_reserve ( iobuf, UDP_MAX_HLEN ); return iobuf; } /** * Deliver datagram as I/O buffer * * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ static int udp_xfer_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta ) { struct udp_connection *udp = container_of ( xfer, struct udp_connection, xfer ); /* Transmit data, if possible */ udp_tx ( udp, iobuf, ( ( struct sockaddr_tcpip * ) meta->src ), ( ( struct sockaddr_tcpip * ) meta->dest ), meta->netdev ); return 0; } /** UDP data transfer interface operations */ static struct xfer_interface_operations udp_xfer_operations = { .close = udp_xfer_close, .vredirect = ignore_xfer_vredirect, .window = unlimited_xfer_window, .alloc_iob = udp_alloc_iob, .deliver_iob = udp_xfer_deliver_iob, .deliver_raw = xfer_deliver_as_iob, }; /*************************************************************************** * * Openers * *************************************************************************** */ /** UDP socket opener */ struct socket_opener udp_socket_opener __socket_opener = { .semantics = UDP_SOCK_DGRAM, .family = AF_INET, .open = udp_open, }; /** Linkage hack */ int udp_sock_dgram = UDP_SOCK_DGRAM; /** * Open UDP URI * * @v xfer Data transfer interface * @v uri URI * @ret rc Return status code */ static int udp_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { struct sockaddr_tcpip peer; /* Sanity check */ if ( ! uri->host ) return -EINVAL; memset ( &peer, 0, sizeof ( peer ) ); peer.st_port = htons ( uri_port ( uri, 0 ) ); return xfer_open_named_socket ( xfer, SOCK_DGRAM, ( struct sockaddr * ) &peer, uri->host, NULL ); } /** UDP URI opener */ struct uri_opener udp_uri_opener __uri_opener = { .scheme = "udp", .open = udp_open_uri, }; debian/grub-extras/disabled/gpxe/src/net/rarp.c0000664000000000000000000000340412524662415016642 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include /** @file * * Reverse Address Resolution Protocol * */ /** * Process incoming ARP packets * * @v iobuf I/O buffer * @v netdev Network device * @v ll_source Link-layer source address * @ret rc Return status code * * This is a dummy method which simply discards RARP packets. */ static int rarp_rx ( struct io_buffer *iobuf, struct net_device *netdev __unused, const void *ll_source __unused ) { free_iob ( iobuf ); return 0; } /** * Transcribe RARP address * * @v net_addr RARP address * @ret string "" * * This operation is meaningless for the RARP protocol. */ static const char * rarp_ntoa ( const void *net_addr __unused ) { return ""; } /** RARP protocol */ struct net_protocol rarp_protocol __net_protocol = { .name = "RARP", .net_proto = htons ( ETH_P_RARP ), .rx = rarp_rx, .ntoa = rarp_ntoa, }; debian/grub-extras/disabled/gpxe/src/net/netdev_settings.c0000664000000000000000000000556012524662415021110 0ustar /* * Copyright (C) 2008 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include /** @file * * Network device configuration settings * */ /** Network device named settings */ struct setting mac_setting __setting = { .name = "mac", .description = "MAC address", .type = &setting_type_hex, }; /** * Store value of network device setting * * @v settings Settings block * @v setting Setting to store * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ static int netdev_store ( struct settings *settings, struct setting *setting, const void *data, size_t len ) { struct net_device *netdev = container_of ( settings, struct net_device, settings.settings ); if ( setting_cmp ( setting, &mac_setting ) == 0 ) { if ( len != netdev->ll_protocol->ll_addr_len ) return -EINVAL; memcpy ( netdev->ll_addr, data, len ); return 0; } return generic_settings_store ( settings, setting, data, len ); } /** * Fetch value of network device setting * * @v settings Settings block * @v setting Setting to fetch * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ static int netdev_fetch ( struct settings *settings, struct setting *setting, void *data, size_t len ) { struct net_device *netdev = container_of ( settings, struct net_device, settings.settings ); if ( setting_cmp ( setting, &mac_setting ) == 0 ) { if ( len > netdev->ll_protocol->ll_addr_len ) len = netdev->ll_protocol->ll_addr_len; memcpy ( data, netdev->ll_addr, len ); return netdev->ll_protocol->ll_addr_len; } return generic_settings_fetch ( settings, setting, data, len ); } /** * Clear network device settings * * @v settings Settings block */ static void netdev_clear ( struct settings *settings ) { generic_settings_clear ( settings ); } /** Network device configuration settings operations */ struct settings_operations netdev_settings_operations = { .store = netdev_store, .fetch = netdev_fetch, .clear = netdev_clear, }; debian/grub-extras/disabled/gpxe/src/net/ethernet.c0000664000000000000000000001130412524662415017512 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * Ethernet protocol * */ /** Ethernet broadcast MAC address */ static uint8_t eth_broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /** * Add Ethernet link-layer header * * @v netdev Network device * @v iobuf I/O buffer * @v ll_dest Link-layer destination address * @v ll_source Source link-layer address * @v net_proto Network-layer protocol, in network-byte order * @ret rc Return status code */ static int eth_push ( struct net_device *netdev __unused, struct io_buffer *iobuf, const void *ll_dest, const void *ll_source, uint16_t net_proto ) { struct ethhdr *ethhdr = iob_push ( iobuf, sizeof ( *ethhdr ) ); /* Build Ethernet header */ memcpy ( ethhdr->h_dest, ll_dest, ETH_ALEN ); memcpy ( ethhdr->h_source, ll_source, ETH_ALEN ); ethhdr->h_protocol = net_proto; return 0; } /** * Remove Ethernet link-layer header * * @v netdev Network device * @v iobuf I/O buffer * @ret ll_dest Link-layer destination address * @ret ll_source Source link-layer address * @ret net_proto Network-layer protocol, in network-byte order * @ret rc Return status code */ static int eth_pull ( struct net_device *netdev __unused, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t *net_proto ) { struct ethhdr *ethhdr = iobuf->data; /* Sanity check */ if ( iob_len ( iobuf ) < sizeof ( *ethhdr ) ) { DBG ( "Ethernet packet too short (%zd bytes)\n", iob_len ( iobuf ) ); return -EINVAL; } /* Strip off Ethernet header */ iob_pull ( iobuf, sizeof ( *ethhdr ) ); /* Fill in required fields */ *ll_dest = ethhdr->h_dest; *ll_source = ethhdr->h_source; *net_proto = ethhdr->h_protocol; return 0; } /** * Initialise Ethernet address * * @v hw_addr Hardware address * @v ll_addr Link-layer address */ void eth_init_addr ( const void *hw_addr, void *ll_addr ) { memcpy ( ll_addr, hw_addr, ETH_ALEN ); } /** * Transcribe Ethernet address * * @v ll_addr Link-layer address * @ret string Link-layer address in human-readable format */ const char * eth_ntoa ( const void *ll_addr ) { static char buf[18]; /* "00:00:00:00:00:00" */ const uint8_t *eth_addr = ll_addr; snprintf ( buf, sizeof (buf), "%02x:%02x:%02x:%02x:%02x:%02x", eth_addr[0], eth_addr[1], eth_addr[2], eth_addr[3], eth_addr[4], eth_addr[5] ); return buf; } /** * Hash multicast address * * @v af Address family * @v net_addr Network-layer address * @v ll_addr Link-layer address to fill in * @ret rc Return status code */ int eth_mc_hash ( unsigned int af, const void *net_addr, void *ll_addr ) { const uint8_t *net_addr_bytes = net_addr; uint8_t *ll_addr_bytes = ll_addr; switch ( af ) { case AF_INET: ll_addr_bytes[0] = 0x01; ll_addr_bytes[1] = 0x00; ll_addr_bytes[2] = 0x5e; ll_addr_bytes[3] = net_addr_bytes[1] & 0x7f; ll_addr_bytes[4] = net_addr_bytes[2]; ll_addr_bytes[5] = net_addr_bytes[3]; return 0; default: return -ENOTSUP; } } /** Ethernet protocol */ struct ll_protocol ethernet_protocol __ll_protocol = { .name = "Ethernet", .ll_proto = htons ( ARPHRD_ETHER ), .hw_addr_len = ETH_ALEN, .ll_addr_len = ETH_ALEN, .ll_header_len = ETH_HLEN, .push = eth_push, .pull = eth_pull, .init_addr = eth_init_addr, .ntoa = eth_ntoa, .mc_hash = eth_mc_hash, }; /** * Allocate Ethernet device * * @v priv_size Size of driver private data * @ret netdev Network device, or NULL */ struct net_device * alloc_etherdev ( size_t priv_size ) { struct net_device *netdev; netdev = alloc_netdev ( priv_size ); if ( netdev ) { netdev->ll_protocol = ðernet_protocol; netdev->ll_broadcast = eth_broadcast; netdev->max_pkt_len = ETH_FRAME_LEN; } return netdev; } debian/grub-extras/disabled/gpxe/src/net/dhcppkt.c0000664000000000000000000001730512524662415017340 0ustar /* * Copyright (C) 2008 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include /** @file * * DHCP packets * */ /**************************************************************************** * * DHCP packet raw interface * */ /** * Calculate used length of an IPv4 field within a DHCP packet * * @v data Field data * @v len Length of field * @ret used Used length of field */ static size_t used_len_ipv4 ( const void *data, size_t len __unused ) { const struct in_addr *in = data; return ( in->s_addr ? sizeof ( *in ) : 0 ); } /** * Calculate used length of a string field within a DHCP packet * * @v data Field data * @v len Length of field * @ret used Used length of field */ static size_t used_len_string ( const void *data, size_t len ) { return strnlen ( data, len ); } /** A dedicated field within a DHCP packet */ struct dhcp_packet_field { /** Settings tag number */ unsigned int tag; /** Offset within DHCP packet */ uint16_t offset; /** Length of field */ uint16_t len; /** Calculate used length of field * * @v data Field data * @v len Length of field * @ret used Used length of field */ size_t ( * used_len ) ( const void *data, size_t len ); }; /** Declare a dedicated field within a DHCP packet * * @v _tag Settings tag number * @v _field Field name * @v _used_len Function to calculate used length of field */ #define DHCP_PACKET_FIELD( _tag, _field, _used_len ) { \ .tag = (_tag), \ .offset = offsetof ( struct dhcphdr, _field ), \ .len = sizeof ( ( ( struct dhcphdr * ) 0 )->_field ), \ .used_len = _used_len, \ } /** Dedicated fields within a DHCP packet */ static struct dhcp_packet_field dhcp_packet_fields[] = { DHCP_PACKET_FIELD ( DHCP_EB_YIADDR, yiaddr, used_len_ipv4 ), DHCP_PACKET_FIELD ( DHCP_EB_SIADDR, siaddr, used_len_ipv4 ), DHCP_PACKET_FIELD ( DHCP_TFTP_SERVER_NAME, sname, used_len_string ), DHCP_PACKET_FIELD ( DHCP_BOOTFILE_NAME, file, used_len_string ), }; /** * Get address of a DHCP packet field * * @v dhcphdr DHCP packet header * @v field DHCP packet field * @ret data Packet field data */ static inline void * dhcp_packet_field ( struct dhcphdr *dhcphdr, struct dhcp_packet_field *field ) { return ( ( ( void * ) dhcphdr ) + field->offset ); } /** * Find DHCP packet field corresponding to settings tag number * * @v tag Settings tag number * @ret field DHCP packet field, or NULL */ static struct dhcp_packet_field * find_dhcp_packet_field ( unsigned int tag ) { struct dhcp_packet_field *field; unsigned int i; for ( i = 0 ; i < ( sizeof ( dhcp_packet_fields ) / sizeof ( dhcp_packet_fields[0] ) ) ; i++ ) { field = &dhcp_packet_fields[i]; if ( field->tag == tag ) return field; } return NULL; } /** * Store value of DHCP packet setting * * @v dhcppkt DHCP packet * @v tag Setting tag number * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ int dhcppkt_store ( struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len ) { struct dhcp_packet_field *field; void *field_data; int rc; /* If this is a special field, fill it in */ if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) { if ( len > field->len ) return -ENOSPC; field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field ); memset ( field_data, 0, field->len ); memcpy ( dhcp_packet_field ( dhcppkt->dhcphdr, field ), data, len ); /* Erase any equivalent option from the options block */ dhcpopt_store ( &dhcppkt->options, tag, NULL, 0 ); return 0; } /* Otherwise, use the generic options block */ rc = dhcpopt_store ( &dhcppkt->options, tag, data, len ); /* Update our used-length field */ dhcppkt->len = ( offsetof ( struct dhcphdr, options ) + dhcppkt->options.len ); return rc; } /** * Fetch value of DHCP packet setting * * @v dhcppkt DHCP packet * @v tag Setting tag number * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error */ int dhcppkt_fetch ( struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len ) { struct dhcp_packet_field *field; void *field_data; size_t field_len = 0; /* Identify special field, if any */ if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) { field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field ); field_len = field->used_len ( field_data, field->len ); } /* Return special field, if it exists and is populated */ if ( field_len ) { if ( len > field_len ) len = field_len; memcpy ( data, field_data, len ); return field_len; } /* Otherwise, use the generic options block */ return dhcpopt_fetch ( &dhcppkt->options, tag, data, len ); } /**************************************************************************** * * DHCP packet settings interface * */ /** * Store value of DHCP setting * * @v settings Settings block * @v setting Setting to store * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ static int dhcppkt_settings_store ( struct settings *settings, struct setting *setting, const void *data, size_t len ) { struct dhcp_packet *dhcppkt = container_of ( settings, struct dhcp_packet, settings ); return dhcppkt_store ( dhcppkt, setting->tag, data, len ); } /** * Fetch value of DHCP setting * * @v settings Settings block, or NULL to search all blocks * @v setting Setting to fetch * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error */ static int dhcppkt_settings_fetch ( struct settings *settings, struct setting *setting, void *data, size_t len ) { struct dhcp_packet *dhcppkt = container_of ( settings, struct dhcp_packet, settings ); return dhcppkt_fetch ( dhcppkt, setting->tag, data, len ); } /** DHCP settings operations */ static struct settings_operations dhcppkt_settings_operations = { .store = dhcppkt_settings_store, .fetch = dhcppkt_settings_fetch, }; /**************************************************************************** * * Constructor * */ /** * Initialise DHCP packet * * @v dhcppkt DHCP packet structure to fill in * @v data DHCP packet raw data * @v max_len Length of raw data buffer * * Initialise a DHCP packet structure from a data buffer containing a * DHCP packet. */ void dhcppkt_init ( struct dhcp_packet *dhcppkt, struct dhcphdr *data, size_t len ) { dhcppkt->dhcphdr = data; dhcppkt->max_len = len; dhcpopt_init ( &dhcppkt->options, &dhcppkt->dhcphdr->options, ( len - offsetof ( struct dhcphdr, options ) ) ); dhcppkt->len = ( offsetof ( struct dhcphdr, options ) + dhcppkt->options.len ); settings_init ( &dhcppkt->settings, &dhcppkt_settings_operations, &dhcppkt->refcnt, DHCP_SETTINGS_NAME, 0 ); } debian/grub-extras/disabled/gpxe/src/net/nullnet.c0000664000000000000000000000306612524662415017363 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include /** @file * * Null network device * */ static int null_open ( struct net_device *netdev __unused ) { return -ENODEV; }; static void null_close ( struct net_device *netdev __unused ) { /* Do nothing */ }; static int null_transmit ( struct net_device *netdev __unused, struct io_buffer *iobuf __unused ) { return -ENODEV; }; static void null_poll ( struct net_device *netdev __unused ) { /* Do nothing */ } static void null_irq ( struct net_device *netdev __unused, int enable __unused ) { /* Do nothing */ } struct net_device_operations null_netdev_operations = { .open = null_open, .close = null_close, .transmit = null_transmit, .poll = null_poll, .irq = null_irq, }; debian/grub-extras/disabled/gpxe/src/net/ipv4.c0000664000000000000000000004257012524662415016567 0ustar #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * IPv4 protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); /* Unique IP datagram identification number */ static uint16_t next_ident = 0; struct net_protocol ipv4_protocol; /** List of IPv4 miniroutes */ struct list_head ipv4_miniroutes = LIST_HEAD_INIT ( ipv4_miniroutes ); /** List of fragment reassembly buffers */ static LIST_HEAD ( frag_buffers ); /** * Add IPv4 minirouting table entry * * @v netdev Network device * @v address IPv4 address * @v netmask Subnet mask * @v gateway Gateway address (or @c INADDR_NONE for no gateway) * @ret miniroute Routing table entry, or NULL */ static struct ipv4_miniroute * __malloc add_ipv4_miniroute ( struct net_device *netdev, struct in_addr address, struct in_addr netmask, struct in_addr gateway ) { struct ipv4_miniroute *miniroute; DBG ( "IPv4 add %s", inet_ntoa ( address ) ); DBG ( "/%s ", inet_ntoa ( netmask ) ); if ( gateway.s_addr != INADDR_NONE ) DBG ( "gw %s ", inet_ntoa ( gateway ) ); DBG ( "via %s\n", netdev->name ); /* Allocate and populate miniroute structure */ miniroute = malloc ( sizeof ( *miniroute ) ); if ( ! miniroute ) { DBG ( "IPv4 could not add miniroute\n" ); return NULL; } /* Record routing information */ miniroute->netdev = netdev_get ( netdev ); miniroute->address = address; miniroute->netmask = netmask; miniroute->gateway = gateway; /* Add to end of list if we have a gateway, otherwise * to start of list. */ if ( gateway.s_addr != INADDR_NONE ) { list_add_tail ( &miniroute->list, &ipv4_miniroutes ); } else { list_add ( &miniroute->list, &ipv4_miniroutes ); } return miniroute; } /** * Delete IPv4 minirouting table entry * * @v miniroute Routing table entry */ static void del_ipv4_miniroute ( struct ipv4_miniroute *miniroute ) { DBG ( "IPv4 del %s", inet_ntoa ( miniroute->address ) ); DBG ( "/%s ", inet_ntoa ( miniroute->netmask ) ); if ( miniroute->gateway.s_addr != INADDR_NONE ) DBG ( "gw %s ", inet_ntoa ( miniroute->gateway ) ); DBG ( "via %s\n", miniroute->netdev->name ); netdev_put ( miniroute->netdev ); list_del ( &miniroute->list ); free ( miniroute ); } /** * Perform IPv4 routing * * @v dest Final destination address * @ret dest Next hop destination address * @ret miniroute Routing table entry to use, or NULL if no route * * If the route requires use of a gateway, the next hop destination * address will be overwritten with the gateway address. */ static struct ipv4_miniroute * ipv4_route ( struct in_addr *dest ) { struct ipv4_miniroute *miniroute; int local; int has_gw; /* Never attempt to route the broadcast address */ if ( dest->s_addr == INADDR_BROADCAST ) return NULL; /* Find first usable route in routing table */ list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) { local = ( ( ( dest->s_addr ^ miniroute->address.s_addr ) & miniroute->netmask.s_addr ) == 0 ); has_gw = ( miniroute->gateway.s_addr != INADDR_NONE ); if ( local || has_gw ) { if ( ! local ) *dest = miniroute->gateway; return miniroute; } } return NULL; } /** * Fragment reassembly counter timeout * * @v timer Retry timer * @v over If asserted, the timer is greater than @c MAX_TIMEOUT */ static void ipv4_frag_expired ( struct retry_timer *timer __unused, int over ) { if ( over ) { DBG ( "Fragment reassembly timeout" ); /* Free the fragment buffer */ } } /** * Free fragment buffer * * @v fragbug Fragment buffer */ static void free_fragbuf ( struct frag_buffer *fragbuf ) { free ( fragbuf ); } /** * Fragment reassembler * * @v iobuf I/O buffer, fragment of the datagram * @ret frag_iob Reassembled packet, or NULL */ static struct io_buffer * ipv4_reassemble ( struct io_buffer * iobuf ) { struct iphdr *iphdr = iobuf->data; struct frag_buffer *fragbuf; /** * Check if the fragment belongs to any fragment series */ list_for_each_entry ( fragbuf, &frag_buffers, list ) { if ( fragbuf->ident == iphdr->ident && fragbuf->src.s_addr == iphdr->src.s_addr ) { /** * Check if the packet is the expected fragment * * The offset of the new packet must be equal to the * length of the data accumulated so far (the length of * the reassembled I/O buffer */ if ( iob_len ( fragbuf->frag_iob ) == ( iphdr->frags & IP_MASK_OFFSET ) ) { /** * Append the contents of the fragment to the * reassembled I/O buffer */ iob_pull ( iobuf, sizeof ( *iphdr ) ); memcpy ( iob_put ( fragbuf->frag_iob, iob_len ( iobuf ) ), iobuf->data, iob_len ( iobuf ) ); free_iob ( iobuf ); /** Check if the fragment series is over */ if ( ! ( iphdr->frags & IP_MASK_MOREFRAGS ) ) { iobuf = fragbuf->frag_iob; free_fragbuf ( fragbuf ); return iobuf; } } else { /* Discard the fragment series */ free_fragbuf ( fragbuf ); free_iob ( iobuf ); } return NULL; } } /** Check if the fragment is the first in the fragment series */ if ( iphdr->frags & IP_MASK_MOREFRAGS && ( ( iphdr->frags & IP_MASK_OFFSET ) == 0 ) ) { /** Create a new fragment buffer */ fragbuf = ( struct frag_buffer* ) malloc ( sizeof( *fragbuf ) ); fragbuf->ident = iphdr->ident; fragbuf->src = iphdr->src; /* Set up the reassembly I/O buffer */ fragbuf->frag_iob = alloc_iob ( IP_FRAG_IOB_SIZE ); iob_pull ( iobuf, sizeof ( *iphdr ) ); memcpy ( iob_put ( fragbuf->frag_iob, iob_len ( iobuf ) ), iobuf->data, iob_len ( iobuf ) ); free_iob ( iobuf ); /* Set the reassembly timer */ fragbuf->frag_timer.timeout = IP_FRAG_TIMEOUT; fragbuf->frag_timer.expired = ipv4_frag_expired; start_timer ( &fragbuf->frag_timer ); /* Add the fragment buffer to the list of fragment buffers */ list_add ( &fragbuf->list, &frag_buffers ); } return NULL; } /** * Add IPv4 pseudo-header checksum to existing checksum * * @v iobuf I/O buffer * @v csum Existing checksum * @ret csum Updated checksum */ static uint16_t ipv4_pshdr_chksum ( struct io_buffer *iobuf, uint16_t csum ) { struct ipv4_pseudo_header pshdr; struct iphdr *iphdr = iobuf->data; size_t hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 ); /* Build pseudo-header */ pshdr.src = iphdr->src; pshdr.dest = iphdr->dest; pshdr.zero_padding = 0x00; pshdr.protocol = iphdr->protocol; pshdr.len = htons ( iob_len ( iobuf ) - hdrlen ); /* Update the checksum value */ return tcpip_continue_chksum ( csum, &pshdr, sizeof ( pshdr ) ); } /** * Determine link-layer address * * @v dest IPv4 destination address * @v src IPv4 source address * @v netdev Network device * @v ll_dest Link-layer destination address buffer * @ret rc Return status code */ static int ipv4_ll_addr ( struct in_addr dest, struct in_addr src, struct net_device *netdev, uint8_t *ll_dest ) { struct ll_protocol *ll_protocol = netdev->ll_protocol; if ( dest.s_addr == INADDR_BROADCAST ) { /* Broadcast address */ memcpy ( ll_dest, netdev->ll_broadcast, ll_protocol->ll_addr_len ); return 0; } else if ( IN_MULTICAST ( ntohl ( dest.s_addr ) ) ) { return ll_protocol->mc_hash ( AF_INET, &dest, ll_dest ); } else { /* Unicast address: resolve via ARP */ return arp_resolve ( netdev, &ipv4_protocol, &dest, &src, ll_dest ); } } /** * Transmit IP packet * * @v iobuf I/O buffer * @v tcpip Transport-layer protocol * @v st_src Source network-layer address * @v st_dest Destination network-layer address * @v netdev Network device to use if no route found, or NULL * @v trans_csum Transport-layer checksum to complete, or NULL * @ret rc Status * * This function expects a transport-layer segment and prepends the IP header */ static int ipv4_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, struct net_device *netdev, uint16_t *trans_csum ) { struct iphdr *iphdr = iob_push ( iobuf, sizeof ( *iphdr ) ); struct sockaddr_in *sin_src = ( ( struct sockaddr_in * ) st_src ); struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest ); struct ipv4_miniroute *miniroute; struct in_addr next_hop; uint8_t ll_dest[MAX_LL_ADDR_LEN]; int rc; /* Fill up the IP header, except source address */ memset ( iphdr, 0, sizeof ( *iphdr ) ); iphdr->verhdrlen = ( IP_VER | ( sizeof ( *iphdr ) / 4 ) ); iphdr->service = IP_TOS; iphdr->len = htons ( iob_len ( iobuf ) ); iphdr->ident = htons ( ++next_ident ); iphdr->ttl = IP_TTL; iphdr->protocol = tcpip_protocol->tcpip_proto; iphdr->dest = sin_dest->sin_addr; /* Use routing table to identify next hop and transmitting netdev */ next_hop = iphdr->dest; if ( sin_src ) iphdr->src = sin_src->sin_addr; if ( ( next_hop.s_addr != INADDR_BROADCAST ) && ( ! IN_MULTICAST ( ntohl ( next_hop.s_addr ) ) ) && ( ( miniroute = ipv4_route ( &next_hop ) ) != NULL ) ) { iphdr->src = miniroute->address; netdev = miniroute->netdev; } if ( ! netdev ) { DBG ( "IPv4 has no route to %s\n", inet_ntoa ( iphdr->dest ) ); rc = -ENETUNREACH; goto err; } /* Determine link-layer destination address */ if ( ( rc = ipv4_ll_addr ( next_hop, iphdr->src, netdev, ll_dest ) ) != 0 ) { DBG ( "IPv4 has no link-layer address for %s: %s\n", inet_ntoa ( next_hop ), strerror ( rc ) ); goto err; } /* Fix up checksums */ if ( trans_csum ) *trans_csum = ipv4_pshdr_chksum ( iobuf, *trans_csum ); iphdr->chksum = tcpip_chksum ( iphdr, sizeof ( *iphdr ) ); /* Print IP4 header for debugging */ DBG ( "IPv4 TX %s->", inet_ntoa ( iphdr->src ) ); DBG ( "%s len %d proto %d id %04x csum %04x\n", inet_ntoa ( iphdr->dest ), ntohs ( iphdr->len ), iphdr->protocol, ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) ); /* Hand off to link layer */ if ( ( rc = net_tx ( iobuf, netdev, &ipv4_protocol, ll_dest ) ) != 0 ) { DBG ( "IPv4 could not transmit packet via %s: %s\n", netdev->name, strerror ( rc ) ); return rc; } return 0; err: free_iob ( iobuf ); return rc; } /** * Process incoming packets * * @v iobuf I/O buffer * @v netdev Network device * @v ll_source Link-layer destination source * * This function expects an IP4 network datagram. It processes the headers * and sends it to the transport layer. */ static int ipv4_rx ( struct io_buffer *iobuf, struct net_device *netdev __unused, const void *ll_source __unused ) { struct iphdr *iphdr = iobuf->data; size_t hdrlen; size_t len; union { struct sockaddr_in sin; struct sockaddr_tcpip st; } src, dest; uint16_t csum; uint16_t pshdr_csum; int rc; /* Sanity check the IPv4 header */ if ( iob_len ( iobuf ) < sizeof ( *iphdr ) ) { DBG ( "IPv4 packet too short at %zd bytes (min %zd bytes)\n", iob_len ( iobuf ), sizeof ( *iphdr ) ); goto err; } if ( ( iphdr->verhdrlen & IP_MASK_VER ) != IP_VER ) { DBG ( "IPv4 version %#02x not supported\n", iphdr->verhdrlen ); goto err; } hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 ); if ( hdrlen < sizeof ( *iphdr ) ) { DBG ( "IPv4 header too short at %zd bytes (min %zd bytes)\n", hdrlen, sizeof ( *iphdr ) ); goto err; } if ( hdrlen > iob_len ( iobuf ) ) { DBG ( "IPv4 header too long at %zd bytes " "(packet is %zd bytes)\n", hdrlen, iob_len ( iobuf ) ); goto err; } if ( ( csum = tcpip_chksum ( iphdr, hdrlen ) ) != 0 ) { DBG ( "IPv4 checksum incorrect (is %04x including checksum " "field, should be 0000)\n", csum ); goto err; } len = ntohs ( iphdr->len ); if ( len < hdrlen ) { DBG ( "IPv4 length too short at %zd bytes " "(header is %zd bytes)\n", len, hdrlen ); goto err; } if ( len > iob_len ( iobuf ) ) { DBG ( "IPv4 length too long at %zd bytes " "(packet is %zd bytes)\n", len, iob_len ( iobuf ) ); goto err; } /* Print IPv4 header for debugging */ DBG ( "IPv4 RX %s<-", inet_ntoa ( iphdr->dest ) ); DBG ( "%s len %d proto %d id %04x csum %04x\n", inet_ntoa ( iphdr->src ), ntohs ( iphdr->len ), iphdr->protocol, ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) ); /* Truncate packet to correct length, calculate pseudo-header * checksum and then strip off the IPv4 header. */ iob_unput ( iobuf, ( iob_len ( iobuf ) - len ) ); pshdr_csum = ipv4_pshdr_chksum ( iobuf, TCPIP_EMPTY_CSUM ); iob_pull ( iobuf, hdrlen ); /* Fragment reassembly */ if ( ( iphdr->frags & htons ( IP_MASK_MOREFRAGS ) ) || ( ( iphdr->frags & htons ( IP_MASK_OFFSET ) ) != 0 ) ) { /* Pass the fragment to ipv4_reassemble() which either * returns a fully reassembled I/O buffer or NULL. */ iobuf = ipv4_reassemble ( iobuf ); if ( ! iobuf ) return 0; } /* Construct socket addresses and hand off to transport layer */ memset ( &src, 0, sizeof ( src ) ); src.sin.sin_family = AF_INET; src.sin.sin_addr = iphdr->src; memset ( &dest, 0, sizeof ( dest ) ); dest.sin.sin_family = AF_INET; dest.sin.sin_addr = iphdr->dest; if ( ( rc = tcpip_rx ( iobuf, iphdr->protocol, &src.st, &dest.st, pshdr_csum ) ) != 0 ) { DBG ( "IPv4 received packet rejected by stack: %s\n", strerror ( rc ) ); return rc; } return 0; err: free_iob ( iobuf ); return -EINVAL; } /** * Check existence of IPv4 address for ARP * * @v netdev Network device * @v net_addr Network-layer address * @ret rc Return status code */ static int ipv4_arp_check ( struct net_device *netdev, const void *net_addr ) { const struct in_addr *address = net_addr; struct ipv4_miniroute *miniroute; list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) { if ( ( miniroute->netdev == netdev ) && ( miniroute->address.s_addr == address->s_addr ) ) { /* Found matching address */ return 0; } } return -ENOENT; } /** * Convert IPv4 address to dotted-quad notation * * @v in IP address * @ret string IP address in dotted-quad notation */ char * inet_ntoa ( struct in_addr in ) { static char buf[16]; /* "xxx.xxx.xxx.xxx" */ uint8_t *bytes = ( uint8_t * ) ∈ snprintf ( buf, sizeof (buf), "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] ); return buf; } /** * Transcribe IP address * * @v net_addr IP address * @ret string IP address in dotted-quad notation * */ static const char * ipv4_ntoa ( const void *net_addr ) { return inet_ntoa ( * ( ( struct in_addr * ) net_addr ) ); } /** IPv4 protocol */ struct net_protocol ipv4_protocol __net_protocol = { .name = "IP", .net_proto = htons ( ETH_P_IP ), .net_addr_len = sizeof ( struct in_addr ), .rx = ipv4_rx, .ntoa = ipv4_ntoa, }; /** IPv4 TCPIP net protocol */ struct tcpip_net_protocol ipv4_tcpip_protocol __tcpip_net_protocol = { .name = "IPv4", .sa_family = AF_INET, .tx = ipv4_tx, }; /** IPv4 ARP protocol */ struct arp_net_protocol ipv4_arp_protocol __arp_net_protocol = { .net_protocol = &ipv4_protocol, .check = ipv4_arp_check, }; /****************************************************************************** * * Settings * ****************************************************************************** */ /** IPv4 address setting */ struct setting ip_setting __setting = { .name = "ip", .description = "IPv4 address", .tag = DHCP_EB_YIADDR, .type = &setting_type_ipv4, }; /** IPv4 subnet mask setting */ struct setting netmask_setting __setting = { .name = "netmask", .description = "IPv4 subnet mask", .tag = DHCP_SUBNET_MASK, .type = &setting_type_ipv4, }; /** Default gateway setting */ struct setting gateway_setting __setting = { .name = "gateway", .description = "Default gateway", .tag = DHCP_ROUTERS, .type = &setting_type_ipv4, }; /** * Create IPv4 routing table based on configured settings * * @ret rc Return status code */ static int ipv4_create_routes ( void ) { struct ipv4_miniroute *miniroute; struct ipv4_miniroute *tmp; struct net_device *netdev; struct settings *settings; struct in_addr address = { 0 }; struct in_addr netmask = { 0 }; struct in_addr gateway = { INADDR_NONE }; /* Delete all existing routes */ list_for_each_entry_safe ( miniroute, tmp, &ipv4_miniroutes, list ) del_ipv4_miniroute ( miniroute ); /* Create a route for each configured network device */ for_each_netdev ( netdev ) { settings = netdev_settings ( netdev ); /* Get IPv4 address */ address.s_addr = 0; fetch_ipv4_setting ( settings, &ip_setting, &address ); if ( ! address.s_addr ) continue; /* Calculate default netmask */ if ( IN_CLASSA ( ntohl ( address.s_addr ) ) ) { netmask.s_addr = htonl ( IN_CLASSA_NET ); } else if ( IN_CLASSB ( ntohl ( address.s_addr ) ) ) { netmask.s_addr = htonl ( IN_CLASSB_NET ); } else if ( IN_CLASSC ( ntohl ( address.s_addr ) ) ) { netmask.s_addr = htonl ( IN_CLASSC_NET ); } else { netmask.s_addr = 0; } /* Override with subnet mask, if present */ fetch_ipv4_setting ( settings, &netmask_setting, &netmask ); /* Get default gateway, if present */ gateway.s_addr = INADDR_NONE; fetch_ipv4_setting ( settings, &gateway_setting, &gateway ); /* Configure route */ miniroute = add_ipv4_miniroute ( netdev, address, netmask, gateway ); if ( ! miniroute ) return -ENOMEM; } return 0; } /** IPv4 settings applicator */ struct settings_applicator ipv4_settings_applicator __settings_applicator = { .apply = ipv4_create_routes, }; /* Drag in ICMP */ REQUIRE_OBJECT ( icmp ); debian/grub-extras/disabled/gpxe/src/net/tls.c0000664000000000000000000013672512524662415016515 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); /** * @file * * Transport Layer Security Protocol */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int tls_send_plaintext ( struct tls_session *tls, unsigned int type, const void *data, size_t len ); static void tls_clear_cipher ( struct tls_session *tls, struct tls_cipherspec *cipherspec ); /****************************************************************************** * * Utility functions * ****************************************************************************** */ /** * Extract 24-bit field value * * @v field24 24-bit field * @ret value Field value * * TLS uses 24-bit integers in several places, which are awkward to * parse in C. */ static unsigned long tls_uint24 ( uint8_t field24[3] ) { return ( ( field24[0] << 16 ) + ( field24[1] << 8 ) + field24[2] ); } /****************************************************************************** * * Cleanup functions * ****************************************************************************** */ /** * Free TLS session * * @v refcnt Reference counter */ static void free_tls ( struct refcnt *refcnt ) { struct tls_session *tls = container_of ( refcnt, struct tls_session, refcnt ); /* Free dynamically-allocated resources */ tls_clear_cipher ( tls, &tls->tx_cipherspec ); tls_clear_cipher ( tls, &tls->tx_cipherspec_pending ); tls_clear_cipher ( tls, &tls->rx_cipherspec ); tls_clear_cipher ( tls, &tls->rx_cipherspec_pending ); x509_free_rsa_public_key ( &tls->rsa ); free ( tls->rx_data ); /* Free TLS structure itself */ free ( tls ); } /** * Finish with TLS session * * @v tls TLS session * @v rc Status code */ static void tls_close ( struct tls_session *tls, int rc ) { /* Remove process */ process_del ( &tls->process ); /* Close ciphertext and plaintext streams */ xfer_nullify ( &tls->cipherstream.xfer ); xfer_close ( &tls->cipherstream.xfer, rc ); xfer_nullify ( &tls->plainstream.xfer ); xfer_close ( &tls->plainstream.xfer, rc ); } /****************************************************************************** * * Random number generation * ****************************************************************************** */ /** * Generate random data * * @v data Buffer to fill * @v len Length of buffer */ static void tls_generate_random ( void *data, size_t len ) { /* FIXME: Some real random data source would be nice... */ memset ( data, 0x01, len ); } /** * Update HMAC with a list of ( data, len ) pairs * * @v digest Hash function to use * @v digest_ctx Digest context * @v args ( data, len ) pairs of data, terminated by NULL */ static void tls_hmac_update_va ( struct digest_algorithm *digest, void *digest_ctx, va_list args ) { void *data; size_t len; while ( ( data = va_arg ( args, void * ) ) ) { len = va_arg ( args, size_t ); hmac_update ( digest, digest_ctx, data, len ); } } /** * Generate secure pseudo-random data using a single hash function * * @v tls TLS session * @v digest Hash function to use * @v secret Secret * @v secret_len Length of secret * @v out Output buffer * @v out_len Length of output buffer * @v seeds ( data, len ) pairs of seed data, terminated by NULL */ static void tls_p_hash_va ( struct tls_session *tls, struct digest_algorithm *digest, void *secret, size_t secret_len, void *out, size_t out_len, va_list seeds ) { uint8_t secret_copy[secret_len]; uint8_t digest_ctx[digest->ctxsize]; uint8_t digest_ctx_partial[digest->ctxsize]; uint8_t a[digest->digestsize]; uint8_t out_tmp[digest->digestsize]; size_t frag_len = digest->digestsize; va_list tmp; /* Copy the secret, in case HMAC modifies it */ memcpy ( secret_copy, secret, secret_len ); secret = secret_copy; DBGC2 ( tls, "TLS %p %s secret:\n", tls, digest->name ); DBGC2_HD ( tls, secret, secret_len ); /* Calculate A(1) */ hmac_init ( digest, digest_ctx, secret, &secret_len ); va_copy ( tmp, seeds ); tls_hmac_update_va ( digest, digest_ctx, tmp ); va_end ( tmp ); hmac_final ( digest, digest_ctx, secret, &secret_len, a ); DBGC2 ( tls, "TLS %p %s A(1):\n", tls, digest->name ); DBGC2_HD ( tls, &a, sizeof ( a ) ); /* Generate as much data as required */ while ( out_len ) { /* Calculate output portion */ hmac_init ( digest, digest_ctx, secret, &secret_len ); hmac_update ( digest, digest_ctx, a, sizeof ( a ) ); memcpy ( digest_ctx_partial, digest_ctx, digest->ctxsize ); va_copy ( tmp, seeds ); tls_hmac_update_va ( digest, digest_ctx, tmp ); va_end ( tmp ); hmac_final ( digest, digest_ctx, secret, &secret_len, out_tmp ); /* Copy output */ if ( frag_len > out_len ) frag_len = out_len; memcpy ( out, out_tmp, frag_len ); DBGC2 ( tls, "TLS %p %s output:\n", tls, digest->name ); DBGC2_HD ( tls, out, frag_len ); /* Calculate A(i) */ hmac_final ( digest, digest_ctx_partial, secret, &secret_len, a ); DBGC2 ( tls, "TLS %p %s A(n):\n", tls, digest->name ); DBGC2_HD ( tls, &a, sizeof ( a ) ); out += frag_len; out_len -= frag_len; } } /** * Generate secure pseudo-random data * * @v tls TLS session * @v secret Secret * @v secret_len Length of secret * @v out Output buffer * @v out_len Length of output buffer * @v ... ( data, len ) pairs of seed data, terminated by NULL */ static void tls_prf ( struct tls_session *tls, void *secret, size_t secret_len, void *out, size_t out_len, ... ) { va_list seeds; va_list tmp; size_t subsecret_len; void *md5_secret; void *sha1_secret; uint8_t out_md5[out_len]; uint8_t out_sha1[out_len]; unsigned int i; va_start ( seeds, out_len ); /* Split secret into two, with an overlap of up to one byte */ subsecret_len = ( ( secret_len + 1 ) / 2 ); md5_secret = secret; sha1_secret = ( secret + secret_len - subsecret_len ); /* Calculate MD5 portion */ va_copy ( tmp, seeds ); tls_p_hash_va ( tls, &md5_algorithm, md5_secret, subsecret_len, out_md5, out_len, seeds ); va_end ( tmp ); /* Calculate SHA1 portion */ va_copy ( tmp, seeds ); tls_p_hash_va ( tls, &sha1_algorithm, sha1_secret, subsecret_len, out_sha1, out_len, seeds ); va_end ( tmp ); /* XOR the two portions together into the final output buffer */ for ( i = 0 ; i < out_len ; i++ ) { *( ( uint8_t * ) out + i ) = ( out_md5[i] ^ out_sha1[i] ); } va_end ( seeds ); } /** * Generate secure pseudo-random data * * @v secret Secret * @v secret_len Length of secret * @v out Output buffer * @v out_len Length of output buffer * @v label String literal label * @v ... ( data, len ) pairs of seed data */ #define tls_prf_label( tls, secret, secret_len, out, out_len, label, ... ) \ tls_prf ( (tls), (secret), (secret_len), (out), (out_len), \ label, ( sizeof ( label ) - 1 ), __VA_ARGS__, NULL ) /****************************************************************************** * * Secret management * ****************************************************************************** */ /** * Generate master secret * * @v tls TLS session * * The pre-master secret and the client and server random values must * already be known. */ static void tls_generate_master_secret ( struct tls_session *tls ) { DBGC ( tls, "TLS %p pre-master-secret:\n", tls ); DBGC_HD ( tls, &tls->pre_master_secret, sizeof ( tls->pre_master_secret ) ); DBGC ( tls, "TLS %p client random bytes:\n", tls ); DBGC_HD ( tls, &tls->client_random, sizeof ( tls->client_random ) ); DBGC ( tls, "TLS %p server random bytes:\n", tls ); DBGC_HD ( tls, &tls->server_random, sizeof ( tls->server_random ) ); tls_prf_label ( tls, &tls->pre_master_secret, sizeof ( tls->pre_master_secret ), &tls->master_secret, sizeof ( tls->master_secret ), "master secret", &tls->client_random, sizeof ( tls->client_random ), &tls->server_random, sizeof ( tls->server_random ) ); DBGC ( tls, "TLS %p generated master secret:\n", tls ); DBGC_HD ( tls, &tls->master_secret, sizeof ( tls->master_secret ) ); } /** * Generate key material * * @v tls TLS session * * The master secret must already be known. */ static int tls_generate_keys ( struct tls_session *tls ) { struct tls_cipherspec *tx_cipherspec = &tls->tx_cipherspec_pending; struct tls_cipherspec *rx_cipherspec = &tls->rx_cipherspec_pending; size_t hash_size = tx_cipherspec->digest->digestsize; size_t key_size = tx_cipherspec->key_len; size_t iv_size = tx_cipherspec->cipher->blocksize; size_t total = ( 2 * ( hash_size + key_size + iv_size ) ); uint8_t key_block[total]; uint8_t *key; int rc; /* Generate key block */ tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ), key_block, sizeof ( key_block ), "key expansion", &tls->server_random, sizeof ( tls->server_random ), &tls->client_random, sizeof ( tls->client_random ) ); /* Split key block into portions */ key = key_block; /* TX MAC secret */ memcpy ( tx_cipherspec->mac_secret, key, hash_size ); DBGC ( tls, "TLS %p TX MAC secret:\n", tls ); DBGC_HD ( tls, key, hash_size ); key += hash_size; /* RX MAC secret */ memcpy ( rx_cipherspec->mac_secret, key, hash_size ); DBGC ( tls, "TLS %p RX MAC secret:\n", tls ); DBGC_HD ( tls, key, hash_size ); key += hash_size; /* TX key */ if ( ( rc = cipher_setkey ( tx_cipherspec->cipher, tx_cipherspec->cipher_ctx, key, key_size ) ) != 0 ) { DBGC ( tls, "TLS %p could not set TX key: %s\n", tls, strerror ( rc ) ); return rc; } DBGC ( tls, "TLS %p TX key:\n", tls ); DBGC_HD ( tls, key, key_size ); key += key_size; /* RX key */ if ( ( rc = cipher_setkey ( rx_cipherspec->cipher, rx_cipherspec->cipher_ctx, key, key_size ) ) != 0 ) { DBGC ( tls, "TLS %p could not set TX key: %s\n", tls, strerror ( rc ) ); return rc; } DBGC ( tls, "TLS %p RX key:\n", tls ); DBGC_HD ( tls, key, key_size ); key += key_size; /* TX initialisation vector */ cipher_setiv ( tx_cipherspec->cipher, tx_cipherspec->cipher_ctx, key ); DBGC ( tls, "TLS %p TX IV:\n", tls ); DBGC_HD ( tls, key, iv_size ); key += iv_size; /* RX initialisation vector */ cipher_setiv ( rx_cipherspec->cipher, rx_cipherspec->cipher_ctx, key ); DBGC ( tls, "TLS %p RX IV:\n", tls ); DBGC_HD ( tls, key, iv_size ); key += iv_size; assert ( ( key_block + total ) == key ); return 0; } /****************************************************************************** * * Cipher suite management * ****************************************************************************** */ /** * Clear cipher suite * * @v cipherspec TLS cipher specification */ static void tls_clear_cipher ( struct tls_session *tls __unused, struct tls_cipherspec *cipherspec ) { free ( cipherspec->dynamic ); memset ( cipherspec, 0, sizeof ( cipherspec ) ); cipherspec->pubkey = &pubkey_null; cipherspec->cipher = &cipher_null; cipherspec->digest = &digest_null; } /** * Set cipher suite * * @v tls TLS session * @v cipherspec TLS cipher specification * @v pubkey Public-key encryption elgorithm * @v cipher Bulk encryption cipher algorithm * @v digest MAC digest algorithm * @v key_len Key length * @ret rc Return status code */ static int tls_set_cipher ( struct tls_session *tls, struct tls_cipherspec *cipherspec, struct pubkey_algorithm *pubkey, struct cipher_algorithm *cipher, struct digest_algorithm *digest, size_t key_len ) { size_t total; void *dynamic; /* Clear out old cipher contents, if any */ tls_clear_cipher ( tls, cipherspec ); /* Allocate dynamic storage */ total = ( pubkey->ctxsize + 2 * cipher->ctxsize + digest->digestsize ); dynamic = malloc ( total ); if ( ! dynamic ) { DBGC ( tls, "TLS %p could not allocate %zd bytes for crypto " "context\n", tls, total ); return -ENOMEM; } memset ( dynamic, 0, total ); /* Assign storage */ cipherspec->dynamic = dynamic; cipherspec->pubkey_ctx = dynamic; dynamic += pubkey->ctxsize; cipherspec->cipher_ctx = dynamic; dynamic += cipher->ctxsize; cipherspec->cipher_next_ctx = dynamic; dynamic += cipher->ctxsize; cipherspec->mac_secret = dynamic; dynamic += digest->digestsize; assert ( ( cipherspec->dynamic + total ) == dynamic ); /* Store parameters */ cipherspec->pubkey = pubkey; cipherspec->cipher = cipher; cipherspec->digest = digest; cipherspec->key_len = key_len; return 0; } /** * Select next cipher suite * * @v tls TLS session * @v cipher_suite Cipher suite specification * @ret rc Return status code */ static int tls_select_cipher ( struct tls_session *tls, unsigned int cipher_suite ) { struct pubkey_algorithm *pubkey = &pubkey_null; struct cipher_algorithm *cipher = &cipher_null; struct digest_algorithm *digest = &digest_null; unsigned int key_len = 0; int rc; switch ( cipher_suite ) { case htons ( TLS_RSA_WITH_AES_128_CBC_SHA ): key_len = ( 128 / 8 ); cipher = &aes_cbc_algorithm; digest = &sha1_algorithm; break; case htons ( TLS_RSA_WITH_AES_256_CBC_SHA ): key_len = ( 256 / 8 ); cipher = &aes_cbc_algorithm; digest = &sha1_algorithm; break; default: DBGC ( tls, "TLS %p does not support cipher %04x\n", tls, ntohs ( cipher_suite ) ); return -ENOTSUP; } /* Set ciphers */ if ( ( rc = tls_set_cipher ( tls, &tls->tx_cipherspec_pending, pubkey, cipher, digest, key_len ) ) != 0 ) return rc; if ( ( rc = tls_set_cipher ( tls, &tls->rx_cipherspec_pending, pubkey, cipher, digest, key_len ) ) != 0 ) return rc; DBGC ( tls, "TLS %p selected %s-%s-%d-%s\n", tls, pubkey->name, cipher->name, ( key_len * 8 ), digest->name ); return 0; } /** * Activate next cipher suite * * @v tls TLS session * @v pending Pending cipher specification * @v active Active cipher specification to replace * @ret rc Return status code */ static int tls_change_cipher ( struct tls_session *tls, struct tls_cipherspec *pending, struct tls_cipherspec *active ) { /* Sanity check */ if ( /* FIXME (when pubkey is not hard-coded to RSA): * ( pending->pubkey == &pubkey_null ) || */ ( pending->cipher == &cipher_null ) || ( pending->digest == &digest_null ) ) { DBGC ( tls, "TLS %p refusing to use null cipher\n", tls ); return -ENOTSUP; } tls_clear_cipher ( tls, active ); memswap ( active, pending, sizeof ( *active ) ); return 0; } /****************************************************************************** * * Handshake verification * ****************************************************************************** */ /** * Add handshake record to verification hash * * @v tls TLS session * @v data Handshake record * @v len Length of handshake record */ static void tls_add_handshake ( struct tls_session *tls, const void *data, size_t len ) { digest_update ( &md5_algorithm, tls->handshake_md5_ctx, data, len ); digest_update ( &sha1_algorithm, tls->handshake_sha1_ctx, data, len ); } /** * Calculate handshake verification hash * * @v tls TLS session * @v out Output buffer * * Calculates the MD5+SHA1 digest over all handshake messages seen so * far. */ static void tls_verify_handshake ( struct tls_session *tls, void *out ) { struct digest_algorithm *md5 = &md5_algorithm; struct digest_algorithm *sha1 = &sha1_algorithm; uint8_t md5_ctx[md5->ctxsize]; uint8_t sha1_ctx[sha1->ctxsize]; void *md5_digest = out; void *sha1_digest = ( out + md5->digestsize ); memcpy ( md5_ctx, tls->handshake_md5_ctx, sizeof ( md5_ctx ) ); memcpy ( sha1_ctx, tls->handshake_sha1_ctx, sizeof ( sha1_ctx ) ); digest_final ( md5, md5_ctx, md5_digest ); digest_final ( sha1, sha1_ctx, sha1_digest ); } /****************************************************************************** * * Record handling * ****************************************************************************** */ /** * Transmit Handshake record * * @v tls TLS session * @v data Plaintext record * @v len Length of plaintext record * @ret rc Return status code */ static int tls_send_handshake ( struct tls_session *tls, void *data, size_t len ) { /* Add to handshake digest */ tls_add_handshake ( tls, data, len ); /* Send record */ return tls_send_plaintext ( tls, TLS_TYPE_HANDSHAKE, data, len ); } /** * Transmit Client Hello record * * @v tls TLS session * @ret rc Return status code */ static int tls_send_client_hello ( struct tls_session *tls ) { struct { uint32_t type_length; uint16_t version; uint8_t random[32]; uint8_t session_id_len; uint16_t cipher_suite_len; uint16_t cipher_suites[2]; uint8_t compression_methods_len; uint8_t compression_methods[1]; } __attribute__ (( packed )) hello; memset ( &hello, 0, sizeof ( hello ) ); hello.type_length = ( cpu_to_le32 ( TLS_CLIENT_HELLO ) | htonl ( sizeof ( hello ) - sizeof ( hello.type_length ) ) ); hello.version = htons ( TLS_VERSION_TLS_1_0 ); memcpy ( &hello.random, &tls->client_random, sizeof ( hello.random ) ); hello.cipher_suite_len = htons ( sizeof ( hello.cipher_suites ) ); hello.cipher_suites[0] = htons ( TLS_RSA_WITH_AES_128_CBC_SHA ); hello.cipher_suites[1] = htons ( TLS_RSA_WITH_AES_256_CBC_SHA ); hello.compression_methods_len = sizeof ( hello.compression_methods ); return tls_send_handshake ( tls, &hello, sizeof ( hello ) ); } /** * Transmit Client Key Exchange record * * @v tls TLS session * @ret rc Return status code */ static int tls_send_client_key_exchange ( struct tls_session *tls ) { /* FIXME: Hack alert */ RSA_CTX *rsa_ctx; RSA_pub_key_new ( &rsa_ctx, tls->rsa.modulus, tls->rsa.modulus_len, tls->rsa.exponent, tls->rsa.exponent_len ); struct { uint32_t type_length; uint16_t encrypted_pre_master_secret_len; uint8_t encrypted_pre_master_secret[rsa_ctx->num_octets]; } __attribute__ (( packed )) key_xchg; memset ( &key_xchg, 0, sizeof ( key_xchg ) ); key_xchg.type_length = ( cpu_to_le32 ( TLS_CLIENT_KEY_EXCHANGE ) | htonl ( sizeof ( key_xchg ) - sizeof ( key_xchg.type_length ) ) ); key_xchg.encrypted_pre_master_secret_len = htons ( sizeof ( key_xchg.encrypted_pre_master_secret ) ); /* FIXME: Hack alert */ DBGC ( tls, "RSA encrypting plaintext, modulus, exponent:\n" ); DBGC_HD ( tls, &tls->pre_master_secret, sizeof ( tls->pre_master_secret ) ); DBGC_HD ( tls, tls->rsa.modulus, tls->rsa.modulus_len ); DBGC_HD ( tls, tls->rsa.exponent, tls->rsa.exponent_len ); RSA_encrypt ( rsa_ctx, ( const uint8_t * ) &tls->pre_master_secret, sizeof ( tls->pre_master_secret ), key_xchg.encrypted_pre_master_secret, 0 ); DBGC ( tls, "RSA encrypt done. Ciphertext:\n" ); DBGC_HD ( tls, &key_xchg.encrypted_pre_master_secret, sizeof ( key_xchg.encrypted_pre_master_secret ) ); RSA_free ( rsa_ctx ); return tls_send_handshake ( tls, &key_xchg, sizeof ( key_xchg ) ); } /** * Transmit Change Cipher record * * @v tls TLS session * @ret rc Return status code */ static int tls_send_change_cipher ( struct tls_session *tls ) { static const uint8_t change_cipher[1] = { 1 }; return tls_send_plaintext ( tls, TLS_TYPE_CHANGE_CIPHER, change_cipher, sizeof ( change_cipher ) ); } /** * Transmit Finished record * * @v tls TLS session * @ret rc Return status code */ static int tls_send_finished ( struct tls_session *tls ) { struct { uint32_t type_length; uint8_t verify_data[12]; } __attribute__ (( packed )) finished; uint8_t digest[MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE]; memset ( &finished, 0, sizeof ( finished ) ); finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) | htonl ( sizeof ( finished ) - sizeof ( finished.type_length ) ) ); tls_verify_handshake ( tls, digest ); tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ), finished.verify_data, sizeof ( finished.verify_data ), "client finished", digest, sizeof ( digest ) ); return tls_send_handshake ( tls, &finished, sizeof ( finished ) ); } /** * Receive new Change Cipher record * * @v tls TLS session * @v data Plaintext record * @v len Length of plaintext record * @ret rc Return status code */ static int tls_new_change_cipher ( struct tls_session *tls, void *data, size_t len ) { int rc; if ( ( len != 1 ) || ( *( ( uint8_t * ) data ) != 1 ) ) { DBGC ( tls, "TLS %p received invalid Change Cipher\n", tls ); DBGC_HD ( tls, data, len ); return -EINVAL; } if ( ( rc = tls_change_cipher ( tls, &tls->rx_cipherspec_pending, &tls->rx_cipherspec ) ) != 0 ) { DBGC ( tls, "TLS %p could not activate RX cipher: %s\n", tls, strerror ( rc ) ); return rc; } tls->rx_seq = ~( ( uint64_t ) 0 ); return 0; } /** * Receive new Alert record * * @v tls TLS session * @v data Plaintext record * @v len Length of plaintext record * @ret rc Return status code */ static int tls_new_alert ( struct tls_session *tls, void *data, size_t len ) { struct { uint8_t level; uint8_t description; char next[0]; } __attribute__ (( packed )) *alert = data; void *end = alert->next; /* Sanity check */ if ( end != ( data + len ) ) { DBGC ( tls, "TLS %p received overlength Alert\n", tls ); DBGC_HD ( tls, data, len ); return -EINVAL; } switch ( alert->level ) { case TLS_ALERT_WARNING: DBGC ( tls, "TLS %p received warning alert %d\n", tls, alert->description ); return 0; case TLS_ALERT_FATAL: DBGC ( tls, "TLS %p received fatal alert %d\n", tls, alert->description ); return -EPERM; default: DBGC ( tls, "TLS %p received unknown alert level %d" "(alert %d)\n", tls, alert->level, alert->description ); return -EIO; } } /** * Receive new Server Hello handshake record * * @v tls TLS session * @v data Plaintext handshake record * @v len Length of plaintext handshake record * @ret rc Return status code */ static int tls_new_server_hello ( struct tls_session *tls, void *data, size_t len ) { struct { uint16_t version; uint8_t random[32]; uint8_t session_id_len; char next[0]; } __attribute__ (( packed )) *hello_a = data; struct { uint8_t session_id[hello_a->session_id_len]; uint16_t cipher_suite; uint8_t compression_method; char next[0]; } __attribute__ (( packed )) *hello_b = ( void * ) &hello_a->next; void *end = hello_b->next; int rc; /* Sanity check */ if ( end != ( data + len ) ) { DBGC ( tls, "TLS %p received overlength Server Hello\n", tls ); DBGC_HD ( tls, data, len ); return -EINVAL; } /* Check protocol version */ if ( ntohs ( hello_a->version ) < TLS_VERSION_TLS_1_0 ) { DBGC ( tls, "TLS %p does not support protocol version %d.%d\n", tls, ( ntohs ( hello_a->version ) >> 8 ), ( ntohs ( hello_a->version ) & 0xff ) ); return -ENOTSUP; } /* Copy out server random bytes */ memcpy ( &tls->server_random, &hello_a->random, sizeof ( tls->server_random ) ); /* Select cipher suite */ if ( ( rc = tls_select_cipher ( tls, hello_b->cipher_suite ) ) != 0 ) return rc; /* Generate secrets */ tls_generate_master_secret ( tls ); if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) return rc; return 0; } /** * Receive new Certificate handshake record * * @v tls TLS session * @v data Plaintext handshake record * @v len Length of plaintext handshake record * @ret rc Return status code */ static int tls_new_certificate ( struct tls_session *tls, void *data, size_t len ) { struct { uint8_t length[3]; uint8_t certificates[0]; } __attribute__ (( packed )) *certificate = data; struct { uint8_t length[3]; uint8_t certificate[0]; } __attribute__ (( packed )) *element = ( ( void * ) certificate->certificates ); size_t elements_len = tls_uint24 ( certificate->length ); void *end = ( certificate->certificates + elements_len ); struct asn1_cursor cursor; int rc; /* Sanity check */ if ( end != ( data + len ) ) { DBGC ( tls, "TLS %p received overlength Server Certificate\n", tls ); DBGC_HD ( tls, data, len ); return -EINVAL; } /* Traverse certificate chain */ do { cursor.data = element->certificate; cursor.len = tls_uint24 ( element->length ); if ( ( cursor.data + cursor.len ) > end ) { DBGC ( tls, "TLS %p received corrupt Server " "Certificate\n", tls ); DBGC_HD ( tls, data, len ); return -EINVAL; } // HACK if ( ( rc = x509_rsa_public_key ( &cursor, &tls->rsa ) ) != 0 ) { DBGC ( tls, "TLS %p cannot determine RSA public key: " "%s\n", tls, strerror ( rc ) ); return rc; } return 0; element = ( cursor.data + cursor.len ); } while ( element != end ); return -EINVAL; } /** * Receive new Server Hello Done handshake record * * @v tls TLS session * @v data Plaintext handshake record * @v len Length of plaintext handshake record * @ret rc Return status code */ static int tls_new_server_hello_done ( struct tls_session *tls, void *data, size_t len ) { struct { char next[0]; } __attribute__ (( packed )) *hello_done = data; void *end = hello_done->next; /* Sanity check */ if ( end != ( data + len ) ) { DBGC ( tls, "TLS %p received overlength Server Hello Done\n", tls ); DBGC_HD ( tls, data, len ); return -EINVAL; } /* Check that we are ready to send the Client Key Exchange */ if ( tls->tx_state != TLS_TX_NONE ) { DBGC ( tls, "TLS %p received Server Hello Done while in " "TX state %d\n", tls, tls->tx_state ); return -EIO; } /* Start sending the Client Key Exchange */ tls->tx_state = TLS_TX_CLIENT_KEY_EXCHANGE; return 0; } /** * Receive new Finished handshake record * * @v tls TLS session * @v data Plaintext handshake record * @v len Length of plaintext handshake record * @ret rc Return status code */ static int tls_new_finished ( struct tls_session *tls, void *data, size_t len ) { /* FIXME: Handle this properly */ tls->tx_state = TLS_TX_DATA; ( void ) data; ( void ) len; return 0; } /** * Receive new Handshake record * * @v tls TLS session * @v data Plaintext record * @v len Length of plaintext record * @ret rc Return status code */ static int tls_new_handshake ( struct tls_session *tls, void *data, size_t len ) { struct { uint8_t type; uint8_t length[3]; uint8_t payload[0]; } __attribute__ (( packed )) *handshake = data; void *payload = &handshake->payload; size_t payload_len = tls_uint24 ( handshake->length ); void *end = ( payload + payload_len ); int rc; /* Sanity check */ if ( end != ( data + len ) ) { DBGC ( tls, "TLS %p received overlength Handshake\n", tls ); DBGC_HD ( tls, data, len ); return -EINVAL; } switch ( handshake->type ) { case TLS_SERVER_HELLO: rc = tls_new_server_hello ( tls, payload, payload_len ); break; case TLS_CERTIFICATE: rc = tls_new_certificate ( tls, payload, payload_len ); break; case TLS_SERVER_HELLO_DONE: rc = tls_new_server_hello_done ( tls, payload, payload_len ); break; case TLS_FINISHED: rc = tls_new_finished ( tls, payload, payload_len ); break; default: DBGC ( tls, "TLS %p ignoring handshake type %d\n", tls, handshake->type ); rc = 0; break; } /* Add to handshake digest (except for Hello Requests, which * are explicitly excluded). */ if ( handshake->type != TLS_HELLO_REQUEST ) tls_add_handshake ( tls, data, len ); return rc; } /** * Receive new record * * @v tls TLS session * @v type Record type * @v data Plaintext record * @v len Length of plaintext record * @ret rc Return status code */ static int tls_new_record ( struct tls_session *tls, unsigned int type, void *data, size_t len ) { switch ( type ) { case TLS_TYPE_CHANGE_CIPHER: return tls_new_change_cipher ( tls, data, len ); case TLS_TYPE_ALERT: return tls_new_alert ( tls, data, len ); case TLS_TYPE_HANDSHAKE: return tls_new_handshake ( tls, data, len ); case TLS_TYPE_DATA: return xfer_deliver_raw ( &tls->plainstream.xfer, data, len ); default: /* RFC4346 says that we should just ignore unknown * record types. */ DBGC ( tls, "TLS %p ignoring record type %d\n", tls, type ); return 0; } } /****************************************************************************** * * Record encryption/decryption * ****************************************************************************** */ /** * Calculate HMAC * * @v tls TLS session * @v cipherspec Cipher specification * @v seq Sequence number * @v tlshdr TLS header * @v data Data * @v len Length of data * @v mac HMAC to fill in */ static void tls_hmac ( struct tls_session *tls __unused, struct tls_cipherspec *cipherspec, uint64_t seq, struct tls_header *tlshdr, const void *data, size_t len, void *hmac ) { struct digest_algorithm *digest = cipherspec->digest; uint8_t digest_ctx[digest->ctxsize]; hmac_init ( digest, digest_ctx, cipherspec->mac_secret, &digest->digestsize ); seq = cpu_to_be64 ( seq ); hmac_update ( digest, digest_ctx, &seq, sizeof ( seq ) ); hmac_update ( digest, digest_ctx, tlshdr, sizeof ( *tlshdr ) ); hmac_update ( digest, digest_ctx, data, len ); hmac_final ( digest, digest_ctx, cipherspec->mac_secret, &digest->digestsize, hmac ); } /** * Allocate and assemble stream-ciphered record from data and MAC portions * * @v tls TLS session * @ret data Data * @ret len Length of data * @ret digest MAC digest * @ret plaintext_len Length of plaintext record * @ret plaintext Allocated plaintext record */ static void * __malloc tls_assemble_stream ( struct tls_session *tls, const void *data, size_t len, void *digest, size_t *plaintext_len ) { size_t mac_len = tls->tx_cipherspec.digest->digestsize; void *plaintext; void *content; void *mac; /* Calculate stream-ciphered struct length */ *plaintext_len = ( len + mac_len ); /* Allocate stream-ciphered struct */ plaintext = malloc ( *plaintext_len ); if ( ! plaintext ) return NULL; content = plaintext; mac = ( content + len ); /* Fill in stream-ciphered struct */ memcpy ( content, data, len ); memcpy ( mac, digest, mac_len ); return plaintext; } /** * Allocate and assemble block-ciphered record from data and MAC portions * * @v tls TLS session * @ret data Data * @ret len Length of data * @ret digest MAC digest * @ret plaintext_len Length of plaintext record * @ret plaintext Allocated plaintext record */ static void * tls_assemble_block ( struct tls_session *tls, const void *data, size_t len, void *digest, size_t *plaintext_len ) { size_t blocksize = tls->tx_cipherspec.cipher->blocksize; size_t iv_len = blocksize; size_t mac_len = tls->tx_cipherspec.digest->digestsize; size_t padding_len; void *plaintext; void *iv; void *content; void *mac; void *padding; /* FIXME: TLSv1.1 has an explicit IV */ iv_len = 0; /* Calculate block-ciphered struct length */ padding_len = ( ( blocksize - 1 ) & -( iv_len + len + mac_len + 1 ) ); *plaintext_len = ( iv_len + len + mac_len + padding_len + 1 ); /* Allocate block-ciphered struct */ plaintext = malloc ( *plaintext_len ); if ( ! plaintext ) return NULL; iv = plaintext; content = ( iv + iv_len ); mac = ( content + len ); padding = ( mac + mac_len ); /* Fill in block-ciphered struct */ memset ( iv, 0, iv_len ); memcpy ( content, data, len ); memcpy ( mac, digest, mac_len ); memset ( padding, padding_len, ( padding_len + 1 ) ); return plaintext; } /** * Send plaintext record * * @v tls TLS session * @v type Record type * @v data Plaintext record * @v len Length of plaintext record * @ret rc Return status code */ static int tls_send_plaintext ( struct tls_session *tls, unsigned int type, const void *data, size_t len ) { struct tls_header plaintext_tlshdr; struct tls_header *tlshdr; struct tls_cipherspec *cipherspec = &tls->tx_cipherspec; void *plaintext = NULL; size_t plaintext_len; struct io_buffer *ciphertext = NULL; size_t ciphertext_len; size_t mac_len = cipherspec->digest->digestsize; uint8_t mac[mac_len]; int rc; /* Construct header */ plaintext_tlshdr.type = type; plaintext_tlshdr.version = htons ( TLS_VERSION_TLS_1_0 ); plaintext_tlshdr.length = htons ( len ); /* Calculate MAC */ tls_hmac ( tls, cipherspec, tls->tx_seq, &plaintext_tlshdr, data, len, mac ); /* Allocate and assemble plaintext struct */ if ( is_stream_cipher ( cipherspec->cipher ) ) { plaintext = tls_assemble_stream ( tls, data, len, mac, &plaintext_len ); } else { plaintext = tls_assemble_block ( tls, data, len, mac, &plaintext_len ); } if ( ! plaintext ) { DBGC ( tls, "TLS %p could not allocate %zd bytes for " "plaintext\n", tls, plaintext_len ); rc = -ENOMEM; goto done; } DBGC2 ( tls, "Sending plaintext data:\n" ); DBGC2_HD ( tls, plaintext, plaintext_len ); /* Allocate ciphertext */ ciphertext_len = ( sizeof ( *tlshdr ) + plaintext_len ); ciphertext = xfer_alloc_iob ( &tls->cipherstream.xfer, ciphertext_len ); if ( ! ciphertext ) { DBGC ( tls, "TLS %p could not allocate %zd bytes for " "ciphertext\n", tls, ciphertext_len ); rc = -ENOMEM; goto done; } /* Assemble ciphertext */ tlshdr = iob_put ( ciphertext, sizeof ( *tlshdr ) ); tlshdr->type = type; tlshdr->version = htons ( TLS_VERSION_TLS_1_0 ); tlshdr->length = htons ( plaintext_len ); memcpy ( cipherspec->cipher_next_ctx, cipherspec->cipher_ctx, cipherspec->cipher->ctxsize ); cipher_encrypt ( cipherspec->cipher, cipherspec->cipher_next_ctx, plaintext, iob_put ( ciphertext, plaintext_len ), plaintext_len ); /* Free plaintext as soon as possible to conserve memory */ free ( plaintext ); plaintext = NULL; /* Send ciphertext */ rc = xfer_deliver_iob ( &tls->cipherstream.xfer, ciphertext ); ciphertext = NULL; if ( rc != 0 ) { DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n", tls, strerror ( rc ) ); goto done; } /* Update TX state machine to next record */ tls->tx_seq += 1; memcpy ( tls->tx_cipherspec.cipher_ctx, tls->tx_cipherspec.cipher_next_ctx, tls->tx_cipherspec.cipher->ctxsize ); done: free ( plaintext ); free_iob ( ciphertext ); return rc; } /** * Split stream-ciphered record into data and MAC portions * * @v tls TLS session * @v plaintext Plaintext record * @v plaintext_len Length of record * @ret data Data * @ret len Length of data * @ret digest MAC digest * @ret rc Return status code */ static int tls_split_stream ( struct tls_session *tls, void *plaintext, size_t plaintext_len, void **data, size_t *len, void **digest ) { void *content; size_t content_len; void *mac; size_t mac_len; /* Decompose stream-ciphered data */ mac_len = tls->rx_cipherspec.digest->digestsize; if ( plaintext_len < mac_len ) { DBGC ( tls, "TLS %p received underlength record\n", tls ); DBGC_HD ( tls, plaintext, plaintext_len ); return -EINVAL; } content_len = ( plaintext_len - mac_len ); content = plaintext; mac = ( content + content_len ); /* Fill in return values */ *data = content; *len = content_len; *digest = mac; return 0; } /** * Split block-ciphered record into data and MAC portions * * @v tls TLS session * @v plaintext Plaintext record * @v plaintext_len Length of record * @ret data Data * @ret len Length of data * @ret digest MAC digest * @ret rc Return status code */ static int tls_split_block ( struct tls_session *tls, void *plaintext, size_t plaintext_len, void **data, size_t *len, void **digest ) { void *iv; size_t iv_len; void *content; size_t content_len; void *mac; size_t mac_len; void *padding; size_t padding_len; unsigned int i; /* Decompose block-ciphered data */ if ( plaintext_len < 1 ) { DBGC ( tls, "TLS %p received underlength record\n", tls ); DBGC_HD ( tls, plaintext, plaintext_len ); return -EINVAL; } iv_len = tls->rx_cipherspec.cipher->blocksize; /* FIXME: TLSv1.1 uses an explicit IV */ iv_len = 0; mac_len = tls->rx_cipherspec.digest->digestsize; padding_len = *( ( uint8_t * ) ( plaintext + plaintext_len - 1 ) ); if ( plaintext_len < ( iv_len + mac_len + padding_len + 1 ) ) { DBGC ( tls, "TLS %p received underlength record\n", tls ); DBGC_HD ( tls, plaintext, plaintext_len ); return -EINVAL; } content_len = ( plaintext_len - iv_len - mac_len - padding_len - 1 ); iv = plaintext; content = ( iv + iv_len ); mac = ( content + content_len ); padding = ( mac + mac_len ); /* Verify padding bytes */ for ( i = 0 ; i < padding_len ; i++ ) { if ( *( ( uint8_t * ) ( padding + i ) ) != padding_len ) { DBGC ( tls, "TLS %p received bad padding\n", tls ); DBGC_HD ( tls, plaintext, plaintext_len ); return -EINVAL; } } /* Fill in return values */ *data = content; *len = content_len; *digest = mac; return 0; } /** * Receive new ciphertext record * * @v tls TLS session * @v tlshdr Record header * @v ciphertext Ciphertext record * @ret rc Return status code */ static int tls_new_ciphertext ( struct tls_session *tls, struct tls_header *tlshdr, void *ciphertext ) { struct tls_header plaintext_tlshdr; struct tls_cipherspec *cipherspec = &tls->rx_cipherspec; size_t record_len = ntohs ( tlshdr->length ); void *plaintext = NULL; void *data; size_t len; void *mac; size_t mac_len = cipherspec->digest->digestsize; uint8_t verify_mac[mac_len]; int rc; /* Allocate buffer for plaintext */ plaintext = malloc ( record_len ); if ( ! plaintext ) { DBGC ( tls, "TLS %p could not allocate %zd bytes for " "decryption buffer\n", tls, record_len ); rc = -ENOMEM; goto done; } /* Decrypt the record */ cipher_decrypt ( cipherspec->cipher, cipherspec->cipher_ctx, ciphertext, plaintext, record_len ); /* Split record into content and MAC */ if ( is_stream_cipher ( cipherspec->cipher ) ) { if ( ( rc = tls_split_stream ( tls, plaintext, record_len, &data, &len, &mac ) ) != 0 ) goto done; } else { if ( ( rc = tls_split_block ( tls, plaintext, record_len, &data, &len, &mac ) ) != 0 ) goto done; } /* Verify MAC */ plaintext_tlshdr.type = tlshdr->type; plaintext_tlshdr.version = tlshdr->version; plaintext_tlshdr.length = htons ( len ); tls_hmac ( tls, cipherspec, tls->rx_seq, &plaintext_tlshdr, data, len, verify_mac); if ( memcmp ( mac, verify_mac, mac_len ) != 0 ) { DBGC ( tls, "TLS %p failed MAC verification\n", tls ); DBGC_HD ( tls, plaintext, record_len ); goto done; } DBGC2 ( tls, "Received plaintext data:\n" ); DBGC2_HD ( tls, data, len ); /* Process plaintext record */ if ( ( rc = tls_new_record ( tls, tlshdr->type, data, len ) ) != 0 ) goto done; rc = 0; done: free ( plaintext ); return rc; } /****************************************************************************** * * Plaintext stream operations * ****************************************************************************** */ /** * Close interface * * @v xfer Plainstream data transfer interface * @v rc Reason for close */ static void tls_plainstream_close ( struct xfer_interface *xfer, int rc ) { struct tls_session *tls = container_of ( xfer, struct tls_session, plainstream.xfer ); tls_close ( tls, rc ); } /** * Check flow control window * * @v xfer Plainstream data transfer interface * @ret len Length of window */ static size_t tls_plainstream_window ( struct xfer_interface *xfer ) { struct tls_session *tls = container_of ( xfer, struct tls_session, plainstream.xfer ); /* Block window unless we are ready to accept data */ if ( tls->tx_state != TLS_TX_DATA ) return 0; return filter_window ( xfer ); } /** * Deliver datagram as raw data * * @v xfer Plainstream data transfer interface * @v data Data buffer * @v len Length of data buffer * @ret rc Return status code */ static int tls_plainstream_deliver_raw ( struct xfer_interface *xfer, const void *data, size_t len ) { struct tls_session *tls = container_of ( xfer, struct tls_session, plainstream.xfer ); /* Refuse unless we are ready to accept data */ if ( tls->tx_state != TLS_TX_DATA ) return -ENOTCONN; return tls_send_plaintext ( tls, TLS_TYPE_DATA, data, len ); } /** TLS plaintext stream operations */ static struct xfer_interface_operations tls_plainstream_operations = { .close = tls_plainstream_close, .vredirect = ignore_xfer_vredirect, .window = tls_plainstream_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, .deliver_raw = tls_plainstream_deliver_raw, }; /****************************************************************************** * * Ciphertext stream operations * ****************************************************************************** */ /** * Close interface * * @v xfer Plainstream data transfer interface * @v rc Reason for close */ static void tls_cipherstream_close ( struct xfer_interface *xfer, int rc ) { struct tls_session *tls = container_of ( xfer, struct tls_session, cipherstream.xfer ); tls_close ( tls, rc ); } /** * Handle received TLS header * * @v tls TLS session * @ret rc Returned status code */ static int tls_newdata_process_header ( struct tls_session *tls ) { size_t data_len = ntohs ( tls->rx_header.length ); /* Allocate data buffer now that we know the length */ assert ( tls->rx_data == NULL ); tls->rx_data = malloc ( data_len ); if ( ! tls->rx_data ) { DBGC ( tls, "TLS %p could not allocate %zd bytes " "for receive buffer\n", tls, data_len ); return -ENOMEM; } /* Move to data state */ tls->rx_state = TLS_RX_DATA; return 0; } /** * Handle received TLS data payload * * @v tls TLS session * @ret rc Returned status code */ static int tls_newdata_process_data ( struct tls_session *tls ) { int rc; /* Process record */ if ( ( rc = tls_new_ciphertext ( tls, &tls->rx_header, tls->rx_data ) ) != 0 ) return rc; /* Increment RX sequence number */ tls->rx_seq += 1; /* Free data buffer */ free ( tls->rx_data ); tls->rx_data = NULL; /* Return to header state */ tls->rx_state = TLS_RX_HEADER; return 0; } /** * Receive new ciphertext * * @v app Stream application * @v data Data received * @v len Length of received data * @ret rc Return status code */ static int tls_cipherstream_deliver_raw ( struct xfer_interface *xfer, const void *data, size_t len ) { struct tls_session *tls = container_of ( xfer, struct tls_session, cipherstream.xfer ); size_t frag_len; void *buf; size_t buf_len; int ( * process ) ( struct tls_session *tls ); int rc; while ( len ) { /* Select buffer according to current state */ switch ( tls->rx_state ) { case TLS_RX_HEADER: buf = &tls->rx_header; buf_len = sizeof ( tls->rx_header ); process = tls_newdata_process_header; break; case TLS_RX_DATA: buf = tls->rx_data; buf_len = ntohs ( tls->rx_header.length ); process = tls_newdata_process_data; break; default: assert ( 0 ); return -EINVAL; } /* Copy data portion to buffer */ frag_len = ( buf_len - tls->rx_rcvd ); if ( frag_len > len ) frag_len = len; memcpy ( ( buf + tls->rx_rcvd ), data, frag_len ); tls->rx_rcvd += frag_len; data += frag_len; len -= frag_len; /* Process data if buffer is now full */ if ( tls->rx_rcvd == buf_len ) { if ( ( rc = process ( tls ) ) != 0 ) { tls_close ( tls, rc ); return rc; } tls->rx_rcvd = 0; } } return 0; } /** TLS ciphertext stream operations */ static struct xfer_interface_operations tls_cipherstream_operations = { .close = tls_cipherstream_close, .vredirect = xfer_vreopen, .window = filter_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, .deliver_raw = tls_cipherstream_deliver_raw, }; /****************************************************************************** * * Controlling process * ****************************************************************************** */ /** * TLS TX state machine * * @v process TLS process */ static void tls_step ( struct process *process ) { struct tls_session *tls = container_of ( process, struct tls_session, process ); int rc; /* Wait for cipherstream to become ready */ if ( ! xfer_window ( &tls->cipherstream.xfer ) ) return; switch ( tls->tx_state ) { case TLS_TX_NONE: /* Nothing to do */ break; case TLS_TX_CLIENT_HELLO: /* Send Client Hello */ if ( ( rc = tls_send_client_hello ( tls ) ) != 0 ) { DBGC ( tls, "TLS %p could not send Client Hello: %s\n", tls, strerror ( rc ) ); goto err; } tls->tx_state = TLS_TX_NONE; break; case TLS_TX_CLIENT_KEY_EXCHANGE: /* Send Client Key Exchange */ if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) { DBGC ( tls, "TLS %p could send Client Key Exchange: " "%s\n", tls, strerror ( rc ) ); goto err; } tls->tx_state = TLS_TX_CHANGE_CIPHER; break; case TLS_TX_CHANGE_CIPHER: /* Send Change Cipher, and then change the cipher in use */ if ( ( rc = tls_send_change_cipher ( tls ) ) != 0 ) { DBGC ( tls, "TLS %p could not send Change Cipher: " "%s\n", tls, strerror ( rc ) ); goto err; } if ( ( rc = tls_change_cipher ( tls, &tls->tx_cipherspec_pending, &tls->tx_cipherspec )) != 0 ){ DBGC ( tls, "TLS %p could not activate TX cipher: " "%s\n", tls, strerror ( rc ) ); goto err; } tls->tx_seq = 0; tls->tx_state = TLS_TX_FINISHED; break; case TLS_TX_FINISHED: /* Send Finished */ if ( ( rc = tls_send_finished ( tls ) ) != 0 ) { DBGC ( tls, "TLS %p could not send Finished: %s\n", tls, strerror ( rc ) ); goto err; } tls->tx_state = TLS_TX_NONE; break; case TLS_TX_DATA: /* Nothing to do */ break; default: assert ( 0 ); } return; err: tls_close ( tls, rc ); } /****************************************************************************** * * Instantiator * ****************************************************************************** */ int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) { struct tls_session *tls; /* Allocate and initialise TLS structure */ tls = malloc ( sizeof ( *tls ) ); if ( ! tls ) return -ENOMEM; memset ( tls, 0, sizeof ( *tls ) ); tls->refcnt.free = free_tls; filter_init ( &tls->plainstream, &tls_plainstream_operations, &tls->cipherstream, &tls_cipherstream_operations, &tls->refcnt ); tls_clear_cipher ( tls, &tls->tx_cipherspec ); tls_clear_cipher ( tls, &tls->tx_cipherspec_pending ); tls_clear_cipher ( tls, &tls->rx_cipherspec ); tls_clear_cipher ( tls, &tls->rx_cipherspec_pending ); tls->client_random.gmt_unix_time = 0; tls_generate_random ( &tls->client_random.random, ( sizeof ( tls->client_random.random ) ) ); tls->pre_master_secret.version = htons ( TLS_VERSION_TLS_1_0 ); tls_generate_random ( &tls->pre_master_secret.random, ( sizeof ( tls->pre_master_secret.random ) ) ); digest_init ( &md5_algorithm, tls->handshake_md5_ctx ); digest_init ( &sha1_algorithm, tls->handshake_sha1_ctx ); tls->tx_state = TLS_TX_CLIENT_HELLO; process_init ( &tls->process, tls_step, &tls->refcnt ); /* Attach to parent interface, mortalise self, and return */ xfer_plug_plug ( &tls->plainstream.xfer, xfer ); *next = &tls->cipherstream.xfer; ref_put ( &tls->refcnt ); return 0; } debian/grub-extras/disabled/gpxe/src/net/tcp.c0000664000000000000000000007352212524662415016474 0ustar #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * TCP protocol * */ FILE_LICENCE ( GPL2_OR_LATER ); /** A TCP connection */ struct tcp_connection { /** Reference counter */ struct refcnt refcnt; /** List of TCP connections */ struct list_head list; /** Data transfer interface */ struct xfer_interface xfer; /** Data transfer interface closed flag */ int xfer_closed; /** Remote socket address */ struct sockaddr_tcpip peer; /** Local port, in network byte order */ unsigned int local_port; /** Current TCP state */ unsigned int tcp_state; /** Previous TCP state * * Maintained only for debug messages */ unsigned int prev_tcp_state; /** Current sequence number * * Equivalent to SND.UNA in RFC 793 terminology. */ uint32_t snd_seq; /** Unacknowledged sequence count * * Equivalent to (SND.NXT-SND.UNA) in RFC 793 terminology. */ uint32_t snd_sent; /** Send window * * Equivalent to SND.WND in RFC 793 terminology */ uint32_t snd_win; /** Current acknowledgement number * * Equivalent to RCV.NXT in RFC 793 terminology. */ uint32_t rcv_ack; /** Receive window * * Equivalent to RCV.WND in RFC 793 terminology. */ uint32_t rcv_win; /** Most recent received timestamp * * Equivalent to TS.Recent in RFC 1323 terminology. */ uint32_t ts_recent; /** Timestamps enabled */ int timestamps; /** Transmit queue */ struct list_head queue; /** Retransmission timer */ struct retry_timer timer; }; /** * List of registered TCP connections */ static LIST_HEAD ( tcp_conns ); /* Forward declarations */ static struct xfer_interface_operations tcp_xfer_operations; static void tcp_expired ( struct retry_timer *timer, int over ); static int tcp_rx_ack ( struct tcp_connection *tcp, uint32_t ack, uint32_t win ); /** * Name TCP state * * @v state TCP state * @ret name Name of TCP state */ static inline __attribute__ (( always_inline )) const char * tcp_state ( int state ) { switch ( state ) { case TCP_CLOSED: return "CLOSED"; case TCP_LISTEN: return "LISTEN"; case TCP_SYN_SENT: return "SYN_SENT"; case TCP_SYN_RCVD: return "SYN_RCVD"; case TCP_ESTABLISHED: return "ESTABLISHED"; case TCP_FIN_WAIT_1: return "FIN_WAIT_1"; case TCP_FIN_WAIT_2: return "FIN_WAIT_2"; case TCP_CLOSING_OR_LAST_ACK: return "CLOSING/LAST_ACK"; case TCP_TIME_WAIT: return "TIME_WAIT"; case TCP_CLOSE_WAIT: return "CLOSE_WAIT"; default: return "INVALID"; } } /** * Dump TCP state transition * * @v tcp TCP connection */ static inline __attribute__ (( always_inline )) void tcp_dump_state ( struct tcp_connection *tcp ) { if ( tcp->tcp_state != tcp->prev_tcp_state ) { DBGC ( tcp, "TCP %p transitioned from %s to %s\n", tcp, tcp_state ( tcp->prev_tcp_state ), tcp_state ( tcp->tcp_state ) ); } tcp->prev_tcp_state = tcp->tcp_state; } /** * Dump TCP flags * * @v flags TCP flags */ static inline __attribute__ (( always_inline )) void tcp_dump_flags ( struct tcp_connection *tcp, unsigned int flags ) { if ( flags & TCP_RST ) DBGC2 ( tcp, " RST" ); if ( flags & TCP_SYN ) DBGC2 ( tcp, " SYN" ); if ( flags & TCP_PSH ) DBGC2 ( tcp, " PSH" ); if ( flags & TCP_FIN ) DBGC2 ( tcp, " FIN" ); if ( flags & TCP_ACK ) DBGC2 ( tcp, " ACK" ); } /*************************************************************************** * * Open and close * *************************************************************************** */ /** * Bind TCP connection to local port * * @v tcp TCP connection * @v port Local port number, in network-endian order * @ret rc Return status code * * If the port is 0, the connection is assigned an available port * between 1024 and 65535. */ static int tcp_bind ( struct tcp_connection *tcp, unsigned int port ) { struct tcp_connection *existing; static uint16_t try_port = 1023; /* If no port specified, find the first available port */ if ( ! port ) { while ( try_port ) { try_port++; if ( try_port < 1024 ) continue; if ( tcp_bind ( tcp, htons ( try_port ) ) == 0 ) return 0; } DBGC ( tcp, "TCP %p could not bind: no free ports\n", tcp ); return -EADDRINUSE; } /* Attempt bind to local port */ list_for_each_entry ( existing, &tcp_conns, list ) { if ( existing->local_port == port ) { DBGC ( tcp, "TCP %p could not bind: port %d in use\n", tcp, ntohs ( port ) ); return -EADDRINUSE; } } tcp->local_port = port; DBGC ( tcp, "TCP %p bound to port %d\n", tcp, ntohs ( port ) ); return 0; } /** * Open a TCP connection * * @v xfer Data transfer interface * @v peer Peer socket address * @v local Local socket address, or NULL * @ret rc Return status code */ static int tcp_open ( struct xfer_interface *xfer, struct sockaddr *peer, struct sockaddr *local ) { struct sockaddr_tcpip *st_peer = ( struct sockaddr_tcpip * ) peer; struct sockaddr_tcpip *st_local = ( struct sockaddr_tcpip * ) local; struct tcp_connection *tcp; unsigned int bind_port; int rc; /* Allocate and initialise structure */ tcp = zalloc ( sizeof ( *tcp ) ); if ( ! tcp ) return -ENOMEM; DBGC ( tcp, "TCP %p allocated\n", tcp ); xfer_init ( &tcp->xfer, &tcp_xfer_operations, &tcp->refcnt ); tcp->prev_tcp_state = TCP_CLOSED; tcp->tcp_state = TCP_STATE_SENT ( TCP_SYN ); tcp_dump_state ( tcp ); tcp->snd_seq = random(); INIT_LIST_HEAD ( &tcp->queue ); tcp->timer.expired = tcp_expired; memcpy ( &tcp->peer, st_peer, sizeof ( tcp->peer ) ); /* Bind to local port */ bind_port = ( st_local ? st_local->st_port : 0 ); if ( ( rc = tcp_bind ( tcp, bind_port ) ) != 0 ) goto err; /* Start timer to initiate SYN */ start_timer_nodelay ( &tcp->timer ); /* Attach parent interface, transfer reference to connection * list and return */ xfer_plug_plug ( &tcp->xfer, xfer ); list_add ( &tcp->list, &tcp_conns ); return 0; err: ref_put ( &tcp->refcnt ); return rc; } /** * Close TCP connection * * @v tcp TCP connection * @v rc Reason for close * * Closes the data transfer interface. If the TCP state machine is in * a suitable state, the connection will be deleted. */ static void tcp_close ( struct tcp_connection *tcp, int rc ) { struct io_buffer *iobuf; struct io_buffer *tmp; /* Close data transfer interface */ xfer_nullify ( &tcp->xfer ); xfer_close ( &tcp->xfer, rc ); tcp->xfer_closed = 1; /* If we are in CLOSED, or have otherwise not yet received a * SYN (i.e. we are in LISTEN or SYN_SENT), just delete the * connection. */ if ( ! ( tcp->tcp_state & TCP_STATE_RCVD ( TCP_SYN ) ) ) { /* Transition to CLOSED for the sake of debugging messages */ tcp->tcp_state = TCP_CLOSED; tcp_dump_state ( tcp ); /* Free any unsent I/O buffers */ list_for_each_entry_safe ( iobuf, tmp, &tcp->queue, list ) { list_del ( &iobuf->list ); free_iob ( iobuf ); } /* Remove from list and drop reference */ stop_timer ( &tcp->timer ); list_del ( &tcp->list ); ref_put ( &tcp->refcnt ); DBGC ( tcp, "TCP %p connection deleted\n", tcp ); return; } /* If we have not had our SYN acknowledged (i.e. we are in * SYN_RCVD), pretend that it has been acknowledged so that we * can send a FIN without breaking things. */ if ( ! ( tcp->tcp_state & TCP_STATE_ACKED ( TCP_SYN ) ) ) tcp_rx_ack ( tcp, ( tcp->snd_seq + 1 ), 0 ); /* If we have no data remaining to send, start sending FIN */ if ( list_empty ( &tcp->queue ) ) { tcp->tcp_state |= TCP_STATE_SENT ( TCP_FIN ); tcp_dump_state ( tcp ); } } /*************************************************************************** * * Transmit data path * *************************************************************************** */ /** * Calculate transmission window * * @v tcp TCP connection * @ret len Maximum length that can be sent in a single packet */ static size_t tcp_xmit_win ( struct tcp_connection *tcp ) { size_t len; /* Not ready if we're not in a suitable connection state */ if ( ! TCP_CAN_SEND_DATA ( tcp->tcp_state ) ) return 0; /* Length is the minimum of the receiver's window and the path MTU */ len = tcp->snd_win; if ( len > TCP_PATH_MTU ) len = TCP_PATH_MTU; return len; } /** * Process TCP transmit queue * * @v tcp TCP connection * @v max_len Maximum length to process * @v dest I/O buffer to fill with data, or NULL * @v remove Remove data from queue * @ret len Length of data processed * * This processes at most @c max_len bytes from the TCP connection's * transmit queue. Data will be copied into the @c dest I/O buffer * (if provided) and, if @c remove is true, removed from the transmit * queue. */ static size_t tcp_process_queue ( struct tcp_connection *tcp, size_t max_len, struct io_buffer *dest, int remove ) { struct io_buffer *iobuf; struct io_buffer *tmp; size_t frag_len; size_t len = 0; list_for_each_entry_safe ( iobuf, tmp, &tcp->queue, list ) { frag_len = iob_len ( iobuf ); if ( frag_len > max_len ) frag_len = max_len; if ( dest ) { memcpy ( iob_put ( dest, frag_len ), iobuf->data, frag_len ); } if ( remove ) { iob_pull ( iobuf, frag_len ); if ( ! iob_len ( iobuf ) ) { list_del ( &iobuf->list ); free_iob ( iobuf ); } } len += frag_len; max_len -= frag_len; } return len; } /** * Transmit any outstanding data * * @v tcp TCP connection * @v force_send Force sending of packet * * Transmits any outstanding data on the connection. * * Note that even if an error is returned, the retransmission timer * will have been started if necessary, and so the stack will * eventually attempt to retransmit the failed packet. */ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) { struct io_buffer *iobuf; struct tcp_header *tcphdr; struct tcp_mss_option *mssopt; struct tcp_timestamp_padded_option *tsopt; void *payload; unsigned int flags; size_t len = 0; uint32_t seq_len; uint32_t app_win; uint32_t max_rcv_win; int rc; /* If retransmission timer is already running, do nothing */ if ( timer_running ( &tcp->timer ) ) return 0; /* Calculate both the actual (payload) and sequence space * lengths that we wish to transmit. */ if ( TCP_CAN_SEND_DATA ( tcp->tcp_state ) ) { len = tcp_process_queue ( tcp, tcp_xmit_win ( tcp ), NULL, 0 ); } seq_len = len; flags = TCP_FLAGS_SENDING ( tcp->tcp_state ); if ( flags & ( TCP_SYN | TCP_FIN ) ) { /* SYN or FIN consume one byte, and we can never send both */ assert ( ! ( ( flags & TCP_SYN ) && ( flags & TCP_FIN ) ) ); seq_len++; } tcp->snd_sent = seq_len; /* If we have nothing to transmit, stop now */ if ( ( seq_len == 0 ) && ! force_send ) return 0; /* If we are transmitting anything that requires * acknowledgement (i.e. consumes sequence space), start the * retransmission timer. Do this before attempting to * allocate the I/O buffer, in case allocation itself fails. */ if ( seq_len ) start_timer ( &tcp->timer ); /* Allocate I/O buffer */ iobuf = alloc_iob ( len + MAX_HDR_LEN ); if ( ! iobuf ) { DBGC ( tcp, "TCP %p could not allocate iobuf for %08x..%08x " "%08x\n", tcp, tcp->snd_seq, ( tcp->snd_seq + seq_len ), tcp->rcv_ack ); return -ENOMEM; } iob_reserve ( iobuf, MAX_HDR_LEN ); /* Fill data payload from transmit queue */ tcp_process_queue ( tcp, len, iobuf, 0 ); /* Expand receive window if possible */ // max_rcv_win = ( ( freemem * 3 ) / 4 ); //if ( max_rcv_win > TCP_MAX_WINDOW_SIZE ) max_rcv_win = TCP_MAX_WINDOW_SIZE; app_win = xfer_window ( &tcp->xfer ); if ( max_rcv_win > app_win ) max_rcv_win = app_win; max_rcv_win &= ~0x03; /* Keep everything dword-aligned */ if ( tcp->rcv_win < max_rcv_win ) tcp->rcv_win = max_rcv_win; /* Fill up the TCP header */ payload = iobuf->data; if ( flags & TCP_SYN ) { mssopt = iob_push ( iobuf, sizeof ( *mssopt ) ); mssopt->kind = TCP_OPTION_MSS; mssopt->length = sizeof ( *mssopt ); mssopt->mss = htons ( TCP_MSS ); } if ( ( flags & TCP_SYN ) || tcp->timestamps ) { tsopt = iob_push ( iobuf, sizeof ( *tsopt ) ); memset ( tsopt->nop, TCP_OPTION_NOP, sizeof ( tsopt->nop ) ); tsopt->tsopt.kind = TCP_OPTION_TS; tsopt->tsopt.length = sizeof ( tsopt->tsopt ); tsopt->tsopt.tsval = ntohl ( currticks() ); tsopt->tsopt.tsecr = ntohl ( tcp->ts_recent ); } if ( ! ( flags & TCP_SYN ) ) flags |= TCP_PSH; tcphdr = iob_push ( iobuf, sizeof ( *tcphdr ) ); memset ( tcphdr, 0, sizeof ( *tcphdr ) ); tcphdr->src = tcp->local_port; tcphdr->dest = tcp->peer.st_port; tcphdr->seq = htonl ( tcp->snd_seq ); tcphdr->ack = htonl ( tcp->rcv_ack ); tcphdr->hlen = ( ( payload - iobuf->data ) << 2 ); tcphdr->flags = flags; tcphdr->win = htons ( tcp->rcv_win ); tcphdr->csum = tcpip_chksum ( iobuf->data, iob_len ( iobuf ) ); /* Dump header */ DBGC2 ( tcp, "TCP %p TX %d->%d %08x..%08x %08x %4zd", tcp, ntohs ( tcphdr->src ), ntohs ( tcphdr->dest ), ntohl ( tcphdr->seq ), ( ntohl ( tcphdr->seq ) + seq_len ), ntohl ( tcphdr->ack ), len ); tcp_dump_flags ( tcp, tcphdr->flags ); DBGC2 ( tcp, "\n" ); /* Transmit packet */ if ( ( rc = tcpip_tx ( iobuf, &tcp_protocol, NULL, &tcp->peer, NULL, &tcphdr->csum ) ) != 0 ) { DBGC ( tcp, "TCP %p could not transmit %08x..%08x %08x: %s\n", tcp, tcp->snd_seq, ( tcp->snd_seq + tcp->snd_sent ), tcp->rcv_ack, strerror ( rc ) ); return rc; } return 0; } /** * Retransmission timer expired * * @v timer Retry timer * @v over Failure indicator */ static void tcp_expired ( struct retry_timer *timer, int over ) { struct tcp_connection *tcp = container_of ( timer, struct tcp_connection, timer ); int graceful_close = TCP_CLOSED_GRACEFULLY ( tcp->tcp_state ); DBGC ( tcp, "TCP %p timer %s in %s for %08x..%08x %08x\n", tcp, ( over ? "expired" : "fired" ), tcp_state ( tcp->tcp_state ), tcp->snd_seq, ( tcp->snd_seq + tcp->snd_sent ), tcp->rcv_ack ); assert ( ( tcp->tcp_state == TCP_SYN_SENT ) || ( tcp->tcp_state == TCP_SYN_RCVD ) || ( tcp->tcp_state == TCP_ESTABLISHED ) || ( tcp->tcp_state == TCP_FIN_WAIT_1 ) || ( tcp->tcp_state == TCP_TIME_WAIT ) || ( tcp->tcp_state == TCP_CLOSE_WAIT ) || ( tcp->tcp_state == TCP_CLOSING_OR_LAST_ACK ) ); if ( over || graceful_close ) { /* If we have finally timed out and given up, or if * this is the result of a graceful close, terminate * the connection */ tcp->tcp_state = TCP_CLOSED; tcp_dump_state ( tcp ); tcp_close ( tcp, -ETIMEDOUT ); } else { /* Otherwise, retransmit the packet */ tcp_xmit ( tcp, 0 ); } } /** * Send RST response to incoming packet * * @v in_tcphdr TCP header of incoming packet * @ret rc Return status code */ static int tcp_xmit_reset ( struct tcp_connection *tcp, struct sockaddr_tcpip *st_dest, struct tcp_header *in_tcphdr ) { struct io_buffer *iobuf; struct tcp_header *tcphdr; int rc; /* Allocate space for dataless TX buffer */ iobuf = alloc_iob ( MAX_HDR_LEN ); if ( ! iobuf ) { DBGC ( tcp, "TCP %p could not allocate iobuf for RST " "%08x..%08x %08x\n", tcp, ntohl ( in_tcphdr->ack ), ntohl ( in_tcphdr->ack ), ntohl ( in_tcphdr->seq ) ); return -ENOMEM; } iob_reserve ( iobuf, MAX_HDR_LEN ); /* Construct RST response */ tcphdr = iob_push ( iobuf, sizeof ( *tcphdr ) ); memset ( tcphdr, 0, sizeof ( *tcphdr ) ); tcphdr->src = in_tcphdr->dest; tcphdr->dest = in_tcphdr->src; tcphdr->seq = in_tcphdr->ack; tcphdr->ack = in_tcphdr->seq; tcphdr->hlen = ( ( sizeof ( *tcphdr ) / 4 ) << 4 ); tcphdr->flags = ( TCP_RST | TCP_ACK ); tcphdr->win = htons ( TCP_MAX_WINDOW_SIZE ); tcphdr->csum = tcpip_chksum ( iobuf->data, iob_len ( iobuf ) ); /* Dump header */ DBGC2 ( tcp, "TCP %p TX %d->%d %08x..%08x %08x %4d", tcp, ntohs ( tcphdr->src ), ntohs ( tcphdr->dest ), ntohl ( tcphdr->seq ), ( ntohl ( tcphdr->seq ) ), ntohl ( tcphdr->ack ), 0 ); tcp_dump_flags ( tcp, tcphdr->flags ); DBGC2 ( tcp, "\n" ); /* Transmit packet */ if ( ( rc = tcpip_tx ( iobuf, &tcp_protocol, NULL, st_dest, NULL, &tcphdr->csum ) ) != 0 ) { DBGC ( tcp, "TCP %p could not transmit RST %08x..%08x %08x: " "%s\n", tcp, ntohl ( in_tcphdr->ack ), ntohl ( in_tcphdr->ack ), ntohl ( in_tcphdr->seq ), strerror ( rc ) ); return rc; } return 0; } /*************************************************************************** * * Receive data path * *************************************************************************** */ /** * Identify TCP connection by local port number * * @v local_port Local port (in network-endian order) * @ret tcp TCP connection, or NULL */ static struct tcp_connection * tcp_demux ( unsigned int local_port ) { struct tcp_connection *tcp; list_for_each_entry ( tcp, &tcp_conns, list ) { if ( tcp->local_port == local_port ) return tcp; } return NULL; } /** * Parse TCP received options * * @v tcp TCP connection * @v data Raw options data * @v len Raw options length * @v options Options structure to fill in */ static void tcp_rx_opts ( struct tcp_connection *tcp, const void *data, size_t len, struct tcp_options *options ) { const void *end = ( data + len ); const struct tcp_option *option; unsigned int kind; memset ( options, 0, sizeof ( *options ) ); while ( data < end ) { option = data; kind = option->kind; if ( kind == TCP_OPTION_END ) return; if ( kind == TCP_OPTION_NOP ) { data++; continue; } switch ( kind ) { case TCP_OPTION_MSS: options->mssopt = data; break; case TCP_OPTION_TS: options->tsopt = data; break; default: DBGC ( tcp, "TCP %p received unknown option %d\n", tcp, kind ); break; } data += option->length; } } /** * Consume received sequence space * * @v tcp TCP connection * @v seq_len Sequence space length to consume */ static void tcp_rx_seq ( struct tcp_connection *tcp, uint32_t seq_len ) { tcp->rcv_ack += seq_len; if ( tcp->rcv_win > seq_len ) { tcp->rcv_win -= seq_len; } else { tcp->rcv_win = 0; } } /** * Handle TCP received SYN * * @v tcp TCP connection * @v seq SEQ value (in host-endian order) * @v options TCP options * @ret rc Return status code */ static int tcp_rx_syn ( struct tcp_connection *tcp, uint32_t seq, struct tcp_options *options ) { /* Synchronise sequence numbers on first SYN */ if ( ! ( tcp->tcp_state & TCP_STATE_RCVD ( TCP_SYN ) ) ) { tcp->rcv_ack = seq; if ( options->tsopt ) tcp->timestamps = 1; } /* Ignore duplicate SYN */ if ( ( tcp->rcv_ack - seq ) > 0 ) return 0; /* Mark SYN as received and start sending ACKs with each packet */ tcp->tcp_state |= ( TCP_STATE_SENT ( TCP_ACK ) | TCP_STATE_RCVD ( TCP_SYN ) ); /* Acknowledge SYN */ tcp_rx_seq ( tcp, 1 ); return 0; } /** * Handle TCP received ACK * * @v tcp TCP connection * @v ack ACK value (in host-endian order) * @v win WIN value (in host-endian order) * @ret rc Return status code */ static int tcp_rx_ack ( struct tcp_connection *tcp, uint32_t ack, uint32_t win ) { uint32_t ack_len = ( ack - tcp->snd_seq ); size_t len; unsigned int acked_flags; /* Check for out-of-range or old duplicate ACKs */ if ( ack_len > tcp->snd_sent ) { DBGC ( tcp, "TCP %p received ACK for %08x..%08x, " "sent only %08x..%08x\n", tcp, tcp->snd_seq, ( tcp->snd_seq + ack_len ), tcp->snd_seq, ( tcp->snd_seq + tcp->snd_sent ) ); if ( TCP_HAS_BEEN_ESTABLISHED ( tcp->tcp_state ) ) { /* Just ignore what might be old duplicate ACKs */ return 0; } else { /* Send RST if an out-of-range ACK is received * on a not-yet-established connection, as per * RFC 793. */ return -EINVAL; } } /* Ignore ACKs that don't actually acknowledge any new data. * (In particular, do not stop the retransmission timer; this * avoids creating a sorceror's apprentice syndrome when a * duplicate ACK is received and we still have data in our * transmit queue.) */ if ( ack_len == 0 ) return 0; /* Stop the retransmission timer */ stop_timer ( &tcp->timer ); /* Determine acknowledged flags and data length */ len = ack_len; acked_flags = ( TCP_FLAGS_SENDING ( tcp->tcp_state ) & ( TCP_SYN | TCP_FIN ) ); if ( acked_flags ) len--; /* Update SEQ and sent counters, and window size */ tcp->snd_seq = ack; tcp->snd_sent = 0; tcp->snd_win = win; /* Remove any acknowledged data from transmit queue */ tcp_process_queue ( tcp, len, NULL, 1 ); /* Mark SYN/FIN as acknowledged if applicable. */ if ( acked_flags ) tcp->tcp_state |= TCP_STATE_ACKED ( acked_flags ); /* Start sending FIN if we've had all possible data ACKed */ if ( list_empty ( &tcp->queue ) && tcp->xfer_closed ) tcp->tcp_state |= TCP_STATE_SENT ( TCP_FIN ); return 0; } /** * Handle TCP received data * * @v tcp TCP connection * @v seq SEQ value (in host-endian order) * @v iobuf I/O buffer * @ret rc Return status code * * This function takes ownership of the I/O buffer. */ static int tcp_rx_data ( struct tcp_connection *tcp, uint32_t seq, struct io_buffer *iobuf ) { uint32_t already_rcvd; uint32_t len; int rc; /* Ignore duplicate or out-of-order data */ already_rcvd = ( tcp->rcv_ack - seq ); len = iob_len ( iobuf ); if ( already_rcvd >= len ) { free_iob ( iobuf ); return 0; } iob_pull ( iobuf, already_rcvd ); len -= already_rcvd; /* Deliver data to application */ if ( ( rc = xfer_deliver_iob ( &tcp->xfer, iobuf ) ) != 0 ) { DBGC ( tcp, "TCP %p could not deliver %08x..%08x: %s\n", tcp, seq, ( seq + len ), strerror ( rc ) ); return rc; } /* Acknowledge new data */ tcp_rx_seq ( tcp, len ); return 0; } /** * Handle TCP received FIN * * @v tcp TCP connection * @v seq SEQ value (in host-endian order) * @ret rc Return status code */ static int tcp_rx_fin ( struct tcp_connection *tcp, uint32_t seq ) { /* Ignore duplicate or out-of-order FIN */ if ( ( tcp->rcv_ack - seq ) > 0 ) return 0; /* Mark FIN as received and acknowledge it */ tcp->tcp_state |= TCP_STATE_RCVD ( TCP_FIN ); tcp_rx_seq ( tcp, 1 ); /* Close connection */ tcp_close ( tcp, 0 ); return 0; } /** * Handle TCP received RST * * @v tcp TCP connection * @v seq SEQ value (in host-endian order) * @ret rc Return status code */ static int tcp_rx_rst ( struct tcp_connection *tcp, uint32_t seq ) { /* Accept RST only if it falls within the window. If we have * not yet received a SYN, then we have no window to test * against, so fall back to checking that our SYN has been * ACKed. */ if ( tcp->tcp_state & TCP_STATE_RCVD ( TCP_SYN ) ) { if ( ( seq - tcp->rcv_ack ) >= tcp->rcv_win ) return 0; } else { if ( ! ( tcp->tcp_state & TCP_STATE_ACKED ( TCP_SYN ) ) ) return 0; } /* Abort connection */ tcp->tcp_state = TCP_CLOSED; tcp_dump_state ( tcp ); tcp_close ( tcp, -ECONNRESET ); DBGC ( tcp, "TCP %p connection reset by peer\n", tcp ); return -ECONNRESET; } /** * Process received packet * * @v iobuf I/O buffer * @v st_src Partially-filled source address * @v st_dest Partially-filled destination address * @v pshdr_csum Pseudo-header checksum * @ret rc Return status code */ static int tcp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest __unused, uint16_t pshdr_csum ) { struct tcp_header *tcphdr = iobuf->data; struct tcp_connection *tcp; struct tcp_options options; size_t hlen; uint16_t csum; uint32_t start_seq; uint32_t seq; uint32_t ack; uint32_t win; unsigned int flags; size_t len; int rc; /* Sanity check packet */ if ( iob_len ( iobuf ) < sizeof ( *tcphdr ) ) { DBG ( "TCP packet too short at %zd bytes (min %zd bytes)\n", iob_len ( iobuf ), sizeof ( *tcphdr ) ); rc = -EINVAL; goto discard; } hlen = ( ( tcphdr->hlen & TCP_MASK_HLEN ) / 16 ) * 4; if ( hlen < sizeof ( *tcphdr ) ) { DBG ( "TCP header too short at %zd bytes (min %zd bytes)\n", hlen, sizeof ( *tcphdr ) ); rc = -EINVAL; goto discard; } if ( hlen > iob_len ( iobuf ) ) { DBG ( "TCP header too long at %zd bytes (max %zd bytes)\n", hlen, iob_len ( iobuf ) ); rc = -EINVAL; goto discard; } csum = tcpip_continue_chksum ( pshdr_csum, iobuf->data, iob_len ( iobuf ) ); if ( csum != 0 ) { DBG ( "TCP checksum incorrect (is %04x including checksum " "field, should be 0000)\n", csum ); rc = -EINVAL; goto discard; } /* Parse parameters from header and strip header */ tcp = tcp_demux ( tcphdr->dest ); start_seq = seq = ntohl ( tcphdr->seq ); ack = ntohl ( tcphdr->ack ); win = ntohs ( tcphdr->win ); flags = tcphdr->flags; tcp_rx_opts ( tcp, ( ( ( void * ) tcphdr ) + sizeof ( *tcphdr ) ), ( hlen - sizeof ( *tcphdr ) ), &options ); iob_pull ( iobuf, hlen ); len = iob_len ( iobuf ); /* Dump header */ DBGC2 ( tcp, "TCP %p RX %d<-%d %08x %08x..%08zx %4zd", tcp, ntohs ( tcphdr->dest ), ntohs ( tcphdr->src ), ntohl ( tcphdr->ack ), ntohl ( tcphdr->seq ), ( ntohl ( tcphdr->seq ) + len + ( ( tcphdr->flags & ( TCP_SYN | TCP_FIN ) ) ? 1 : 0 )), len); tcp_dump_flags ( tcp, tcphdr->flags ); DBGC2 ( tcp, "\n" ); /* If no connection was found, send RST */ if ( ! tcp ) { tcp_xmit_reset ( tcp, st_src, tcphdr ); rc = -ENOTCONN; goto discard; } /* Handle ACK, if present */ if ( flags & TCP_ACK ) { if ( ( rc = tcp_rx_ack ( tcp, ack, win ) ) != 0 ) { tcp_xmit_reset ( tcp, st_src, tcphdr ); goto discard; } } /* Handle SYN, if present */ if ( flags & TCP_SYN ) { tcp_rx_syn ( tcp, seq, &options ); seq++; } /* Handle RST, if present */ if ( flags & TCP_RST ) { if ( ( rc = tcp_rx_rst ( tcp, seq ) ) != 0 ) goto discard; } /* Handle new data, if any */ tcp_rx_data ( tcp, seq, iobuf ); seq += len; /* Handle FIN, if present */ if ( flags & TCP_FIN ) { tcp_rx_fin ( tcp, seq ); seq++; } /* Update timestamp, if present and applicable */ if ( ( seq == tcp->rcv_ack ) && options.tsopt ) tcp->ts_recent = ntohl ( options.tsopt->tsval ); /* Dump out any state change as a result of the received packet */ tcp_dump_state ( tcp ); /* Send out any pending data. We force sending a reply if either * * a) the peer is expecting an ACK (i.e. consumed sequence space), or * b) either end of the packet was outside the receive window * * Case (b) enables us to support TCP keepalives using * zero-length packets, which we would otherwise ignore. Note * that for case (b), we need *only* consider zero-length * packets, since non-zero-length packets will already be * caught by case (a). */ tcp_xmit ( tcp, ( ( start_seq != seq ) || ( ( seq - tcp->rcv_ack ) > tcp->rcv_win ) ) ); /* If this packet was the last we expect to receive, set up * timer to expire and cause the connection to be freed. */ if ( TCP_CLOSED_GRACEFULLY ( tcp->tcp_state ) ) { tcp->timer.timeout = ( 2 * TCP_MSL ); start_timer ( &tcp->timer ); } return 0; discard: /* Free received packet */ free_iob ( iobuf ); return rc; } /** TCP protocol */ struct tcpip_protocol tcp_protocol __tcpip_protocol = { .name = "TCP", .rx = tcp_rx, .tcpip_proto = IP_TCP, }; /*************************************************************************** * * Data transfer interface * *************************************************************************** */ /** * Close interface * * @v xfer Data transfer interface * @v rc Reason for close */ static void tcp_xfer_close ( struct xfer_interface *xfer, int rc ) { struct tcp_connection *tcp = container_of ( xfer, struct tcp_connection, xfer ); /* Close data transfer interface */ tcp_close ( tcp, rc ); /* Transmit FIN, if possible */ tcp_xmit ( tcp, 0 ); } /** * Check flow control window * * @v xfer Data transfer interface * @ret len Length of window */ static size_t tcp_xfer_window ( struct xfer_interface *xfer ) { struct tcp_connection *tcp = container_of ( xfer, struct tcp_connection, xfer ); /* Not ready if data queue is non-empty. This imposes a limit * of only one unACKed packet in the TX queue at any time; we * do this to conserve memory usage. */ if ( ! list_empty ( &tcp->queue ) ) return 0; /* Return TCP window length */ return tcp_xmit_win ( tcp ); } /** * Deliver datagram as I/O buffer * * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ static int tcp_xfer_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta __unused ) { struct tcp_connection *tcp = container_of ( xfer, struct tcp_connection, xfer ); /* Enqueue packet */ list_add_tail ( &iobuf->list, &tcp->queue ); /* Transmit data, if possible */ tcp_xmit ( tcp, 0 ); return 0; } /** TCP data transfer interface operations */ static struct xfer_interface_operations tcp_xfer_operations = { .close = tcp_xfer_close, .vredirect = ignore_xfer_vredirect, .window = tcp_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = tcp_xfer_deliver_iob, .deliver_raw = xfer_deliver_as_iob, }; /*************************************************************************** * * Openers * *************************************************************************** */ /** TCP socket opener */ struct socket_opener tcp_socket_opener __socket_opener = { .semantics = TCP_SOCK_STREAM, .family = AF_INET, .open = tcp_open, }; /** Linkage hack */ int tcp_sock_stream = TCP_SOCK_STREAM; /** * Open TCP URI * * @v xfer Data transfer interface * @v uri URI * @ret rc Return status code */ static int tcp_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { struct sockaddr_tcpip peer; /* Sanity check */ if ( ! uri->host ) return -EINVAL; memset ( &peer, 0, sizeof ( peer ) ); peer.st_port = htons ( uri_port ( uri, 0 ) ); return xfer_open_named_socket ( xfer, SOCK_STREAM, ( struct sockaddr * ) &peer, uri->host, NULL ); } /** TCP URI opener */ struct uri_opener tcp_uri_opener __uri_opener = { .scheme = "tcp", .open = tcp_open_uri, }; debian/grub-extras/disabled/gpxe/src/net/udp/0000775000000000000000000000000012524676037016326 5ustar debian/grub-extras/disabled/gpxe/src/net/udp/slam.c0000664000000000000000000005256212524662415017433 0ustar /* * Copyright (C) 2008 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * Scalable Local Area Multicast protocol * * The SLAM protocol is supported only by Etherboot; it was designed * and implemented by Eric Biederman. A server implementation is * available in contrib/mini-slamd. There does not appear to be any * documentation beyond a few sparse comments in Etherboot's * proto_slam.c. * * SLAM packets use three types of data field: * * Nul : A single NUL (0) byte, used as a list terminator * * Raw : A block of raw data * * Int : A variable-length integer, in big-endian order. The length * of the integer is encoded in the most significant three bits. * * Packets received by the client have the following layout: * * Int : Transaction identifier. This is an opaque value. * * Int : Total number of bytes in the transfer. * * Int : Block size, in bytes. * * Int : Packet sequence number within the transfer (if this packet * contains data). * * Raw : Packet data (if this packet contains data). * * Packets transmitted by the client consist of a run-length-encoded * representation of the received-blocks bitmap, looking something * like: * * Int : Number of consecutive successfully-received packets * Int : Number of consecutive missing packets * Int : Number of consecutive successfully-received packets * Int : Number of consecutive missing packets * .... * Nul * */ FEATURE ( FEATURE_PROTOCOL, "SLAM", DHCP_EB_FEATURE_SLAM, 1 ); /** Default SLAM server port */ #define SLAM_DEFAULT_PORT 10000 /** Default SLAM multicast IP address */ #define SLAM_DEFAULT_MULTICAST_IP \ ( ( 239 << 24 ) | ( 255 << 16 ) | ( 1 << 8 ) | ( 1 << 0 ) ) /** Default SLAM multicast port */ #define SLAM_DEFAULT_MULTICAST_PORT 10000 /** Maximum SLAM header length */ #define SLAM_MAX_HEADER_LEN ( 7 /* transaction id */ + 7 /* total_bytes */ + \ 7 /* block_size */ ) /** Maximum number of blocks to request per NACK * * This is a policy decision equivalent to selecting a TCP window * size. */ #define SLAM_MAX_BLOCKS_PER_NACK 4 /** Maximum SLAM NACK length * * We only ever send a NACK for a single range of up to @c * SLAM_MAX_BLOCKS_PER_NACK blocks. */ #define SLAM_MAX_NACK_LEN ( 7 /* block */ + 7 /* #blocks */ + 1 /* NUL */ ) /** SLAM slave timeout */ #define SLAM_SLAVE_TIMEOUT ( 1 * TICKS_PER_SEC ) /** A SLAM request */ struct slam_request { /** Reference counter */ struct refcnt refcnt; /** Data transfer interface */ struct xfer_interface xfer; /** Unicast socket */ struct xfer_interface socket; /** Multicast socket */ struct xfer_interface mc_socket; /** Master client retry timer */ struct retry_timer master_timer; /** Slave client retry timer */ struct retry_timer slave_timer; /** Cached header */ uint8_t header[SLAM_MAX_HEADER_LEN]; /** Size of cached header */ size_t header_len; /** Total number of bytes in transfer */ unsigned long total_bytes; /** Transfer block size */ unsigned long block_size; /** Number of blocks in transfer */ unsigned long num_blocks; /** Block bitmap */ struct bitmap bitmap; /** NACK sent flag */ int nack_sent; }; /** * Free a SLAM request * * @v refcnt Reference counter */ static void slam_free ( struct refcnt *refcnt ) { struct slam_request *slam = container_of ( refcnt, struct slam_request, refcnt ); bitmap_free ( &slam->bitmap ); free ( slam ); } /** * Mark SLAM request as complete * * @v slam SLAM request * @v rc Return status code */ static void slam_finished ( struct slam_request *slam, int rc ) { static const uint8_t slam_disconnect[] = { 0 }; DBGC ( slam, "SLAM %p finished with status code %d (%s)\n", slam, rc, strerror ( rc ) ); /* Send a disconnect message if we ever sent anything to the * server. */ if ( slam->nack_sent ) { xfer_deliver_raw ( &slam->socket, slam_disconnect, sizeof ( slam_disconnect ) ); } /* Stop the retry timers */ stop_timer ( &slam->master_timer ); stop_timer ( &slam->slave_timer ); /* Close all data transfer interfaces */ xfer_nullify ( &slam->socket ); xfer_close ( &slam->socket, rc ); xfer_nullify ( &slam->mc_socket ); xfer_close ( &slam->mc_socket, rc ); xfer_nullify ( &slam->xfer ); xfer_close ( &slam->xfer, rc ); } /**************************************************************************** * * TX datapath * */ /** * Add a variable-length value to a SLAM packet * * @v slam SLAM request * @v iobuf I/O buffer * @v value Value to add * @ret rc Return status code * * Adds a variable-length value to the end of an I/O buffer. Will * always leave at least one byte of tailroom in the I/O buffer (to * allow space for the terminating NUL). */ static int slam_put_value ( struct slam_request *slam, struct io_buffer *iobuf, unsigned long value ) { uint8_t *data; size_t len; unsigned int i; /* Calculate variable length required to store value. Always * leave at least one byte in the I/O buffer. */ len = ( ( flsl ( value ) + 10 ) / 8 ); if ( len >= iob_tailroom ( iobuf ) ) { DBGC2 ( slam, "SLAM %p cannot add %zd-byte value\n", slam, len ); return -ENOBUFS; } /* There is no valid way within the protocol that we can end * up trying to push a full-sized long (i.e. without space for * the length encoding). */ assert ( len <= sizeof ( value ) ); /* Add value */ data = iob_put ( iobuf, len ); for ( i = len ; i-- ; ) { data[i] = value; value >>= 8; } *data |= ( len << 5 ); assert ( value == 0 ); return 0; } /** * Send SLAM NACK packet * * @v slam SLAM request * @ret rc Return status code */ static int slam_tx_nack ( struct slam_request *slam ) { struct io_buffer *iobuf; unsigned long first_block; unsigned long num_blocks; uint8_t *nul; int rc; /* Mark NACK as sent, so that we know we have to disconnect later */ slam->nack_sent = 1; /* Allocate I/O buffer */ iobuf = xfer_alloc_iob ( &slam->socket, SLAM_MAX_NACK_LEN ); if ( ! iobuf ) { DBGC ( slam, "SLAM %p could not allocate I/O buffer\n", slam ); return -ENOMEM; } /* Construct NACK. We always request only a single packet; * this allows us to force multicast-TFTP-style flow control * on the SLAM server, which will otherwise just blast the * data out as fast as it can. On a gigabit network, without * RX checksumming, this would inevitably cause packet drops. */ first_block = bitmap_first_gap ( &slam->bitmap ); for ( num_blocks = 1 ; ; num_blocks++ ) { if ( num_blocks >= SLAM_MAX_BLOCKS_PER_NACK ) break; if ( ( first_block + num_blocks ) >= slam->num_blocks ) break; if ( bitmap_test ( &slam->bitmap, ( first_block + num_blocks ) ) ) break; } if ( first_block ) { DBGCP ( slam, "SLAM %p transmitting NACK for blocks " "%ld-%ld\n", slam, first_block, ( first_block + num_blocks - 1 ) ); } else { DBGC ( slam, "SLAM %p transmitting initial NACK for blocks " "0-%ld\n", slam, ( num_blocks - 1 ) ); } if ( ( rc = slam_put_value ( slam, iobuf, first_block ) ) != 0 ) return rc; if ( ( rc = slam_put_value ( slam, iobuf, num_blocks ) ) != 0 ) return rc; nul = iob_put ( iobuf, 1 ); *nul = 0; /* Transmit packet */ return xfer_deliver_iob ( &slam->socket, iobuf ); } /** * Handle SLAM master client retry timer expiry * * @v timer Master retry timer * @v fail Failure indicator */ static void slam_master_timer_expired ( struct retry_timer *timer, int fail ) { struct slam_request *slam = container_of ( timer, struct slam_request, master_timer ); if ( fail ) { /* Allow timer to stop running. We will terminate the * connection only if the slave timer times out. */ DBGC ( slam, "SLAM %p giving up acting as master client\n", slam ); } else { /* Retransmit NACK */ start_timer ( timer ); slam_tx_nack ( slam ); } } /** * Handle SLAM slave client retry timer expiry * * @v timer Master retry timer * @v fail Failure indicator */ static void slam_slave_timer_expired ( struct retry_timer *timer, int fail ) { struct slam_request *slam = container_of ( timer, struct slam_request, slave_timer ); if ( fail ) { /* Terminate connection */ slam_finished ( slam, -ETIMEDOUT ); } else { /* Try sending a NACK */ DBGC ( slam, "SLAM %p trying to become master client\n", slam ); start_timer ( timer ); slam_tx_nack ( slam ); } } /**************************************************************************** * * RX datapath * */ /** * Read and strip a variable-length value from a SLAM packet * * @v slam SLAM request * @v iobuf I/O buffer * @v value Value to fill in, or NULL to ignore value * @ret rc Return status code * * Reads a variable-length value from the start of the I/O buffer. */ static int slam_pull_value ( struct slam_request *slam, struct io_buffer *iobuf, unsigned long *value ) { uint8_t *data; size_t len; /* Sanity check */ if ( iob_len ( iobuf ) == 0 ) { DBGC ( slam, "SLAM %p empty value\n", slam ); return -EINVAL; } /* Read and verify length of value */ data = iobuf->data; len = ( *data >> 5 ); if ( ( len == 0 ) || ( value && ( len > sizeof ( *value ) ) ) ) { DBGC ( slam, "SLAM %p invalid value length %zd bytes\n", slam, len ); return -EINVAL; } if ( len > iob_len ( iobuf ) ) { DBGC ( slam, "SLAM %p value extends beyond I/O buffer\n", slam ); return -EINVAL; } /* Read value */ iob_pull ( iobuf, len ); *value = ( *data & 0x1f ); while ( --len ) { *value <<= 8; *value |= *(++data); } return 0; } /** * Read and strip SLAM header * * @v slam SLAM request * @v iobuf I/O buffer * @ret rc Return status code */ static int slam_pull_header ( struct slam_request *slam, struct io_buffer *iobuf ) { void *header = iobuf->data; int rc; /* If header matches cached header, just pull it and return */ if ( ( slam->header_len <= iob_len ( iobuf ) ) && ( memcmp ( slam->header, iobuf->data, slam->header_len ) == 0 )){ iob_pull ( iobuf, slam->header_len ); return 0; } DBGC ( slam, "SLAM %p detected changed header; resetting\n", slam ); /* Read and strip transaction ID, total number of bytes, and * block size. */ if ( ( rc = slam_pull_value ( slam, iobuf, NULL ) ) != 0 ) return rc; if ( ( rc = slam_pull_value ( slam, iobuf, &slam->total_bytes ) ) != 0 ) return rc; if ( ( rc = slam_pull_value ( slam, iobuf, &slam->block_size ) ) != 0 ) return rc; /* Update the cached header */ slam->header_len = ( iobuf->data - header ); assert ( slam->header_len <= sizeof ( slam->header ) ); memcpy ( slam->header, header, slam->header_len ); /* Calculate number of blocks */ slam->num_blocks = ( ( slam->total_bytes + slam->block_size - 1 ) / slam->block_size ); DBGC ( slam, "SLAM %p has total bytes %ld, block size %ld, num " "blocks %ld\n", slam, slam->total_bytes, slam->block_size, slam->num_blocks ); /* Discard and reset the bitmap */ bitmap_free ( &slam->bitmap ); memset ( &slam->bitmap, 0, sizeof ( slam->bitmap ) ); /* Allocate a new bitmap */ if ( ( rc = bitmap_resize ( &slam->bitmap, slam->num_blocks ) ) != 0 ) { /* Failure to allocate a bitmap is fatal */ DBGC ( slam, "SLAM %p could not allocate bitmap for %ld " "blocks: %s\n", slam, slam->num_blocks, strerror ( rc ) ); slam_finished ( slam, rc ); return rc; } /* Notify recipient of file size */ xfer_seek ( &slam->xfer, slam->total_bytes, SEEK_SET ); return 0; } /** * Receive SLAM data packet * * @v mc_socket SLAM multicast socket * @v iobuf I/O buffer * @ret rc Return status code */ static int slam_mc_socket_deliver ( struct xfer_interface *mc_socket, struct io_buffer *iobuf, struct xfer_metadata *rx_meta __unused ) { struct slam_request *slam = container_of ( mc_socket, struct slam_request, mc_socket ); struct xfer_metadata meta; unsigned long packet; size_t len; int rc; /* Stop the master client timer. Restart the slave client timer. */ stop_timer ( &slam->master_timer ); stop_timer ( &slam->slave_timer ); start_timer_fixed ( &slam->slave_timer, SLAM_SLAVE_TIMEOUT ); /* Read and strip packet header */ if ( ( rc = slam_pull_header ( slam, iobuf ) ) != 0 ) goto err_discard; /* Read and strip packet number */ if ( ( rc = slam_pull_value ( slam, iobuf, &packet ) ) != 0 ) goto err_discard; /* Sanity check packet number */ if ( packet >= slam->num_blocks ) { DBGC ( slam, "SLAM %p received out-of-range packet %ld " "(num_blocks=%ld)\n", slam, packet, slam->num_blocks ); rc = -EINVAL; goto err_discard; } /* Sanity check length */ len = iob_len ( iobuf ); if ( len > slam->block_size ) { DBGC ( slam, "SLAM %p received oversize packet of %zd bytes " "(block_size=%ld)\n", slam, len, slam->block_size ); rc = -EINVAL; goto err_discard; } if ( ( packet != ( slam->num_blocks - 1 ) ) && ( len < slam->block_size ) ) { DBGC ( slam, "SLAM %p received short packet of %zd bytes " "(block_size=%ld)\n", slam, len, slam->block_size ); rc = -EINVAL; goto err_discard; } /* If we have already seen this packet, discard it */ if ( bitmap_test ( &slam->bitmap, packet ) ) { goto discard; } /* Pass to recipient */ memset ( &meta, 0, sizeof ( meta ) ); meta.whence = SEEK_SET; meta.offset = ( packet * slam->block_size ); if ( ( rc = xfer_deliver_iob_meta ( &slam->xfer, iobuf, &meta ) ) != 0 ) goto err; /* Mark block as received */ bitmap_set ( &slam->bitmap, packet ); /* If we have received all blocks, terminate */ if ( bitmap_full ( &slam->bitmap ) ) slam_finished ( slam, 0 ); return 0; err_discard: discard: free_iob ( iobuf ); err: return rc; } /** * Receive SLAM non-data packet * * @v socket SLAM unicast socket * @v iobuf I/O buffer * @ret rc Return status code */ static int slam_socket_deliver ( struct xfer_interface *socket, struct io_buffer *iobuf, struct xfer_metadata *rx_meta __unused ) { struct slam_request *slam = container_of ( socket, struct slam_request, socket ); int rc; /* Restart the master client timer */ stop_timer ( &slam->master_timer ); start_timer ( &slam->master_timer ); /* Read and strip packet header */ if ( ( rc = slam_pull_header ( slam, iobuf ) ) != 0 ) goto discard; /* Sanity check */ if ( iob_len ( iobuf ) != 0 ) { DBGC ( slam, "SLAM %p received trailing garbage:\n", slam ); DBGC_HD ( slam, iobuf->data, iob_len ( iobuf ) ); rc = -EINVAL; goto discard; } /* Discard packet */ free_iob ( iobuf ); /* Send NACK in reply */ slam_tx_nack ( slam ); return 0; discard: free_iob ( iobuf ); return rc; } /** * Close SLAM unicast socket * * @v socket SLAM unicast socket * @v rc Reason for close */ static void slam_socket_close ( struct xfer_interface *socket, int rc ) { struct slam_request *slam = container_of ( socket, struct slam_request, socket ); DBGC ( slam, "SLAM %p unicast socket closed: %s\n", slam, strerror ( rc ) ); slam_finished ( slam, rc ); } /** SLAM unicast socket data transfer operations */ static struct xfer_interface_operations slam_socket_operations = { .close = slam_socket_close, .vredirect = xfer_vreopen, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = slam_socket_deliver, .deliver_raw = xfer_deliver_as_iob, }; /** * Close SLAM multicast socket * * @v mc_socket SLAM multicast socket * @v rc Reason for close */ static void slam_mc_socket_close ( struct xfer_interface *mc_socket, int rc ){ struct slam_request *slam = container_of ( mc_socket, struct slam_request, mc_socket ); DBGC ( slam, "SLAM %p multicast socket closed: %s\n", slam, strerror ( rc ) ); slam_finished ( slam, rc ); } /** SLAM multicast socket data transfer operations */ static struct xfer_interface_operations slam_mc_socket_operations = { .close = slam_mc_socket_close, .vredirect = xfer_vreopen, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = slam_mc_socket_deliver, .deliver_raw = xfer_deliver_as_iob, }; /**************************************************************************** * * Data transfer interface * */ /** * Close SLAM data transfer interface * * @v xfer SLAM data transfer interface * @v rc Reason for close */ static void slam_xfer_close ( struct xfer_interface *xfer, int rc ) { struct slam_request *slam = container_of ( xfer, struct slam_request, xfer ); DBGC ( slam, "SLAM %p data transfer interface closed: %s\n", slam, strerror ( rc ) ); slam_finished ( slam, rc ); } /** SLAM data transfer operations */ static struct xfer_interface_operations slam_xfer_operations = { .close = slam_xfer_close, .vredirect = ignore_xfer_vredirect, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, .deliver_raw = ignore_xfer_deliver_raw, }; /** * Parse SLAM URI multicast address * * @v slam SLAM request * @v path Path portion of x-slam:// URI * @v address Socket address to fill in * @ret rc Return status code */ static int slam_parse_multicast_address ( struct slam_request *slam, const char *path, struct sockaddr_in *address ) { char path_dup[ strlen ( path ) /* no +1 */ ]; char *sep; char *end; /* Create temporary copy of path, minus the leading '/' */ assert ( *path == '/' ); memcpy ( path_dup, ( path + 1 ) , sizeof ( path_dup ) ); /* Parse port, if present */ sep = strchr ( path_dup, ':' ); if ( sep ) { *(sep++) = '\0'; address->sin_port = htons ( strtoul ( sep, &end, 0 ) ); if ( *end != '\0' ) { DBGC ( slam, "SLAM %p invalid multicast port " "\"%s\"\n", slam, sep ); return -EINVAL; } } /* Parse address */ if ( inet_aton ( path_dup, &address->sin_addr ) == 0 ) { DBGC ( slam, "SLAM %p invalid multicast address \"%s\"\n", slam, path_dup ); return -EINVAL; } return 0; } /** * Initiate a SLAM request * * @v xfer Data transfer interface * @v uri Uniform Resource Identifier * @ret rc Return status code */ static int slam_open ( struct xfer_interface *xfer, struct uri *uri ) { static const struct sockaddr_in default_multicast = { .sin_family = AF_INET, .sin_port = htons ( SLAM_DEFAULT_MULTICAST_PORT ), .sin_addr = { htonl ( SLAM_DEFAULT_MULTICAST_IP ) }, }; struct slam_request *slam; struct sockaddr_tcpip server; struct sockaddr_in multicast; int rc; /* Sanity checks */ if ( ! uri->host ) return -EINVAL; /* Allocate and populate structure */ slam = zalloc ( sizeof ( *slam ) ); if ( ! slam ) return -ENOMEM; slam->refcnt.free = slam_free; xfer_init ( &slam->xfer, &slam_xfer_operations, &slam->refcnt ); xfer_init ( &slam->socket, &slam_socket_operations, &slam->refcnt ); xfer_init ( &slam->mc_socket, &slam_mc_socket_operations, &slam->refcnt ); slam->master_timer.expired = slam_master_timer_expired; slam->slave_timer.expired = slam_slave_timer_expired; /* Fake an invalid cached header of { 0x00, ... } */ slam->header_len = 1; /* Fake parameters for initial NACK */ slam->num_blocks = 1; if ( ( rc = bitmap_resize ( &slam->bitmap, 1 ) ) != 0 ) { DBGC ( slam, "SLAM %p could not allocate initial bitmap: " "%s\n", slam, strerror ( rc ) ); goto err; } /* Open unicast socket */ memset ( &server, 0, sizeof ( server ) ); server.st_port = htons ( uri_port ( uri, SLAM_DEFAULT_PORT ) ); if ( ( rc = xfer_open_named_socket ( &slam->socket, SOCK_DGRAM, ( struct sockaddr * ) &server, uri->host, NULL ) ) != 0 ) { DBGC ( slam, "SLAM %p could not open unicast socket: %s\n", slam, strerror ( rc ) ); goto err; } /* Open multicast socket */ memcpy ( &multicast, &default_multicast, sizeof ( multicast ) ); if ( uri->path && ( ( rc = slam_parse_multicast_address ( slam, uri->path, &multicast ) ) != 0 ) ) { goto err; } if ( ( rc = xfer_open_socket ( &slam->mc_socket, SOCK_DGRAM, ( struct sockaddr * ) &multicast, ( struct sockaddr * ) &multicast ) ) != 0 ) { DBGC ( slam, "SLAM %p could not open multicast socket: %s\n", slam, strerror ( rc ) ); goto err; } /* Start slave retry timer */ start_timer_fixed ( &slam->slave_timer, SLAM_SLAVE_TIMEOUT ); /* Attach to parent interface, mortalise self, and return */ xfer_plug_plug ( &slam->xfer, xfer ); ref_put ( &slam->refcnt ); return 0; err: slam_finished ( slam, rc ); ref_put ( &slam->refcnt ); return rc; } /** SLAM URI opener */ struct uri_opener slam_uri_opener __uri_opener = { .scheme = "x-slam", .open = slam_open, }; debian/grub-extras/disabled/gpxe/src/net/udp/dns.c0000664000000000000000000003532412524662415017260 0ustar /* * Copyright (C) 2006 Michael Brown . * * Portions copyright (C) 2004 Anselm M. Hoffmeister * . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * DNS protocol * */ FEATURE ( FEATURE_PROTOCOL, "DNS", DHCP_EB_FEATURE_DNS, 1 ); /** The DNS server */ static struct sockaddr_tcpip nameserver = { .st_port = htons ( DNS_PORT ), }; /** The local domain */ static char *localdomain; /** A DNS request */ struct dns_request { /** Reference counter */ struct refcnt refcnt; /** Name resolution interface */ struct resolv_interface resolv; /** Data transfer interface */ struct xfer_interface socket; /** Retry timer */ struct retry_timer timer; /** Socket address to fill in with resolved address */ struct sockaddr sa; /** Current query packet */ struct dns_query query; /** Location of query info structure within current packet * * The query info structure is located immediately after the * compressed name. */ struct dns_query_info *qinfo; /** Recursion counter */ unsigned int recursion; }; /** * Mark DNS request as complete * * @v dns DNS request * @v rc Return status code */ static void dns_done ( struct dns_request *dns, int rc ) { /* Stop the retry timer */ stop_timer ( &dns->timer ); /* Close data transfer interface */ xfer_nullify ( &dns->socket ); xfer_close ( &dns->socket, rc ); /* Mark name resolution as complete */ resolv_done ( &dns->resolv, &dns->sa, rc ); } /** * Compare DNS reply name against the query name from the original request * * @v dns DNS request * @v reply DNS reply * @v rname Reply name * @ret zero Names match * @ret non-zero Names do not match */ static int dns_name_cmp ( struct dns_request *dns, const struct dns_header *reply, const char *rname ) { const char *qname = dns->query.payload; int i; while ( 1 ) { /* Obtain next section of rname */ while ( ( *rname ) & 0xc0 ) { rname = ( ( ( char * ) reply ) + ( ntohs( *((uint16_t *)rname) ) & ~0xc000 )); } /* Check that lengths match */ if ( *rname != *qname ) return -1; /* If length is zero, we have reached the end */ if ( ! *qname ) return 0; /* Check that data matches */ for ( i = *qname + 1; i > 0 ; i-- ) { if ( *(rname++) != *(qname++) ) return -1; } } } /** * Skip over a (possibly compressed) DNS name * * @v name DNS name * @ret name Next DNS name */ static const char * dns_skip_name ( const char *name ) { while ( 1 ) { if ( ! *name ) { /* End of name */ return ( name + 1); } if ( *name & 0xc0 ) { /* Start of a compressed name */ return ( name + 2 ); } /* Uncompressed name portion */ name += *name + 1; } } /** * Find an RR in a reply packet corresponding to our query * * @v dns DNS request * @v reply DNS reply * @ret rr DNS RR, or NULL if not found */ static union dns_rr_info * dns_find_rr ( struct dns_request *dns, const struct dns_header *reply ) { int i, cmp; const char *p = ( ( char * ) reply ) + sizeof ( struct dns_header ); union dns_rr_info *rr_info; /* Skip over the questions section */ for ( i = ntohs ( reply->qdcount ) ; i > 0 ; i-- ) { p = dns_skip_name ( p ) + sizeof ( struct dns_query_info ); } /* Process the answers section */ for ( i = ntohs ( reply->ancount ) ; i > 0 ; i-- ) { cmp = dns_name_cmp ( dns, reply, p ); p = dns_skip_name ( p ); rr_info = ( ( union dns_rr_info * ) p ); if ( cmp == 0 ) return rr_info; p += ( sizeof ( rr_info->common ) + ntohs ( rr_info->common.rdlength ) ); } return NULL; } /** * Append DHCP domain name if available and name is not fully qualified * * @v string Name as a NUL-terminated string * @ret fqdn Fully-qualified domain name, malloc'd copy * * The caller must free fqdn which is allocated even if the name is already * fully qualified. */ static char * dns_qualify_name ( const char *string ) { char *fqdn; /* Leave unchanged if already fully-qualified or no local domain */ if ( ( ! localdomain ) || ( strchr ( string, '.' ) != 0 ) ) return strdup ( string ); /* Append local domain to name */ return grub_xasprintf ( "%s.%s", string, localdomain ); } /** * Convert a standard NUL-terminated string to a DNS name * * @v string Name as a NUL-terminated string * @v buf Buffer in which to place DNS name * @ret next Byte following constructed DNS name * * DNS names consist of "element" pairs. */ static char * dns_make_name ( const char *string, char *buf ) { char *length_byte = buf++; char c; while ( ( c = *(string++) ) ) { if ( c == '.' ) { *length_byte = buf - length_byte - 1; length_byte = buf; } *(buf++) = c; } *length_byte = buf - length_byte - 1; *(buf++) = '\0'; return buf; } /** * Convert an uncompressed DNS name to a NUL-terminated string * * @v name DNS name * @ret string NUL-terminated string * * Produce a printable version of a DNS name. Used only for debugging. */ static inline char * dns_unmake_name ( char *name ) { char *p; unsigned int len; p = name; while ( ( len = *p ) ) { *(p++) = '.'; p += len; } return name + 1; } /** * Decompress a DNS name * * @v reply DNS replay * @v name DNS name * @v buf Buffer into which to decompress DNS name * @ret next Byte following decompressed DNS name */ static char * dns_decompress_name ( const struct dns_header *reply, const char *name, char *buf ) { int i, len; do { /* Obtain next section of name */ while ( ( *name ) & 0xc0 ) { name = ( ( char * ) reply + ( ntohs ( *((uint16_t *)name) ) & ~0xc000 ) ); } /* Copy data */ len = *name; for ( i = len + 1 ; i > 0 ; i-- ) { *(buf++) = *(name++); } } while ( len ); return buf; } /** * Send next packet in DNS request * * @v dns DNS request */ static int dns_send_packet ( struct dns_request *dns ) { static unsigned int qid = 0; size_t qlen; /* Increment query ID */ dns->query.dns.id = htons ( ++qid ); DBGC ( dns, "DNS %p sending query ID %d\n", dns, qid ); /* Start retransmission timer */ start_timer ( &dns->timer ); /* Send the data */ qlen = ( ( ( void * ) dns->qinfo ) - ( ( void * ) &dns->query ) + sizeof ( dns->qinfo ) ); return xfer_deliver_raw ( &dns->socket, &dns->query, qlen ); } /** * Handle DNS retransmission timer expiry * * @v timer Retry timer * @v fail Failure indicator */ static void dns_timer_expired ( struct retry_timer *timer, int fail ) { struct dns_request *dns = container_of ( timer, struct dns_request, timer ); if ( fail ) { dns_done ( dns, -ETIMEDOUT ); } else { dns_send_packet ( dns ); } } /** * Receive new data * * @v socket UDP socket * @v data DNS reply * @v len Length of DNS reply * @ret rc Return status code */ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, const void *data, size_t len ) { struct dns_request *dns = container_of ( socket, struct dns_request, socket ); const struct dns_header *reply = data; union dns_rr_info *rr_info; struct sockaddr_in *sin; unsigned int qtype = dns->qinfo->qtype; /* Sanity check */ if ( len < sizeof ( *reply ) ) { DBGC ( dns, "DNS %p received underlength packet length %zd\n", dns, len ); return -EINVAL; } /* Check reply ID matches query ID */ if ( reply->id != dns->query.dns.id ) { DBGC ( dns, "DNS %p received unexpected reply ID %d " "(wanted %d)\n", dns, ntohs ( reply->id ), ntohs ( dns->query.dns.id ) ); return -EINVAL; } DBGC ( dns, "DNS %p received reply ID %d\n", dns, ntohs ( reply->id )); /* Stop the retry timer. After this point, each code path * must either restart the timer by calling dns_send_packet(), * or mark the DNS operation as complete by calling * dns_done() */ stop_timer ( &dns->timer ); /* Search through response for useful answers. Do this * multiple times, to take advantage of useful nameservers * which send us e.g. the CNAME *and* the A record for the * pointed-to name. */ while ( ( rr_info = dns_find_rr ( dns, reply ) ) ) { switch ( rr_info->common.type ) { case htons ( DNS_TYPE_A ): /* Found the target A record */ DBGC ( dns, "DNS %p found address %s\n", dns, inet_ntoa ( rr_info->a.in_addr ) ); sin = ( struct sockaddr_in * ) &dns->sa; sin->sin_family = AF_INET; sin->sin_addr = rr_info->a.in_addr; /* Mark operation as complete */ dns_done ( dns, 0 ); return 0; case htons ( DNS_TYPE_CNAME ): /* Found a CNAME record; update query and recurse */ DBGC ( dns, "DNS %p found CNAME\n", dns ); dns->qinfo = ( void * ) dns_decompress_name ( reply, rr_info->cname.cname, dns->query.payload ); dns->qinfo->qtype = htons ( DNS_TYPE_A ); dns->qinfo->qclass = htons ( DNS_CLASS_IN ); /* Terminate the operation if we recurse too far */ if ( ++dns->recursion > DNS_MAX_CNAME_RECURSION ) { DBGC ( dns, "DNS %p recursion exceeded\n", dns ); dns_done ( dns, -ELOOP ); return 0; } break; default: DBGC ( dns, "DNS %p got unknown record type %d\n", dns, ntohs ( rr_info->common.type ) ); break; } } /* Determine what to do next based on the type of query we * issued and the reponse we received */ switch ( qtype ) { case htons ( DNS_TYPE_A ): /* We asked for an A record and got nothing; * try the CNAME. */ DBGC ( dns, "DNS %p found no A record; trying CNAME\n", dns ); dns->qinfo->qtype = htons ( DNS_TYPE_CNAME ); dns_send_packet ( dns ); return 0; case htons ( DNS_TYPE_CNAME ): /* We asked for a CNAME record. If we got a response * (i.e. if the next A query is already set up), then * issue it, otherwise abort. */ if ( dns->qinfo->qtype == htons ( DNS_TYPE_A ) ) { dns_send_packet ( dns ); return 0; } else { DBGC ( dns, "DNS %p found no CNAME record\n", dns ); dns_done ( dns, -ENXIO ); return 0; } default: assert ( 0 ); dns_done ( dns, -EINVAL ); return 0; } } /** * Receive new data * * @v socket UDP socket * @v rc Reason for close */ static void dns_xfer_close ( struct xfer_interface *socket, int rc ) { struct dns_request *dns = container_of ( socket, struct dns_request, socket ); if ( ! rc ) rc = -ECONNABORTED; dns_done ( dns, rc ); } /** DNS socket operations */ static struct xfer_interface_operations dns_socket_operations = { .close = dns_xfer_close, .vredirect = xfer_vreopen, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, .deliver_raw = dns_xfer_deliver_raw, }; /** * Resolve name using DNS * * @v resolv Name resolution interface * @v name Name to resolve * @v sa Socket address to fill in * @ret rc Return status code */ static int dns_resolv ( struct resolv_interface *resolv, const char *name, struct sockaddr *sa ) { struct dns_request *dns; char *fqdn; int rc; /* Fail immediately if no DNS servers */ if ( ! nameserver.st_family ) { DBG ( "DNS not attempting to resolve \"%s\": " "no DNS servers\n", name ); rc = -ENXIO; goto err_no_nameserver; } /* Ensure fully-qualified domain name if DHCP option was given */ fqdn = dns_qualify_name ( name ); if ( ! fqdn ) { rc = -ENOMEM; goto err_qualify_name; } /* Allocate DNS structure */ dns = zalloc ( sizeof ( *dns ) ); if ( ! dns ) { rc = -ENOMEM; goto err_alloc_dns; } resolv_init ( &dns->resolv, &null_resolv_ops, &dns->refcnt ); xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt ); dns->timer.expired = dns_timer_expired; memcpy ( &dns->sa, sa, sizeof ( dns->sa ) ); /* Create query */ dns->query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY | DNS_FLAG_RD ); dns->query.dns.qdcount = htons ( 1 ); dns->qinfo = ( void * ) dns_make_name ( fqdn, dns->query.payload ); dns->qinfo->qtype = htons ( DNS_TYPE_A ); dns->qinfo->qclass = htons ( DNS_CLASS_IN ); /* Open UDP connection */ if ( ( rc = xfer_open_socket ( &dns->socket, SOCK_DGRAM, ( struct sockaddr * ) &nameserver, NULL ) ) != 0 ) { DBGC ( dns, "DNS %p could not open socket: %s\n", dns, strerror ( rc ) ); goto err_open_socket; } /* Send first DNS packet */ dns_send_packet ( dns ); /* Attach parent interface, mortalise self, and return */ resolv_plug_plug ( &dns->resolv, resolv ); ref_put ( &dns->refcnt ); free ( fqdn ); return 0; err_open_socket: err_alloc_dns: ref_put ( &dns->refcnt ); err_qualify_name: free ( fqdn ); err_no_nameserver: return rc; } /** DNS name resolver */ struct resolver dns_resolver __resolver ( RESOLV_NORMAL ) = { .name = "DNS", .resolv = dns_resolv, }; /****************************************************************************** * * Settings * ****************************************************************************** */ /** DNS server setting */ struct setting dns_setting __setting = { .name = "dns", .description = "DNS server", .tag = DHCP_DNS_SERVERS, .type = &setting_type_ipv4, }; /** Domain name setting */ struct setting domain_setting __setting = { .name = "domain", .description = "Local domain", .tag = DHCP_DOMAIN_NAME, .type = &setting_type_string, }; /** * Apply DNS settings * * @ret rc Return status code */ static int apply_dns_settings ( void ) { struct sockaddr_in *sin_nameserver = ( struct sockaddr_in * ) &nameserver; int len; if ( ( len = fetch_ipv4_setting ( NULL, &dns_setting, &sin_nameserver->sin_addr ) ) >= 0 ){ sin_nameserver->sin_family = AF_INET; DBG ( "DNS using nameserver %s\n", inet_ntoa ( sin_nameserver->sin_addr ) ); } /* Get local domain DHCP option */ if ( ( len = fetch_string_setting_copy ( NULL, &domain_setting, &localdomain ) ) >= 0 ) DBG ( "DNS local domain %s\n", localdomain ); return 0; } /** DNS settings applicator */ struct settings_applicator dns_applicator __settings_applicator = { .apply = apply_dns_settings, }; debian/grub-extras/disabled/gpxe/src/net/udp/dhcp.c0000664000000000000000000011661412524662415017414 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * Dynamic Host Configuration Protocol * */ struct dhcp_session; static int dhcp_tx ( struct dhcp_session *dhcp ); /** * DHCP operation types * * This table maps from DHCP message types (i.e. values of the @c * DHCP_MESSAGE_TYPE option) to values of the "op" field within a DHCP * packet. */ static const uint8_t dhcp_op[] = { [DHCPDISCOVER] = BOOTP_REQUEST, [DHCPOFFER] = BOOTP_REPLY, [DHCPREQUEST] = BOOTP_REQUEST, [DHCPDECLINE] = BOOTP_REQUEST, [DHCPACK] = BOOTP_REPLY, [DHCPNAK] = BOOTP_REPLY, [DHCPRELEASE] = BOOTP_REQUEST, [DHCPINFORM] = BOOTP_REQUEST, }; /** Raw option data for options common to all DHCP requests */ static uint8_t dhcp_request_options_data[] = { DHCP_MAX_MESSAGE_SIZE, DHCP_WORD ( ETH_MAX_MTU - 20 /* IP header */ - 8 /* UDP header */ ), DHCP_CLIENT_ARCHITECTURE, DHCP_WORD ( 0 ), DHCP_CLIENT_NDI, DHCP_OPTION ( 1 /* UNDI */ , 2, 1 /* v2.1 */ ), DHCP_VENDOR_CLASS_ID, DHCP_STRING ( 'P', 'X', 'E', 'C', 'l', 'i', 'e', 'n', 't', ':', 'A', 'r', 'c', 'h', ':', '0', '0', '0', '0', '0', ':', 'U', 'N', 'D', 'I', ':', '0', '0', '2', '0', '0', '1' ), DHCP_USER_CLASS_ID, DHCP_STRING ( 'g', 'P', 'X', 'E' ), DHCP_PARAMETER_REQUEST_LIST, DHCP_OPTION ( DHCP_SUBNET_MASK, DHCP_ROUTERS, DHCP_DNS_SERVERS, DHCP_LOG_SERVERS, DHCP_HOST_NAME, DHCP_DOMAIN_NAME, DHCP_ROOT_PATH, DHCP_VENDOR_ENCAP, DHCP_VENDOR_CLASS_ID, DHCP_TFTP_SERVER_NAME, DHCP_BOOTFILE_NAME, DHCP_EB_ENCAP, DHCP_ISCSI_INITIATOR_IQN ), DHCP_END }; /** Version number feature */ FEATURE_VERSION ( VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH ); /** DHCP server address setting */ struct setting dhcp_server_setting __setting = { .name = "dhcp-server", .description = "DHCP server address", .tag = DHCP_SERVER_IDENTIFIER, .type = &setting_type_ipv4, }; /** DHCP user class setting */ struct setting user_class_setting __setting = { .name = "user-class", .description = "User class identifier", .tag = DHCP_USER_CLASS_ID, .type = &setting_type_string, }; /** * Name a DHCP packet type * * @v msgtype DHCP message type * @ret string DHCP mesasge type name */ static inline const char * dhcp_msgtype_name ( unsigned int msgtype ) { switch ( msgtype ) { case DHCPNONE: return "BOOTP"; /* Non-DHCP packet */ case DHCPDISCOVER: return "DHCPDISCOVER"; case DHCPOFFER: return "DHCPOFFER"; case DHCPREQUEST: return "DHCPREQUEST"; case DHCPDECLINE: return "DHCPDECLINE"; case DHCPACK: return "DHCPACK"; case DHCPNAK: return "DHCPNAK"; case DHCPRELEASE: return "DHCPRELEASE"; case DHCPINFORM: return "DHCPINFORM"; default: return "DHCP"; } } /** * Calculate DHCP transaction ID for a network device * * @v netdev Network device * @ret xid DHCP XID * * Extract the least significant bits of the hardware address for use * as the transaction ID. */ static uint32_t dhcp_xid ( struct net_device *netdev ) { uint32_t xid; memcpy ( &xid, ( netdev->ll_addr + netdev->ll_protocol->ll_addr_len - sizeof ( xid ) ), sizeof ( xid ) ); return xid; } /**************************************************************************** * * DHCP session * */ struct dhcp_session; /** DHCP session state operations */ struct dhcp_session_state { /** State name */ const char *name; /** * Construct transmitted packet * * @v dhcp DHCP session * @v dhcppkt DHCP packet * @v peer Destination address */ int ( * tx ) ( struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer ); /** Handle received packet * * @v dhcp DHCP session * @v dhcppkt DHCP packet * @v peer DHCP server address * @v msgtype DHCP message type * @v server_id DHCP server ID */ void ( * rx ) ( struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id ); /** Handle timer expiry * * @v dhcp DHCP session */ void ( * expired ) ( struct dhcp_session *dhcp ); /** Transmitted message type */ uint8_t tx_msgtype; /** Apply minimum timeout */ uint8_t apply_min_timeout; }; static struct dhcp_session_state dhcp_state_discover; static struct dhcp_session_state dhcp_state_request; static struct dhcp_session_state dhcp_state_proxy; static struct dhcp_session_state dhcp_state_pxebs; /** A DHCP session */ struct dhcp_session { /** Reference counter */ struct refcnt refcnt; /** Job control interface */ struct job_interface job; /** Data transfer interface */ struct xfer_interface xfer; /** Network device being configured */ struct net_device *netdev; /** Local socket address */ struct sockaddr_in local; /** State of the session */ struct dhcp_session_state *state; /** Offered IP address */ struct in_addr offer; /** DHCP server */ struct in_addr server; /** DHCP offer priority */ int priority; /** ProxyDHCP protocol extensions should be ignored */ int no_pxedhcp; /** ProxyDHCP server */ struct in_addr proxy_server; /** ProxyDHCP port */ uint16_t proxy_port; /** ProxyDHCP server priority */ int proxy_priority; /** PXE Boot Server type */ uint16_t pxe_type; /** List of PXE Boot Servers to attempt */ struct in_addr *pxe_attempt; /** List of PXE Boot Servers to accept */ struct in_addr *pxe_accept; /** Retransmission timer */ struct retry_timer timer; /** Start time of the current state (in ticks) */ unsigned long start; }; /** * Free DHCP session * * @v refcnt Reference counter */ static void dhcp_free ( struct refcnt *refcnt ) { struct dhcp_session *dhcp = container_of ( refcnt, struct dhcp_session, refcnt ); netdev_put ( dhcp->netdev ); free ( dhcp ); } /** * Mark DHCP session as complete * * @v dhcp DHCP session * @v rc Return status code */ static void dhcp_finished ( struct dhcp_session *dhcp, int rc ) { /* Block futher incoming messages */ job_nullify ( &dhcp->job ); xfer_nullify ( &dhcp->xfer ); /* Stop retry timer */ stop_timer ( &dhcp->timer ); /* Free resources and close interfaces */ xfer_close ( &dhcp->xfer, rc ); job_done ( &dhcp->job, rc ); } /** * Transition to new DHCP session state * * @v dhcp DHCP session * @v state New session state */ static void dhcp_set_state ( struct dhcp_session *dhcp, struct dhcp_session_state *state ) { DBGC ( dhcp, "DHCP %p entering %s state\n", dhcp, state->name ); dhcp->state = state; dhcp->start = currticks(); stop_timer ( &dhcp->timer ); dhcp->timer.min_timeout = ( state->apply_min_timeout ? DHCP_MIN_TIMEOUT : 0 ); dhcp->timer.max_timeout = DHCP_MAX_TIMEOUT; start_timer_nodelay ( &dhcp->timer ); } /**************************************************************************** * * DHCP state machine * */ /** * Construct transmitted packet for DHCP discovery * * @v dhcp DHCP session * @v dhcppkt DHCP packet * @v peer Destination address */ static int dhcp_discovery_tx ( struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt __unused, struct sockaddr_in *peer ) { DBGC ( dhcp, "DHCP %p DHCPDISCOVER\n", dhcp ); /* Set server address */ peer->sin_addr.s_addr = INADDR_BROADCAST; peer->sin_port = htons ( BOOTPS_PORT ); return 0; } /** * Handle received packet during DHCP discovery * * @v dhcp DHCP session * @v dhcppkt DHCP packet * @v peer DHCP server address * @v msgtype DHCP message type * @v server_id DHCP server ID */ static void dhcp_discovery_rx ( struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id ) { struct in_addr ip; char vci[9]; /* "PXEClient" */ int vci_len; int has_pxeclient; int pxeopts_len; int has_pxeopts; int8_t priority = 0; uint8_t no_pxedhcp = 0; unsigned long elapsed; DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp, dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ) ); if ( server_id.s_addr != peer->sin_addr.s_addr ) DBGC ( dhcp, " (%s)", inet_ntoa ( server_id ) ); /* Identify offered IP address */ ip = dhcppkt->dhcphdr->yiaddr; if ( ip.s_addr ) DBGC ( dhcp, " for %s", inet_ntoa ( ip ) ); /* Identify "PXEClient" vendor class */ vci_len = dhcppkt_fetch ( dhcppkt, DHCP_VENDOR_CLASS_ID, vci, sizeof ( vci ) ); has_pxeclient = ( ( vci_len >= ( int ) sizeof ( vci ) ) && ( strncmp ( "PXEClient", vci, sizeof (vci) ) == 0 )); /* Identify presence of vendor-specific options */ pxeopts_len = dhcppkt_fetch ( dhcppkt, DHCP_VENDOR_ENCAP, NULL, 0 ); has_pxeopts = ( pxeopts_len >= 0 ); if ( has_pxeclient ) DBGC ( dhcp, "%s", ( has_pxeopts ? " pxe" : " proxy" ) ); /* Identify priority */ dhcppkt_fetch ( dhcppkt, DHCP_EB_PRIORITY, &priority, sizeof ( priority ) ); if ( priority ) DBGC ( dhcp, " pri %d", priority ); /* Identify ignore-PXE flag */ dhcppkt_fetch ( dhcppkt, DHCP_EB_NO_PXEDHCP, &no_pxedhcp, sizeof ( no_pxedhcp ) ); if ( no_pxedhcp ) DBGC ( dhcp, " nopxe" ); DBGC ( dhcp, "\n" ); /* Select as DHCP offer, if applicable */ if ( ip.s_addr && ( peer->sin_port == htons ( BOOTPS_PORT ) ) && ( ( msgtype == DHCPOFFER ) || ( ! msgtype /* BOOTP */ ) ) && ( priority >= dhcp->priority ) ) { dhcp->offer = ip; dhcp->server = server_id; dhcp->priority = priority; dhcp->no_pxedhcp = no_pxedhcp; } /* Select as ProxyDHCP offer, if applicable */ if ( has_pxeclient && ( msgtype == DHCPOFFER ) && ( priority >= dhcp->proxy_priority ) ) { /* If the offer already includes the PXE options, then * assume that we can send the ProxyDHCPREQUEST to * port 67 (since the DHCPDISCOVER that triggered this * ProxyDHCPOFFER was sent to port 67). Otherwise, * send the ProxyDHCPREQUEST to port 4011. */ dhcp->proxy_server = server_id; dhcp->proxy_port = ( has_pxeopts ? htons ( BOOTPS_PORT ) : htons ( PXE_PORT ) ); dhcp->proxy_priority = priority; } /* We can exit the discovery state when we have a valid * DHCPOFFER, and either: * * o The DHCPOFFER instructs us to ignore ProxyDHCPOFFERs, or * o We have a valid ProxyDHCPOFFER, or * o We have allowed sufficient time for ProxyDHCPOFFERs. */ /* If we don't yet have a DHCPOFFER, do nothing */ if ( ! dhcp->offer.s_addr ) return; /* If we can't yet transition to DHCPREQUEST, do nothing */ elapsed = ( currticks() - dhcp->start ); if ( ! ( dhcp->no_pxedhcp || dhcp->proxy_server.s_addr || ( elapsed > PROXYDHCP_MAX_TIMEOUT ) ) ) return; /* Transition to DHCPREQUEST */ dhcp_set_state ( dhcp, &dhcp_state_request ); } /** * Handle timer expiry during DHCP discovery * * @v dhcp DHCP session */ static void dhcp_discovery_expired ( struct dhcp_session *dhcp ) { unsigned long elapsed = ( currticks() - dhcp->start ); /* Give up waiting for ProxyDHCP before we reach the failure point */ if ( dhcp->offer.s_addr && ( elapsed > PROXYDHCP_MAX_TIMEOUT ) ) { dhcp_set_state ( dhcp, &dhcp_state_request ); return; } /* Otherwise, retransmit current packet */ dhcp_tx ( dhcp ); } /** DHCP discovery state operations */ static struct dhcp_session_state dhcp_state_discover = { .name = "discovery", .tx = dhcp_discovery_tx, .rx = dhcp_discovery_rx, .expired = dhcp_discovery_expired, .tx_msgtype = DHCPDISCOVER, .apply_min_timeout = 1, }; /** * Construct transmitted packet for DHCP request * * @v dhcp DHCP session * @v dhcppkt DHCP packet * @v peer Destination address */ static int dhcp_request_tx ( struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer ) { int rc; DBGC ( dhcp, "DHCP %p DHCPREQUEST to %s:%d", dhcp, inet_ntoa ( dhcp->server ), BOOTPS_PORT ); DBGC ( dhcp, " for %s\n", inet_ntoa ( dhcp->offer ) ); /* Set server ID */ if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER, &dhcp->server, sizeof ( dhcp->server ) ) ) != 0 ) return rc; /* Set requested IP address */ if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_REQUESTED_ADDRESS, &dhcp->offer, sizeof ( dhcp->offer ) ) ) != 0 ) return rc; /* Set server address */ peer->sin_addr.s_addr = INADDR_BROADCAST; peer->sin_port = htons ( BOOTPS_PORT ); return 0; } /** * Handle received packet during DHCP request * * @v dhcp DHCP session * @v dhcppkt DHCP packet * @v peer DHCP server address * @v msgtype DHCP message type * @v server_id DHCP server ID */ static void dhcp_request_rx ( struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id ) { struct in_addr ip; struct settings *parent; int rc; DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp, dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ) ); if ( server_id.s_addr != peer->sin_addr.s_addr ) DBGC ( dhcp, " (%s)", inet_ntoa ( server_id ) ); /* Identify leased IP address */ ip = dhcppkt->dhcphdr->yiaddr; if ( ip.s_addr ) DBGC ( dhcp, " for %s", inet_ntoa ( ip ) ); DBGC ( dhcp, "\n" ); /* Filter out unacceptable responses */ if ( peer->sin_port != htons ( BOOTPS_PORT ) ) return; if ( msgtype /* BOOTP */ && ( msgtype != DHCPACK ) ) return; if ( server_id.s_addr != dhcp->server.s_addr ) return; /* Record assigned address */ dhcp->local.sin_addr = ip; /* Register settings */ parent = netdev_settings ( dhcp->netdev ); if ( ( rc = register_settings ( &dhcppkt->settings, parent ) ) != 0 ){ DBGC ( dhcp, "DHCP %p could not register settings: %s\n", dhcp, strerror ( rc ) ); dhcp_finished ( dhcp, rc ); return; } /* Start ProxyDHCPREQUEST if applicable */ if ( dhcp->proxy_server.s_addr /* Have ProxyDHCP server */ && ( ! dhcp->no_pxedhcp ) /* ProxyDHCP not disabled */ && ( /* ProxyDHCP server is not just the DHCP server itself */ ( dhcp->proxy_server.s_addr != dhcp->server.s_addr ) || ( dhcp->proxy_port != htons ( BOOTPS_PORT ) ) ) ) { dhcp_set_state ( dhcp, &dhcp_state_proxy ); return; } /* Terminate DHCP */ dhcp_finished ( dhcp, 0 ); } /** * Handle timer expiry during DHCP discovery * * @v dhcp DHCP session */ static void dhcp_request_expired ( struct dhcp_session *dhcp ) { /* Retransmit current packet */ dhcp_tx ( dhcp ); } /** DHCP request state operations */ static struct dhcp_session_state dhcp_state_request = { .name = "request", .tx = dhcp_request_tx, .rx = dhcp_request_rx, .expired = dhcp_request_expired, .tx_msgtype = DHCPREQUEST, .apply_min_timeout = 0, }; /** * Construct transmitted packet for ProxyDHCP request * * @v dhcp DHCP session * @v dhcppkt DHCP packet * @v peer Destination address */ static int dhcp_proxy_tx ( struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer ) { int rc; DBGC ( dhcp, "DHCP %p ProxyDHCP REQUEST to %s:%d\n", dhcp, inet_ntoa ( dhcp->proxy_server ), ntohs ( dhcp->proxy_port ) ); /* Set server ID */ if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER, &dhcp->proxy_server, sizeof ( dhcp->proxy_server ) ) ) != 0 ) return rc; /* Set server address */ peer->sin_addr = dhcp->proxy_server; peer->sin_port = dhcp->proxy_port; return 0; } /** * Handle received packet during ProxyDHCP request * * @v dhcp DHCP session * @v dhcppkt DHCP packet * @v peer DHCP server address * @v msgtype DHCP message type * @v server_id DHCP server ID */ static void dhcp_proxy_rx ( struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id ) { int rc; DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp, dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ) ); if ( server_id.s_addr != peer->sin_addr.s_addr ) DBGC ( dhcp, " (%s)", inet_ntoa ( server_id ) ); DBGC ( dhcp, "\n" ); /* Filter out unacceptable responses */ if ( peer->sin_port != dhcp->proxy_port ) return; if ( msgtype != DHCPACK ) return; if ( server_id.s_addr /* Linux PXE server omits server ID */ && ( server_id.s_addr != dhcp->proxy_server.s_addr ) ) return; /* Register settings */ dhcppkt->settings.name = PROXYDHCP_SETTINGS_NAME; if ( ( rc = register_settings ( &dhcppkt->settings, NULL ) ) != 0 ) { DBGC ( dhcp, "DHCP %p could not register settings: %s\n", dhcp, strerror ( rc ) ); dhcp_finished ( dhcp, rc ); return; } /* Terminate DHCP */ dhcp_finished ( dhcp, 0 ); } /** * Handle timer expiry during ProxyDHCP request * * @v dhcp DHCP session */ static void dhcp_proxy_expired ( struct dhcp_session *dhcp ) { unsigned long elapsed = ( currticks() - dhcp->start ); /* Give up waiting for ProxyDHCP before we reach the failure point */ if ( elapsed > PROXYDHCP_MAX_TIMEOUT ) { dhcp_finished ( dhcp, 0 ); return; } /* Retransmit current packet */ dhcp_tx ( dhcp ); } /** ProxyDHCP request state operations */ static struct dhcp_session_state dhcp_state_proxy = { .name = "ProxyDHCP", .tx = dhcp_proxy_tx, .rx = dhcp_proxy_rx, .expired = dhcp_proxy_expired, .tx_msgtype = DHCPREQUEST, .apply_min_timeout = 0, }; /** * Construct transmitted packet for PXE Boot Server Discovery * * @v dhcp DHCP session * @v dhcppkt DHCP packet * @v peer Destination address */ static int dhcp_pxebs_tx ( struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer ) { struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 }; int rc; /* Set server address */ peer->sin_addr = *(dhcp->pxe_attempt); peer->sin_port = ( ( peer->sin_addr.s_addr == INADDR_BROADCAST ) ? htons ( BOOTPS_PORT ) : htons ( PXE_PORT ) ); DBGC ( dhcp, "DHCP %p PXEBS REQUEST to %s:%d for type %d\n", dhcp, inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ), ntohs ( dhcp->pxe_type ) ); /* Set boot menu item */ menu_item.type = dhcp->pxe_type; if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_PXE_BOOT_MENU_ITEM, &menu_item, sizeof ( menu_item ) ) ) != 0 ) return rc; return 0; } /** * Check to see if PXE Boot Server address is acceptable * * @v dhcp DHCP session * @v bs Boot Server address * @ret accept Boot Server is acceptable */ static int dhcp_pxebs_accept ( struct dhcp_session *dhcp, struct in_addr bs ) { struct in_addr *accept; /* Accept if we have no acceptance filter */ if ( ! dhcp->pxe_accept ) return 1; /* Scan through acceptance list */ for ( accept = dhcp->pxe_accept ; accept->s_addr ; accept++ ) { if ( accept->s_addr == bs.s_addr ) return 1; } DBGC ( dhcp, "DHCP %p rejecting server %s\n", dhcp, inet_ntoa ( bs ) ); return 0; } /** * Handle received packet during PXE Boot Server Discovery * * @v dhcp DHCP session * @v dhcppkt DHCP packet * @v peer DHCP server address * @v msgtype DHCP message type * @v server_id DHCP server ID */ static void dhcp_pxebs_rx ( struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id ) { struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 }; int rc; DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp, dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ) ); if ( server_id.s_addr != peer->sin_addr.s_addr ) DBGC ( dhcp, " (%s)", inet_ntoa ( server_id ) ); /* Identify boot menu item */ dhcppkt_fetch ( dhcppkt, DHCP_PXE_BOOT_MENU_ITEM, &menu_item, sizeof ( menu_item ) ); if ( menu_item.type ) DBGC ( dhcp, " for type %d", ntohs ( menu_item.type ) ); DBGC ( dhcp, "\n" ); /* Filter out unacceptable responses */ if ( ( peer->sin_port != htons ( BOOTPS_PORT ) ) && ( peer->sin_port != htons ( PXE_PORT ) ) ) return; if ( msgtype != DHCPACK ) return; if ( menu_item.type != dhcp->pxe_type ) return; if ( ! dhcp_pxebs_accept ( dhcp, ( server_id.s_addr ? server_id : peer->sin_addr ) ) ) return; /* Register settings */ dhcppkt->settings.name = PXEBS_SETTINGS_NAME; if ( ( rc = register_settings ( &dhcppkt->settings, NULL ) ) != 0 ) { DBGC ( dhcp, "DHCP %p could not register settings: %s\n", dhcp, strerror ( rc ) ); dhcp_finished ( dhcp, rc ); return; } /* Terminate DHCP */ dhcp_finished ( dhcp, 0 ); } /** * Handle timer expiry during PXE Boot Server Discovery * * @v dhcp DHCP session */ static void dhcp_pxebs_expired ( struct dhcp_session *dhcp ) { unsigned long elapsed = ( currticks() - dhcp->start ); /* Give up waiting before we reach the failure point, and fail * over to the next server in the attempt list */ if ( elapsed > PXEBS_MAX_TIMEOUT ) { dhcp->pxe_attempt++; if ( dhcp->pxe_attempt->s_addr ) { dhcp_set_state ( dhcp, &dhcp_state_pxebs ); return; } else { dhcp_finished ( dhcp, -ETIMEDOUT ); return; } } /* Retransmit current packet */ dhcp_tx ( dhcp ); } /** PXE Boot Server Discovery state operations */ static struct dhcp_session_state dhcp_state_pxebs = { .name = "PXEBS", .tx = dhcp_pxebs_tx, .rx = dhcp_pxebs_rx, .expired = dhcp_pxebs_expired, .tx_msgtype = DHCPREQUEST, .apply_min_timeout = 1, }; /**************************************************************************** * * Packet construction * */ /** * Construct DHCP client hardware address field and broadcast flag * * @v netdev Network device * @v hlen DHCP hardware address length to fill in * @v flags DHCP flags to fill in * @ret chaddr DHCP client hardware address */ void * dhcp_chaddr ( struct net_device *netdev, uint8_t *hlen, uint16_t *flags ) { struct ll_protocol *ll_protocol = netdev->ll_protocol; typeof ( ( ( struct dhcphdr * ) NULL )->chaddr ) chaddr; /* If the link-layer address cannot fit into the chaddr field * (as is the case for IPoIB) then try using the hardware * address instead. If we do this, set the broadcast flag, * since chaddr then does not represent a valid link-layer * address for the return path. * * If even the hardware address is too large, use an empty * chaddr field and set the broadcast flag. * * This goes against RFC4390, but RFC4390 mandates that we use * a DHCP client identifier that conforms with RFC4361, which * we cannot do without either persistent (NIC-independent) * storage, or by eliminating the hardware address completely * from the DHCP packet, which seems unfriendly to users. */ if ( ( *hlen = ll_protocol->ll_addr_len ) <= sizeof ( chaddr ) ) { return netdev->ll_addr; } *flags = htons ( BOOTP_FL_BROADCAST ); if ( ( *hlen = ll_protocol->hw_addr_len ) <= sizeof ( chaddr ) ) { return netdev->hw_addr; } else { *hlen = 0; return NULL; } } /** * Create a DHCP packet * * @v dhcppkt DHCP packet structure to fill in * @v netdev Network device * @v msgtype DHCP message type * @v options Initial options to include (or NULL) * @v options_len Length of initial options * @v data Buffer for DHCP packet * @v max_len Size of DHCP packet buffer * @ret rc Return status code * * Creates a DHCP packet in the specified buffer, and initialise a * DHCP packet structure. */ int dhcp_create_packet ( struct dhcp_packet *dhcppkt, struct net_device *netdev, uint8_t msgtype, const void *options, size_t options_len, void *data, size_t max_len ) { struct dhcphdr *dhcphdr = data; void *chaddr; int rc; /* Sanity check */ if ( max_len < ( sizeof ( *dhcphdr ) + options_len ) ) return -ENOSPC; /* Initialise DHCP packet content */ memset ( dhcphdr, 0, max_len ); dhcphdr->xid = dhcp_xid ( netdev ); dhcphdr->magic = htonl ( DHCP_MAGIC_COOKIE ); dhcphdr->htype = ntohs ( netdev->ll_protocol->ll_proto ); dhcphdr->op = dhcp_op[msgtype]; chaddr = dhcp_chaddr ( netdev, &dhcphdr->hlen, &dhcphdr->flags ); memcpy ( dhcphdr->chaddr, chaddr, dhcphdr->hlen ); memcpy ( dhcphdr->options, options, options_len ); /* Initialise DHCP packet structure */ memset ( dhcppkt, 0, sizeof ( *dhcppkt ) ); dhcppkt_init ( dhcppkt, data, max_len ); /* Set DHCP_MESSAGE_TYPE option */ if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_MESSAGE_TYPE, &msgtype, sizeof ( msgtype ) ) ) != 0 ) return rc; return 0; } /** * Create DHCP request packet * * @v dhcppkt DHCP packet structure to fill in * @v netdev Network device * @v msgtype DHCP message type * @v ciaddr Client IP address * @v data Buffer for DHCP packet * @v max_len Size of DHCP packet buffer * @ret rc Return status code * * Creates a DHCP request packet in the specified buffer, and * initialise a DHCP packet structure. */ int dhcp_create_request ( struct dhcp_packet *dhcppkt, struct net_device *netdev, unsigned int msgtype, struct in_addr ciaddr, void *data, size_t max_len ) { struct device_description *desc = &netdev->dev->desc; struct dhcp_netdev_desc dhcp_desc; struct dhcp_client_id client_id; struct dhcp_client_uuid client_uuid; uint8_t *dhcp_features; size_t dhcp_features_len; size_t ll_addr_len; ssize_t len; int rc; /* Create DHCP packet */ if ( ( rc = dhcp_create_packet ( dhcppkt, netdev, msgtype, dhcp_request_options_data, sizeof ( dhcp_request_options_data ), data, max_len ) ) != 0 ) { DBG ( "DHCP could not create DHCP packet: %s\n", strerror ( rc ) ); return rc; } /* Set client IP address */ dhcppkt->dhcphdr->ciaddr = ciaddr; /* Add options to identify the feature list */ #if 0 dhcp_features = table_start ( DHCP_FEATURES ); dhcp_features_len = table_num_entries ( DHCP_FEATURES ); if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_ENCAP, dhcp_features, dhcp_features_len ) ) != 0 ) { DBG ( "DHCP could not set features list option: %s\n", strerror ( rc ) ); return rc; } #endif /* Add options to identify the network device */ dhcp_desc.type = desc->bus_type; dhcp_desc.vendor = htons ( desc->vendor ); dhcp_desc.device = htons ( desc->device ); if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_BUS_ID, &dhcp_desc, sizeof ( dhcp_desc ) ) ) != 0 ) { DBG ( "DHCP could not set bus ID option: %s\n", strerror ( rc ) ); return rc; } /* Add DHCP client identifier. Required for Infiniband, and * doesn't hurt other link layers. */ client_id.ll_proto = ntohs ( netdev->ll_protocol->ll_proto ); ll_addr_len = netdev->ll_protocol->ll_addr_len; assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) ); memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len ); if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_ID, &client_id, ( ll_addr_len + 1 ) ) ) != 0 ) { DBG ( "DHCP could not set client ID: %s\n", strerror ( rc ) ); return rc; } #if 0 /* Add client UUID, if we have one. Required for PXE. */ client_uuid.type = DHCP_CLIENT_UUID_TYPE; if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting, &client_uuid.uuid ) ) >= 0 ) { if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_UUID, &client_uuid, sizeof ( client_uuid ) ) ) != 0 ) { DBG ( "DHCP could not set client UUID: %s\n", strerror ( rc ) ); return rc; } } #endif /* Add user class, if we have one. */ if ( ( len = fetch_setting_len ( NULL, &user_class_setting ) ) >= 0 ) { char user_class[len]; fetch_setting ( NULL, &user_class_setting, user_class, sizeof ( user_class ) ); if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_USER_CLASS_ID, &user_class, sizeof ( user_class ) ) ) != 0 ) { DBG ( "DHCP could not set user class: %s\n", strerror ( rc ) ); return rc; } } return 0; } /**************************************************************************** * * Data transfer interface * */ /** * Transmit DHCP request * * @v dhcp DHCP session * @ret rc Return status code */ static int dhcp_tx ( struct dhcp_session *dhcp ) { static struct sockaddr_in peer = { .sin_family = AF_INET, }; struct xfer_metadata meta = { .netdev = dhcp->netdev, .src = ( struct sockaddr * ) &dhcp->local, .dest = ( struct sockaddr * ) &peer, }; struct io_buffer *iobuf; uint8_t msgtype = dhcp->state->tx_msgtype; struct dhcp_packet dhcppkt; int rc; /* Start retry timer. Do this first so that failures to * transmit will be retried. */ start_timer ( &dhcp->timer ); /* Allocate buffer for packet */ iobuf = xfer_alloc_iob ( &dhcp->xfer, DHCP_MIN_LEN ); if ( ! iobuf ) return -ENOMEM; /* Create basic DHCP packet in temporary buffer */ if ( ( rc = dhcp_create_request ( &dhcppkt, dhcp->netdev, msgtype, dhcp->local.sin_addr, iobuf->data, iob_tailroom ( iobuf ) ) ) != 0 ) { DBGC ( dhcp, "DHCP %p could not construct DHCP request: %s\n", dhcp, strerror ( rc ) ); goto done; } /* Fill in packet based on current state */ if ( ( rc = dhcp->state->tx ( dhcp, &dhcppkt, &peer ) ) != 0 ) { DBGC ( dhcp, "DHCP %p could not fill DHCP request: %s\n", dhcp, strerror ( rc ) ); goto done; } /* Transmit the packet */ iob_put ( iobuf, dhcppkt.len ); if ( ( rc = xfer_deliver_iob_meta ( &dhcp->xfer, iob_disown ( iobuf ), &meta ) ) != 0 ) { DBGC ( dhcp, "DHCP %p could not transmit UDP packet: %s\n", dhcp, strerror ( rc ) ); goto done; } done: free_iob ( iobuf ); return rc; } /** * Receive new data * * @v xfer Data transfer interface * @v iobuf I/O buffer * @v meta Transfer metadata * @ret rc Return status code */ static int dhcp_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta ) { struct dhcp_session *dhcp = container_of ( xfer, struct dhcp_session, xfer ); struct sockaddr_in *peer; size_t data_len; struct dhcp_packet *dhcppkt; struct dhcphdr *dhcphdr; uint8_t msgtype = 0; struct in_addr server_id = { 0 }; int rc = 0; /* Sanity checks */ if ( ! meta->src ) { DBGC ( dhcp, "DHCP %p received packet without source port\n", dhcp ); rc = -EINVAL; goto err_no_src; } peer = ( struct sockaddr_in * ) meta->src; /* Create a DHCP packet containing the I/O buffer contents. * Whilst we could just use the original buffer in situ, that * would waste the unused space in the packet buffer, and also * waste a relatively scarce fully-aligned I/O buffer. */ data_len = iob_len ( iobuf ); dhcppkt = zalloc ( sizeof ( *dhcppkt ) + data_len ); if ( ! dhcppkt ) { rc = -ENOMEM; goto err_alloc_dhcppkt; } dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) ); memcpy ( dhcphdr, iobuf->data, data_len ); dhcppkt_init ( dhcppkt, dhcphdr, data_len ); /* Identify message type */ dhcppkt_fetch ( dhcppkt, DHCP_MESSAGE_TYPE, &msgtype, sizeof ( msgtype ) ); /* Identify server ID */ dhcppkt_fetch ( dhcppkt, DHCP_SERVER_IDENTIFIER, &server_id, sizeof ( server_id ) ); /* Check for matching transaction ID */ if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) { DBGC ( dhcp, "DHCP %p %s from %s:%d has bad transaction " "ID\n", dhcp, dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ) ); rc = -EINVAL; goto err_xid; }; /* Handle packet based on current state */ dhcp->state->rx ( dhcp, dhcppkt, peer, msgtype, server_id ); err_xid: dhcppkt_put ( dhcppkt ); err_alloc_dhcppkt: err_no_src: free_iob ( iobuf ); return rc; } /** DHCP data transfer interface operations */ static struct xfer_interface_operations dhcp_xfer_operations = { .close = ignore_xfer_close, .vredirect = xfer_vreopen, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = dhcp_deliver_iob, .deliver_raw = xfer_deliver_as_iob, }; /** * Handle DHCP retry timer expiry * * @v timer DHCP retry timer * @v fail Failure indicator */ static void dhcp_timer_expired ( struct retry_timer *timer, int fail ) { struct dhcp_session *dhcp = container_of ( timer, struct dhcp_session, timer ); /* If we have failed, terminate DHCP */ if ( fail ) { dhcp_finished ( dhcp, -ETIMEDOUT ); return; } /* Handle timer expiry based on current state */ dhcp->state->expired ( dhcp ); } /**************************************************************************** * * Job control interface * */ /** * Handle kill() event received via job control interface * * @v job DHCP job control interface */ static void dhcp_job_kill ( struct job_interface *job ) { struct dhcp_session *dhcp = container_of ( job, struct dhcp_session, job ); /* Terminate DHCP session */ dhcp_finished ( dhcp, -ECANCELED ); } /** DHCP job control interface operations */ static struct job_interface_operations dhcp_job_operations = { .done = ignore_job_done, .kill = dhcp_job_kill, .progress = ignore_job_progress, }; /**************************************************************************** * * Instantiators * */ /** * DHCP peer address for socket opening * * This is a dummy address; the only useful portion is the socket * family (so that we get a UDP connection). The DHCP client will set * the IP address and source port explicitly on each transmission. */ static struct sockaddr dhcp_peer = { .sa_family = AF_INET, }; /** * Start DHCP state machine on a network device * * @v job Job control interface * @v netdev Network device * @ret rc Return status code * * Starts DHCP on the specified network device. If successful, the * DHCPACK (and ProxyDHCPACK, if applicable) will be registered as * option sources. */ int start_dhcp ( struct job_interface *job, struct net_device *netdev ) { struct dhcp_session *dhcp; int rc; /* Allocate and initialise structure */ dhcp = zalloc ( sizeof ( *dhcp ) ); if ( ! dhcp ) return -ENOMEM; dhcp->refcnt.free = dhcp_free; job_init ( &dhcp->job, &dhcp_job_operations, &dhcp->refcnt ); xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt ); dhcp->netdev = netdev_get ( netdev ); dhcp->local.sin_family = AF_INET; dhcp->local.sin_port = htons ( BOOTPC_PORT ); dhcp->timer.expired = dhcp_timer_expired; /* Instantiate child objects and attach to our interfaces */ if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer, ( struct sockaddr * ) &dhcp->local ) ) != 0 ) goto err; /* Enter DHCPDISCOVER state */ dhcp_set_state ( dhcp, &dhcp_state_discover ); /* Attach parent interface, mortalise self, and return */ job_plug_plug ( &dhcp->job, job ); ref_put ( &dhcp->refcnt ); return 0; err: dhcp_finished ( dhcp, rc ); ref_put ( &dhcp->refcnt ); return rc; } /** * Retrieve list of PXE boot servers for a given server type * * @v dhcp DHCP session * @v raw DHCP PXE boot server list * @v raw_len Length of DHCP PXE boot server list * @v ip IP address list to fill in * * The caller must ensure that the IP address list has sufficient * space. */ static void pxebs_list ( struct dhcp_session *dhcp, void *raw, size_t raw_len, struct in_addr *ip ) { struct dhcp_pxe_boot_server *server = raw; size_t server_len; unsigned int i; while ( raw_len ) { if ( raw_len < sizeof ( *server ) ) { DBGC ( dhcp, "DHCP %p malformed PXE server list\n", dhcp ); break; } server_len = offsetof ( typeof ( *server ), ip[ server->num_ip ] ); if ( raw_len < server_len ) { DBGC ( dhcp, "DHCP %p malformed PXE server list\n", dhcp ); break; } if ( server->type == dhcp->pxe_type ) { for ( i = 0 ; i < server->num_ip ; i++ ) *(ip++) = server->ip[i]; } server = ( ( ( void * ) server ) + server_len ); raw_len -= server_len; } } /** * Start PXE Boot Server Discovery on a network device * * @v job Job control interface * @v netdev Network device * @v pxe_type PXE server type * @ret rc Return status code * * Starts PXE Boot Server Discovery on the specified network device. * If successful, the Boot Server ACK will be registered as an option * source. */ int start_pxebs ( struct job_interface *job, struct net_device *netdev, unsigned int pxe_type ) { struct setting pxe_discovery_control_setting = { .tag = DHCP_PXE_DISCOVERY_CONTROL }; struct setting pxe_boot_servers_setting = { .tag = DHCP_PXE_BOOT_SERVERS }; struct setting pxe_boot_server_mcast_setting = { .tag = DHCP_PXE_BOOT_SERVER_MCAST }; ssize_t pxebs_list_len; struct dhcp_session *dhcp; struct in_addr *ip; unsigned int pxe_discovery_control; int rc; /* Get upper bound for PXE boot server IP address list */ pxebs_list_len = fetch_setting_len ( NULL, &pxe_boot_servers_setting ); if ( pxebs_list_len < 0 ) pxebs_list_len = 0; /* Allocate and initialise structure */ dhcp = zalloc ( sizeof ( *dhcp ) + sizeof ( *ip ) /* mcast */ + sizeof ( *ip ) /* bcast */ + pxebs_list_len + sizeof ( *ip ) /* terminator */ ); if ( ! dhcp ) return -ENOMEM; dhcp->refcnt.free = dhcp_free; job_init ( &dhcp->job, &dhcp_job_operations, &dhcp->refcnt ); xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt ); dhcp->netdev = netdev_get ( netdev ); dhcp->local.sin_family = AF_INET; fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting, &dhcp->local.sin_addr ); dhcp->local.sin_port = htons ( BOOTPC_PORT ); dhcp->pxe_type = htons ( pxe_type ); dhcp->timer.expired = dhcp_timer_expired; /* Construct PXE boot server IP address lists */ pxe_discovery_control = fetch_uintz_setting ( NULL, &pxe_discovery_control_setting ); ip = ( ( ( void * ) dhcp ) + sizeof ( *dhcp ) ); dhcp->pxe_attempt = ip; if ( ! ( pxe_discovery_control & PXEBS_NO_MULTICAST ) ) { fetch_ipv4_setting ( NULL, &pxe_boot_server_mcast_setting, ip); if ( ip->s_addr ) ip++; } if ( ! ( pxe_discovery_control & PXEBS_NO_BROADCAST ) ) (ip++)->s_addr = INADDR_BROADCAST; if ( pxe_discovery_control & PXEBS_NO_UNKNOWN_SERVERS ) dhcp->pxe_accept = ip; if ( pxebs_list_len ) { uint8_t buf[pxebs_list_len]; fetch_setting ( NULL, &pxe_boot_servers_setting, buf, sizeof ( buf ) ); pxebs_list ( dhcp, buf, sizeof ( buf ), ip ); } if ( ! dhcp->pxe_attempt->s_addr ) { DBGC ( dhcp, "DHCP %p has no PXE boot servers for type %04x\n", dhcp, pxe_type ); rc = -EINVAL; goto err; } /* Dump out PXE server lists */ DBGC ( dhcp, "DHCP %p attempting", dhcp ); for ( ip = dhcp->pxe_attempt ; ip->s_addr ; ip++ ) DBGC ( dhcp, " %s", inet_ntoa ( *ip ) ); DBGC ( dhcp, "\n" ); if ( dhcp->pxe_accept ) { DBGC ( dhcp, "DHCP %p accepting", dhcp ); for ( ip = dhcp->pxe_accept ; ip->s_addr ; ip++ ) DBGC ( dhcp, " %s", inet_ntoa ( *ip ) ); DBGC ( dhcp, "\n" ); } /* Instantiate child objects and attach to our interfaces */ if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer, ( struct sockaddr * ) &dhcp->local ) ) != 0 ) goto err; /* Enter PXEBS state */ dhcp_set_state ( dhcp, &dhcp_state_pxebs ); /* Attach parent interface, mortalise self, and return */ job_plug_plug ( &dhcp->job, job ); ref_put ( &dhcp->refcnt ); return 0; err: dhcp_finished ( dhcp, rc ); ref_put ( &dhcp->refcnt ); return rc; } debian/grub-extras/disabled/gpxe/src/net/udp/tftp.c0000664000000000000000000007457612524662415017465 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * TFTP protocol * */ FEATURE ( FEATURE_PROTOCOL, "TFTP", DHCP_EB_FEATURE_TFTP, 1 ); /* TFTP-specific error codes */ #define ETFTP_INVALID_BLKSIZE EUNIQ_01 #define ETFTP_INVALID_TSIZE EUNIQ_02 #define ETFTP_MC_NO_PORT EUNIQ_03 #define ETFTP_MC_NO_MC EUNIQ_04 #define ETFTP_MC_INVALID_MC EUNIQ_05 #define ETFTP_MC_INVALID_IP EUNIQ_06 #define ETFTP_MC_INVALID_PORT EUNIQ_07 /** * A TFTP request * * This data structure holds the state for an ongoing TFTP transfer. */ struct tftp_request { /** Reference count */ struct refcnt refcnt; /** Data transfer interface */ struct xfer_interface xfer; /** URI being fetched */ struct uri *uri; /** Transport layer interface */ struct xfer_interface socket; /** Multicast transport layer interface */ struct xfer_interface mc_socket; /** Data block size * * This is the "blksize" option negotiated with the TFTP * server. (If the TFTP server does not support TFTP options, * this will default to 512). */ unsigned int blksize; /** File size * * This is the value returned in the "tsize" option from the * TFTP server. If the TFTP server does not support the * "tsize" option, this value will be zero. */ unsigned long tsize; /** Server port * * This is the port to which RRQ packets are sent. */ unsigned int port; /** Peer address * * The peer address is determined by the first response * received to the TFTP RRQ. */ struct sockaddr_tcpip peer; /** Request flags */ unsigned int flags; /** MTFTP timeout count */ unsigned int mtftp_timeouts; /** Block bitmap */ struct bitmap bitmap; /** Maximum known length * * We don't always know the file length in advance. In * particular, if the TFTP server doesn't support the tsize * option, or we are using MTFTP, then we don't know the file * length until we see the end-of-file block (which, in the * case of MTFTP, may not be the last block we see). * * This value is updated whenever we obtain information about * the file length. */ size_t filesize; /** Retransmission timer */ struct retry_timer timer; }; /** TFTP request flags */ enum { /** Send ACK packets */ TFTP_FL_SEND_ACK = 0x0001, /** Request blksize and tsize options */ TFTP_FL_RRQ_SIZES = 0x0002, /** Request multicast option */ TFTP_FL_RRQ_MULTICAST = 0x0004, /** Perform MTFTP recovery on timeout */ TFTP_FL_MTFTP_RECOVERY = 0x0008, }; /** Maximum number of MTFTP open requests before falling back to TFTP */ #define MTFTP_MAX_TIMEOUTS 3 /** * Free TFTP request * * @v refcnt Reference counter */ static void tftp_free ( struct refcnt *refcnt ) { struct tftp_request *tftp = container_of ( refcnt, struct tftp_request, refcnt ); uri_put ( tftp->uri ); bitmap_free ( &tftp->bitmap ); free ( tftp ); } /** * Mark TFTP request as complete * * @v tftp TFTP connection * @v rc Return status code */ static void tftp_done ( struct tftp_request *tftp, int rc ) { DBGC ( tftp, "TFTP %p finished with status %d (%s)\n", tftp, rc, strerror ( rc ) ); /* Stop the retry timer */ stop_timer ( &tftp->timer ); /* Close all data transfer interfaces */ xfer_nullify ( &tftp->socket ); xfer_close ( &tftp->socket, rc ); xfer_nullify ( &tftp->mc_socket ); xfer_close ( &tftp->mc_socket, rc ); xfer_nullify ( &tftp->xfer ); xfer_close ( &tftp->xfer, rc ); } /** * Reopen TFTP socket * * @v tftp TFTP connection * @ret rc Return status code */ static int tftp_reopen ( struct tftp_request *tftp ) { struct sockaddr_tcpip server; int rc; /* Close socket */ xfer_close ( &tftp->socket, 0 ); /* Disable ACK sending. */ tftp->flags &= ~TFTP_FL_SEND_ACK; /* Reset peer address */ memset ( &tftp->peer, 0, sizeof ( tftp->peer ) ); /* Open socket */ memset ( &server, 0, sizeof ( server ) ); server.st_port = htons ( tftp->port ); if ( ( rc = xfer_open_named_socket ( &tftp->socket, SOCK_DGRAM, ( struct sockaddr * ) &server, tftp->uri->host, NULL ) ) != 0 ) { DBGC ( tftp, "TFTP %p could not open socket: %s\n", tftp, strerror ( rc ) ); return rc; } return 0; } /** * Reopen TFTP multicast socket * * @v tftp TFTP connection * @v local Local socket address * @ret rc Return status code */ static int tftp_reopen_mc ( struct tftp_request *tftp, struct sockaddr *local ) { int rc; /* Close multicast socket */ xfer_close ( &tftp->mc_socket, 0 ); /* Open multicast socket. We never send via this socket, so * use the local address as the peer address (since the peer * address cannot be NULL). */ if ( ( rc = xfer_open_socket ( &tftp->mc_socket, SOCK_DGRAM, local, local ) ) != 0 ) { DBGC ( tftp, "TFTP %p could not open multicast " "socket: %s\n", tftp, strerror ( rc ) ); return rc; } return 0; } /** * Presize TFTP receive buffers and block bitmap * * @v tftp TFTP connection * @v filesize Known minimum file size * @ret rc Return status code */ static int tftp_presize ( struct tftp_request *tftp, size_t filesize ) { unsigned int num_blocks; int rc; /* Do nothing if we are already large enough */ if ( filesize <= tftp->filesize ) return 0; /* Record filesize */ tftp->filesize = filesize; /* Notify recipient of file size */ xfer_seek ( &tftp->xfer, filesize, SEEK_SET ); xfer_seek ( &tftp->xfer, 0, SEEK_SET ); /* Calculate expected number of blocks. Note that files whose * length is an exact multiple of the blocksize will have a * trailing zero-length block, which must be included. */ num_blocks = ( ( filesize / tftp->blksize ) + 1 ); if ( ( rc = bitmap_resize ( &tftp->bitmap, num_blocks ) ) != 0 ) { DBGC ( tftp, "TFTP %p could not resize bitmap to %d blocks: " "%s\n", tftp, num_blocks, strerror ( rc ) ); return rc; } return 0; } /** * TFTP requested blocksize * * This is treated as a global configuration parameter. */ static unsigned int tftp_request_blksize = TFTP_MAX_BLKSIZE; /** * Set TFTP request blocksize * * @v blksize Requested block size */ void tftp_set_request_blksize ( unsigned int blksize ) { if ( blksize < TFTP_DEFAULT_BLKSIZE ) blksize = TFTP_DEFAULT_BLKSIZE; tftp_request_blksize = blksize; } /** * MTFTP multicast receive address * * This is treated as a global configuration parameter. */ static struct sockaddr_in tftp_mtftp_socket = { .sin_family = AF_INET, .sin_addr.s_addr = htonl ( 0xefff0101 ), .sin_port = htons ( 3001 ), }; /** * Set MTFTP multicast address * * @v address Multicast IPv4 address */ void tftp_set_mtftp_address ( struct in_addr address ) { tftp_mtftp_socket.sin_addr = address; } /** * Set MTFTP multicast port * * @v port Multicast port */ void tftp_set_mtftp_port ( unsigned int port ) { tftp_mtftp_socket.sin_port = htons ( port ); } /** * Transmit RRQ * * @v tftp TFTP connection * @ret rc Return status code */ static int tftp_send_rrq ( struct tftp_request *tftp ) { struct tftp_rrq *rrq; const char *path; size_t len; struct io_buffer *iobuf; /* Strip initial '/' if present. If we were opened via the * URI interface, then there will be an initial '/', since a * full tftp:// URI provides no way to specify a non-absolute * path. However, many TFTP servers (particularly Windows * TFTP servers) complain about having an initial '/', and it * violates user expectations to have a '/' silently added to * the DHCP-specified filename. */ path = tftp->uri->path; if ( *path == '/' ) path++; DBGC ( tftp, "TFTP %p requesting \"%s\"\n", tftp, path ); /* Allocate buffer */ len = ( sizeof ( *rrq ) + strlen ( path ) + 1 /* NUL */ + 5 + 1 /* "octet" + NUL */ + 7 + 1 + 5 + 1 /* "blksize" + NUL + ddddd + NUL */ + 5 + 1 + 1 + 1 /* "tsize" + NUL + "0" + NUL */ + 9 + 1 + 1 /* "multicast" + NUL + NUL */ ); iobuf = xfer_alloc_iob ( &tftp->socket, len ); if ( ! iobuf ) return -ENOMEM; /* Build request */ rrq = iob_put ( iobuf, sizeof ( *rrq ) ); rrq->opcode = htons ( TFTP_RRQ ); iob_put ( iobuf, snprintf ( iobuf->tail, iob_tailroom ( iobuf ), "%s%coctet", path, 0 ) + 1 ); if ( tftp->flags & TFTP_FL_RRQ_SIZES ) { iob_put ( iobuf, snprintf ( iobuf->tail, iob_tailroom ( iobuf ), "blksize%c%d%ctsize%c0", 0, tftp_request_blksize, 0, 0 ) + 1 ); } if ( tftp->flags & TFTP_FL_RRQ_MULTICAST ) { iob_put ( iobuf, snprintf ( iobuf->tail, iob_tailroom ( iobuf ), "multicast%c", 0 ) + 1 ); } /* RRQ always goes to the address specified in the initial * xfer_open() call */ return xfer_deliver_iob ( &tftp->socket, iobuf ); } /** * Transmit ACK * * @v tftp TFTP connection * @ret rc Return status code */ static int tftp_send_ack ( struct tftp_request *tftp ) { struct tftp_ack *ack; struct io_buffer *iobuf; struct xfer_metadata meta = { .dest = ( struct sockaddr * ) &tftp->peer, }; unsigned int block; /* Determine next required block number */ block = bitmap_first_gap ( &tftp->bitmap ); DBGC2 ( tftp, "TFTP %p sending ACK for block %d\n", tftp, block ); /* Allocate buffer */ iobuf = xfer_alloc_iob ( &tftp->socket, sizeof ( *ack ) ); if ( ! iobuf ) return -ENOMEM; /* Build ACK */ ack = iob_put ( iobuf, sizeof ( *ack ) ); ack->opcode = htons ( TFTP_ACK ); ack->block = htons ( block ); /* ACK always goes to the peer recorded from the RRQ response */ return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta ); } /** * Transmit next relevant packet * * @v tftp TFTP connection * @ret rc Return status code */ static int tftp_send_packet ( struct tftp_request *tftp ) { /* Update retransmission timer */ stop_timer ( &tftp->timer ); start_timer ( &tftp->timer ); /* Send RRQ or ACK as appropriate */ if ( ! tftp->peer.st_family ) { return tftp_send_rrq ( tftp ); } else { if ( tftp->flags & TFTP_FL_SEND_ACK ) { return tftp_send_ack ( tftp ); } else { return 0; } } } /** * Handle TFTP retransmission timer expiry * * @v timer Retry timer * @v fail Failure indicator */ static void tftp_timer_expired ( struct retry_timer *timer, int fail ) { struct tftp_request *tftp = container_of ( timer, struct tftp_request, timer ); int rc; /* If we are doing MTFTP, attempt the various recovery strategies */ if ( tftp->flags & TFTP_FL_MTFTP_RECOVERY ) { if ( tftp->peer.st_family ) { /* If we have received any response from the server, * try resending the RRQ to restart the download. */ DBGC ( tftp, "TFTP %p attempting reopen\n", tftp ); if ( ( rc = tftp_reopen ( tftp ) ) != 0 ) goto err; } else { /* Fall back to plain TFTP after several attempts */ tftp->mtftp_timeouts++; DBGC ( tftp, "TFTP %p timeout %d waiting for MTFTP " "open\n", tftp, tftp->mtftp_timeouts ); if ( tftp->mtftp_timeouts > MTFTP_MAX_TIMEOUTS ) { DBGC ( tftp, "TFTP %p falling back to plain " "TFTP\n", tftp ); tftp->flags = TFTP_FL_RRQ_SIZES; /* Close multicast socket */ xfer_close ( &tftp->mc_socket, 0 ); /* Reset retry timer */ start_timer_nodelay ( &tftp->timer ); /* The blocksize may change: discard * the block bitmap */ bitmap_free ( &tftp->bitmap ); memset ( &tftp->bitmap, 0, sizeof ( tftp->bitmap ) ); /* Reopen on standard TFTP port */ tftp->port = TFTP_PORT; if ( ( rc = tftp_reopen ( tftp ) ) != 0 ) goto err; } } } else { /* Not doing MTFTP (or have fallen back to plain * TFTP); fail as per normal. */ if ( fail ) { rc = -ETIMEDOUT; goto err; } } tftp_send_packet ( tftp ); return; err: tftp_done ( tftp, rc ); } /** * Process TFTP "blksize" option * * @v tftp TFTP connection * @v value Option value * @ret rc Return status code */ static int tftp_process_blksize ( struct tftp_request *tftp, const char *value ) { char *end; tftp->blksize = strtoul ( value, &end, 10 ); if ( *end ) { DBGC ( tftp, "TFTP %p got invalid blksize \"%s\"\n", tftp, value ); return -( EINVAL | ETFTP_INVALID_BLKSIZE ); } DBGC ( tftp, "TFTP %p blksize=%d\n", tftp, tftp->blksize ); return 0; } /** * Process TFTP "tsize" option * * @v tftp TFTP connection * @v value Option value * @ret rc Return status code */ static int tftp_process_tsize ( struct tftp_request *tftp, const char *value ) { char *end; tftp->tsize = strtoul ( value, &end, 10 ); if ( *end ) { DBGC ( tftp, "TFTP %p got invalid tsize \"%s\"\n", tftp, value ); return -( EINVAL | ETFTP_INVALID_TSIZE ); } DBGC ( tftp, "TFTP %p tsize=%ld\n", tftp, tftp->tsize ); return 0; } /** * Process TFTP "multicast" option * * @v tftp TFTP connection * @v value Option value * @ret rc Return status code */ static int tftp_process_multicast ( struct tftp_request *tftp, const char *value ) { union { struct sockaddr sa; struct sockaddr_in sin; } socket; char buf[ strlen ( value ) + 1 ]; char *addr; char *port; char *port_end; char *mc; char *mc_end; int rc; /* Split value into "addr,port,mc" fields */ memcpy ( buf, value, sizeof ( buf ) ); addr = buf; port = strchr ( addr, ',' ); if ( ! port ) { DBGC ( tftp, "TFTP %p multicast missing port,mc\n", tftp ); return -( EINVAL | ETFTP_MC_NO_PORT ); } *(port++) = '\0'; mc = strchr ( port, ',' ); if ( ! mc ) { DBGC ( tftp, "TFTP %p multicast missing mc\n", tftp ); return -( EINVAL | ETFTP_MC_NO_MC ); } *(mc++) = '\0'; /* Parse parameters */ if ( strtoul ( mc, &mc_end, 0 ) == 0 ) tftp->flags &= ~TFTP_FL_SEND_ACK; if ( *mc_end ) { DBGC ( tftp, "TFTP %p multicast invalid mc %s\n", tftp, mc ); return -( EINVAL | ETFTP_MC_INVALID_MC ); } DBGC ( tftp, "TFTP %p is%s the master client\n", tftp, ( ( tftp->flags & TFTP_FL_SEND_ACK ) ? "" : " not" ) ); if ( *addr && *port ) { socket.sin.sin_family = AF_INET; if ( inet_aton ( addr, &socket.sin.sin_addr ) == 0 ) { DBGC ( tftp, "TFTP %p multicast invalid IP address " "%s\n", tftp, addr ); return -( EINVAL | ETFTP_MC_INVALID_IP ); } DBGC ( tftp, "TFTP %p multicast IP address %s\n", tftp, inet_ntoa ( socket.sin.sin_addr ) ); socket.sin.sin_port = htons ( strtoul ( port, &port_end, 0 ) ); if ( *port_end ) { DBGC ( tftp, "TFTP %p multicast invalid port %s\n", tftp, port ); return -( EINVAL | ETFTP_MC_INVALID_PORT ); } DBGC ( tftp, "TFTP %p multicast port %d\n", tftp, ntohs ( socket.sin.sin_port ) ); if ( ( rc = tftp_reopen_mc ( tftp, &socket.sa ) ) != 0 ) return rc; } return 0; } /** A TFTP option */ struct tftp_option { /** Option name */ const char *name; /** Option processor * * @v tftp TFTP connection * @v value Option value * @ret rc Return status code */ int ( * process ) ( struct tftp_request *tftp, const char *value ); }; /** Recognised TFTP options */ static struct tftp_option tftp_options[] = { { "blksize", tftp_process_blksize }, { "tsize", tftp_process_tsize }, { "multicast", tftp_process_multicast }, { NULL, NULL } }; /** * Process TFTP option * * @v tftp TFTP connection * @v name Option name * @v value Option value * @ret rc Return status code */ static int tftp_process_option ( struct tftp_request *tftp, const char *name, const char *value ) { struct tftp_option *option; for ( option = tftp_options ; option->name ; option++ ) { if ( strcasecmp ( name, option->name ) == 0 ) return option->process ( tftp, value ); } DBGC ( tftp, "TFTP %p received unknown option \"%s\" = \"%s\"\n", tftp, name, value ); /* Unknown options should be silently ignored */ return 0; } /** * Receive OACK * * @v tftp TFTP connection * @v buf Temporary data buffer * @v len Length of temporary data buffer * @ret rc Return status code */ static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) { struct tftp_oack *oack = buf; char *end = buf + len; char *name; char *value; char *next; int rc = 0; /* Sanity check */ if ( len < sizeof ( *oack ) ) { DBGC ( tftp, "TFTP %p received underlength OACK packet " "length %zd\n", tftp, len ); rc = -EINVAL; goto done; } /* Process each option in turn */ for ( name = oack->data ; name < end ; name = next ) { /* Parse option name and value * * We treat parsing errors as non-fatal, because there * exists at least one TFTP server (IBM Tivoli PXE * Server 5.1.0.3) that has been observed to send * malformed OACKs containing trailing garbage bytes. */ value = ( name + strnlen ( name, ( end - name ) ) + 1 ); if ( value > end ) { DBGC ( tftp, "TFTP %p received OACK with malformed " "option name:\n", tftp ); DBGC_HD ( tftp, oack, len ); break; } if ( value == end ) { DBGC ( tftp, "TFTP %p received OACK missing value " "for option \"%s\"\n", tftp, name ); DBGC_HD ( tftp, oack, len ); break; } next = ( value + strnlen ( value, ( end - value ) ) + 1 ); if ( next > end ) { DBGC ( tftp, "TFTP %p received OACK with malformed " "value for option \"%s\":\n", tftp, name ); DBGC_HD ( tftp, oack, len ); break; } /* Process option */ if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 ) goto done; } /* Process tsize information, if available */ if ( tftp->tsize ) { if ( ( rc = tftp_presize ( tftp, tftp->tsize ) ) != 0 ) goto done; } /* Request next data block */ tftp_send_packet ( tftp ); done: if ( rc ) tftp_done ( tftp, rc ); return rc; } /** * Receive DATA * * @v tftp TFTP connection * @v iobuf I/O buffer * @ret rc Return status code * * Takes ownership of I/O buffer. */ static int tftp_rx_data ( struct tftp_request *tftp, struct io_buffer *iobuf ) { struct tftp_data *data = iobuf->data; struct xfer_metadata meta; int block; off_t offset; size_t data_len; int rc; /* Sanity check */ if ( iob_len ( iobuf ) < sizeof ( *data ) ) { DBGC ( tftp, "TFTP %p received underlength DATA packet " "length %zd\n", tftp, iob_len ( iobuf ) ); rc = -EINVAL; goto done; } if ( data->block == 0 ) { DBGC ( tftp, "TFTP %p received data block 0\n", tftp ); rc = -EINVAL; goto done; } /* Extract data */ block = ( ntohs ( data->block ) - 1 ); offset = ( block * tftp->blksize ); iob_pull ( iobuf, sizeof ( *data ) ); data_len = iob_len ( iobuf ); if ( data_len > tftp->blksize ) { DBGC ( tftp, "TFTP %p received overlength DATA packet " "length %zd\n", tftp, data_len ); rc = -EINVAL; goto done; } /* Deliver data */ memset ( &meta, 0, sizeof ( meta ) ); meta.whence = SEEK_SET; meta.offset = offset; if ( ( rc = xfer_deliver_iob_meta ( &tftp->xfer, iob_disown ( iobuf ), &meta ) ) != 0 ) { DBGC ( tftp, "TFTP %p could not deliver data: %s\n", tftp, strerror ( rc ) ); goto done; } /* Ensure block bitmap is ready */ if ( ( rc = tftp_presize ( tftp, ( offset + data_len ) ) ) != 0 ) goto done; /* Mark block as received */ bitmap_set ( &tftp->bitmap, block ); /* Acknowledge block */ tftp_send_packet ( tftp ); /* If all blocks have been received, finish. */ if ( bitmap_full ( &tftp->bitmap ) ) tftp_done ( tftp, 0 ); done: free_iob ( iobuf ); if ( rc ) tftp_done ( tftp, rc ); return rc; } /** Translation between TFTP errors and internal error numbers */ static const int tftp_errors[] = { [TFTP_ERR_FILE_NOT_FOUND] = ENOENT, [TFTP_ERR_ACCESS_DENIED] = EACCES, [TFTP_ERR_ILLEGAL_OP] = ENOTSUP, }; /** * Receive ERROR * * @v tftp TFTP connection * @v buf Temporary data buffer * @v len Length of temporary data buffer * @ret rc Return status code */ static int tftp_rx_error ( struct tftp_request *tftp, void *buf, size_t len ) { struct tftp_error *error = buf; unsigned int err; int rc = 0; /* Sanity check */ if ( len < sizeof ( *error ) ) { DBGC ( tftp, "TFTP %p received underlength ERROR packet " "length %zd\n", tftp, len ); return -EINVAL; } DBGC ( tftp, "TFTP %p received ERROR packet with code %d, message " "\"%s\"\n", tftp, ntohs ( error->errcode ), error->errmsg ); /* Determine final operation result */ err = ntohs ( error->errcode ); if ( err < ( sizeof ( tftp_errors ) / sizeof ( tftp_errors[0] ) ) ) rc = -tftp_errors[err]; if ( ! rc ) rc = -ENOTSUP; /* Close TFTP request */ tftp_done ( tftp, rc ); return 0; } /** * Receive new data * * @v tftp TFTP connection * @v iobuf I/O buffer * @v meta Transfer metadata * @ret rc Return status code */ static int tftp_rx ( struct tftp_request *tftp, struct io_buffer *iobuf, struct xfer_metadata *meta ) { struct sockaddr_tcpip *st_src; struct tftp_common *common = iobuf->data; size_t len = iob_len ( iobuf ); int rc = -EINVAL; /* Sanity checks */ if ( len < sizeof ( *common ) ) { DBGC ( tftp, "TFTP %p received underlength packet length " "%zd\n", tftp, len ); goto done; } if ( ! meta->src ) { DBGC ( tftp, "TFTP %p received packet without source port\n", tftp ); goto done; } /* Filter by TID. Set TID on first response received */ st_src = ( struct sockaddr_tcpip * ) meta->src; if ( ! tftp->peer.st_family ) { memcpy ( &tftp->peer, st_src, sizeof ( tftp->peer ) ); DBGC ( tftp, "TFTP %p using remote port %d\n", tftp, ntohs ( tftp->peer.st_port ) ); } else if ( memcmp ( &tftp->peer, st_src, sizeof ( tftp->peer ) ) != 0 ) { DBGC ( tftp, "TFTP %p received packet from wrong source (got " "%d, wanted %d)\n", tftp, ntohs ( st_src->st_port ), ntohs ( tftp->peer.st_port ) ); goto done; } switch ( common->opcode ) { case htons ( TFTP_OACK ): rc = tftp_rx_oack ( tftp, iobuf->data, len ); break; case htons ( TFTP_DATA ): rc = tftp_rx_data ( tftp, iob_disown ( iobuf ) ); break; case htons ( TFTP_ERROR ): rc = tftp_rx_error ( tftp, iobuf->data, len ); break; default: DBGC ( tftp, "TFTP %p received strange packet type %d\n", tftp, ntohs ( common->opcode ) ); break; }; done: free_iob ( iobuf ); return rc; } /** * Receive new data via socket * * @v socket Transport layer interface * @v iobuf I/O buffer * @v meta Transfer metadata * @ret rc Return status code */ static int tftp_socket_deliver_iob ( struct xfer_interface *socket, struct io_buffer *iobuf, struct xfer_metadata *meta ) { struct tftp_request *tftp = container_of ( socket, struct tftp_request, socket ); /* Enable sending ACKs when we receive a unicast packet. This * covers three cases: * * 1. Standard TFTP; we should always send ACKs, and will * always receive a unicast packet before we need to send the * first ACK. * * 2. RFC2090 multicast TFTP; the only unicast packets we will * receive are the OACKs; enable sending ACKs here (before * processing the OACK) and disable it when processing the * multicast option if we are not the master client. * * 3. MTFTP; receiving a unicast datagram indicates that we * are the "master client" and should send ACKs. */ tftp->flags |= TFTP_FL_SEND_ACK; return tftp_rx ( tftp, iobuf, meta ); } /** TFTP socket operations */ static struct xfer_interface_operations tftp_socket_operations = { .close = ignore_xfer_close, .vredirect = xfer_vreopen, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = tftp_socket_deliver_iob, .deliver_raw = xfer_deliver_as_iob, }; /** * Receive new data via multicast socket * * @v mc_socket Multicast transport layer interface * @v iobuf I/O buffer * @v meta Transfer metadata * @ret rc Return status code */ static int tftp_mc_socket_deliver_iob ( struct xfer_interface *mc_socket, struct io_buffer *iobuf, struct xfer_metadata *meta ) { struct tftp_request *tftp = container_of ( mc_socket, struct tftp_request, mc_socket ); return tftp_rx ( tftp, iobuf, meta ); } /** TFTP multicast socket operations */ static struct xfer_interface_operations tftp_mc_socket_operations = { .close = ignore_xfer_close, .vredirect = xfer_vreopen, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = tftp_mc_socket_deliver_iob, .deliver_raw = xfer_deliver_as_iob, }; /** * Close TFTP data transfer interface * * @v xfer Data transfer interface * @v rc Reason for close */ static void tftp_xfer_close ( struct xfer_interface *xfer, int rc ) { struct tftp_request *tftp = container_of ( xfer, struct tftp_request, xfer ); DBGC ( tftp, "TFTP %p interface closed: %s\n", tftp, strerror ( rc ) ); tftp_done ( tftp, rc ); } /** * Check flow control window * * @v xfer Data transfer interface * @ret len Length of window */ static size_t tftp_xfer_window ( struct xfer_interface *xfer ) { struct tftp_request *tftp = container_of ( xfer, struct tftp_request, xfer ); /* We abuse this data-xfer method to convey the blocksize to * the caller. This really should be done using some kind of * stat() method, but we don't yet have the facility to do * that. */ return tftp->blksize; } /** TFTP data transfer interface operations */ static struct xfer_interface_operations tftp_xfer_operations = { .close = tftp_xfer_close, .vredirect = ignore_xfer_vredirect, .window = tftp_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, .deliver_raw = ignore_xfer_deliver_raw, }; /** * Initiate TFTP/TFTM/MTFTP download * * @v xfer Data transfer interface * @v uri Uniform Resource Identifier * @ret rc Return status code */ static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri, unsigned int default_port, struct sockaddr *multicast, unsigned int flags ) { struct tftp_request *tftp; int rc; /* Sanity checks */ if ( ! uri->host ) return -EINVAL; if ( ! uri->path ) return -EINVAL; /* Allocate and populate TFTP structure */ tftp = zalloc ( sizeof ( *tftp ) ); if ( ! tftp ) return -ENOMEM; tftp->refcnt.free = tftp_free; xfer_init ( &tftp->xfer, &tftp_xfer_operations, &tftp->refcnt ); tftp->uri = uri_get ( uri ); xfer_init ( &tftp->socket, &tftp_socket_operations, &tftp->refcnt ); xfer_init ( &tftp->mc_socket, &tftp_mc_socket_operations, &tftp->refcnt ); tftp->blksize = TFTP_DEFAULT_BLKSIZE; tftp->flags = flags; tftp->timer.expired = tftp_timer_expired; /* Open socket */ tftp->port = uri_port ( tftp->uri, default_port ); if ( ( rc = tftp_reopen ( tftp ) ) != 0 ) goto err; /* Open multicast socket */ if ( multicast ) { if ( ( rc = tftp_reopen_mc ( tftp, multicast ) ) != 0 ) goto err; } /* Start timer to initiate RRQ */ start_timer_nodelay ( &tftp->timer ); /* Attach to parent interface, mortalise self, and return */ xfer_plug_plug ( &tftp->xfer, xfer ); ref_put ( &tftp->refcnt ); return 0; err: DBGC ( tftp, "TFTP %p could not create request: %s\n", tftp, strerror ( rc ) ); tftp_done ( tftp, rc ); ref_put ( &tftp->refcnt ); return rc; } /** * Initiate TFTP download * * @v xfer Data transfer interface * @v uri Uniform Resource Identifier * @ret rc Return status code */ static int tftp_open ( struct xfer_interface *xfer, struct uri *uri ) { return tftp_core_open ( xfer, uri, TFTP_PORT, NULL, TFTP_FL_RRQ_SIZES ); } /** TFTP URI opener */ struct uri_opener tftp_uri_opener __uri_opener = { .scheme = "tftp", .open = tftp_open, }; /** * Initiate TFTM download * * @v xfer Data transfer interface * @v uri Uniform Resource Identifier * @ret rc Return status code */ static int tftm_open ( struct xfer_interface *xfer, struct uri *uri ) { return tftp_core_open ( xfer, uri, TFTP_PORT, NULL, ( TFTP_FL_RRQ_SIZES | TFTP_FL_RRQ_MULTICAST ) ); } /** TFTM URI opener */ struct uri_opener tftm_uri_opener __uri_opener = { .scheme = "tftm", .open = tftm_open, }; /** * Initiate MTFTP download * * @v xfer Data transfer interface * @v uri Uniform Resource Identifier * @ret rc Return status code */ static int mtftp_open ( struct xfer_interface *xfer, struct uri *uri ) { return tftp_core_open ( xfer, uri, MTFTP_PORT, ( struct sockaddr * ) &tftp_mtftp_socket, TFTP_FL_MTFTP_RECOVERY ); } /** MTFTP URI opener */ struct uri_opener mtftp_uri_opener __uri_opener = { .scheme = "mtftp", .open = mtftp_open, }; /****************************************************************************** * * Settings * ****************************************************************************** */ /** TFTP server setting */ struct setting next_server_setting __setting = { .name = "next-server", .description = "TFTP server", .tag = DHCP_EB_SIADDR, .type = &setting_type_ipv4, }; /** * Apply TFTP configuration settings * * @ret rc Return status code */ static int tftp_apply_settings ( void ) { static struct in_addr tftp_server = { 0 }; struct in_addr last_tftp_server; char uri_string[32]; struct uri *uri; /* Retrieve TFTP server setting */ last_tftp_server = tftp_server; fetch_ipv4_setting ( NULL, &next_server_setting, &tftp_server ); /* If TFTP server setting has changed, set the current working * URI to match. Do it only when the TFTP server has changed * to try to minimise surprises to the user, who probably * won't expect the CWURI to change just because they updated * an unrelated setting and triggered all the settings * applicators. */ if ( tftp_server.s_addr != last_tftp_server.s_addr ) { snprintf ( uri_string, sizeof ( uri_string ), "tftp://%s/", inet_ntoa ( tftp_server ) ); uri = parse_uri ( uri_string ); if ( ! uri ) return -ENOMEM; churi ( uri ); uri_put ( uri ); } return 0; } /** TFTP settings applicator */ struct settings_applicator tftp_settings_applicator __settings_applicator = { .apply = tftp_apply_settings, }; debian/grub-extras/disabled/gpxe/src/net/80211/0000775000000000000000000000000012524676037016211 5ustar debian/grub-extras/disabled/gpxe/src/net/80211/net80211.c0000664000000000000000000021675412524662415017551 0ustar /* * The gPXE 802.11 MAC layer. * * Copyright (c) 2009 Joshua Oreman . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * 802.11 device management */ /* Disambiguate the EINVAL's a bit */ #define EINVAL_PKT_TOO_SHORT ( EINVAL | EUNIQ_01 ) #define EINVAL_PKT_VERSION ( EINVAL | EUNIQ_02 ) #define EINVAL_PKT_NOT_DATA ( EINVAL | EUNIQ_03 ) #define EINVAL_PKT_NOT_FROMDS ( EINVAL | EUNIQ_04 ) #define EINVAL_PKT_LLC_HEADER ( EINVAL | EUNIQ_05 ) #define EINVAL_CRYPTO_REQUEST ( EINVAL | EUNIQ_06 ) #define EINVAL_ACTIVE_SCAN ( EINVAL | EUNIQ_07 ) /* * 802.11 error codes: The AP can give us a status code explaining why * authentication failed, or a reason code explaining why we were * deauthenticated/disassociated. These codes range from 0-63 (the * field is 16 bits wide, but only up to 45 or so are defined yet; we * allow up to 63 for extensibility). This is encoded into an error * code as such: * * status & 0x1f goes here --vv-- * Status code 0-31: ECONNREFUSED | EUNIQ_(status & 0x1f) (0e1a6038) * Status code 32-63: EHOSTUNREACH | EUNIQ_(status & 0x1f) (171a6011) * Reason code 0-31: ECONNRESET | EUNIQ_(reason & 0x1f) (0f1a6039) * Reason code 32-63: ENETRESET | EUNIQ_(reason & 0x1f) (271a6001) * * The POSIX error codes more or less convey the appropriate message * (status codes occur when we can't associate at all, reason codes * when we lose association unexpectedly) and let us extract the * complete 802.11 error code from the rc value. */ /** Make return status code from 802.11 status code */ #define E80211_STATUS( stat ) ( ((stat & 0x20)? EHOSTUNREACH : ECONNREFUSED) \ | ((stat & 0x1f) << 8) ) /** Make return status code from 802.11 reason code */ #define E80211_REASON( reas ) ( ((reas & 0x20)? ENETRESET : ECONNRESET) \ | ((reas & 0x1f) << 8) ) /** List of 802.11 devices */ static struct list_head net80211_devices = LIST_HEAD_INIT ( net80211_devices ); /** Set of device operations that does nothing */ static struct net80211_device_operations net80211_null_ops; /** Information associated with a received management packet * * This is used to keep beacon signal strengths in a parallel queue to * the beacons themselves. */ struct net80211_rx_info { int signal; struct list_head list; }; /** Context for a probe operation */ struct net80211_probe_ctx { /** 802.11 device to probe on */ struct net80211_device *dev; /** Value of keep_mgmt before probe was started */ int old_keep_mgmt; /** If scanning actively, pointer to probe packet to send */ struct io_buffer *probe; /** If non-"", the ESSID to limit ourselves to */ const char *essid; /** Time probe was started */ u32 ticks_start; /** Time last useful beacon was received */ u32 ticks_beacon; /** Time channel was last changed */ u32 ticks_channel; /** Time to stay on each channel */ u32 hop_time; /** Channels to hop by when changing channel */ int hop_step; /** List of best beacons for each network found so far */ struct list_head *beacons; }; /** Context for the association task */ struct net80211_assoc_ctx { /** Next authentication method to try using */ int method; /** Time (in ticks) of the last sent association-related packet */ int last_packet; /** Number of times we have tried sending it */ int times_tried; }; /** * @defgroup net80211_netdev Network device interface functions * @{ */ static int net80211_netdev_open ( struct net_device *netdev ); static void net80211_netdev_close ( struct net_device *netdev ); static int net80211_netdev_transmit ( struct net_device *netdev, struct io_buffer *iobuf ); static void net80211_netdev_poll ( struct net_device *netdev ); static void net80211_netdev_irq ( struct net_device *netdev, int enable ); /** @} */ /** * @defgroup net80211_linklayer 802.11 link-layer protocol functions * @{ */ static int net80211_ll_push ( struct net_device *netdev, struct io_buffer *iobuf, const void *ll_dest, const void *ll_source, uint16_t net_proto ); static int net80211_ll_pull ( struct net_device *netdev, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t * net_proto ); /** @} */ /** * @defgroup net80211_help 802.11 helper functions * @{ */ static void net80211_add_channels ( struct net80211_device *dev, int start, int len, int txpower ); static void net80211_filter_hw_channels ( struct net80211_device *dev ); static void net80211_set_rtscts_rate ( struct net80211_device *dev ); static int net80211_process_capab ( struct net80211_device *dev, u16 capab ); static int net80211_process_ie ( struct net80211_device *dev, union ieee80211_ie *ie, void *ie_end ); static union ieee80211_ie * net80211_marshal_request_info ( struct net80211_device *dev, union ieee80211_ie *ie ); /** @} */ /** * @defgroup net80211_assoc_ll 802.11 association handling functions * @{ */ static void net80211_step_associate ( struct process *proc ); static void net80211_handle_auth ( struct net80211_device *dev, struct io_buffer *iob ); static void net80211_handle_assoc_reply ( struct net80211_device *dev, struct io_buffer *iob ); static int net80211_send_disassoc ( struct net80211_device *dev, int reason ); static void net80211_handle_mgmt ( struct net80211_device *dev, struct io_buffer *iob, int signal ); /** @} */ /** * @defgroup net80211_frag 802.11 fragment handling functions * @{ */ static void net80211_free_frags ( struct net80211_device *dev, int fcid ); static struct io_buffer *net80211_accum_frags ( struct net80211_device *dev, int fcid, int nfrags, int size ); static void net80211_rx_frag ( struct net80211_device *dev, struct io_buffer *iob, int signal ); /** @} */ /** * @defgroup net80211_settings 802.11 settings handlers * @{ */ static int net80211_check_ssid_update ( void ); /** 802.11 settings applicator * * When the SSID is changed, this will cause any open devices to * re-associate. */ struct settings_applicator net80211_ssid_applicator __settings_applicator = { .apply = net80211_check_ssid_update, }; /** The network name to associate with * * If this is blank, we scan for all networks and use the one with the * greatest signal strength. */ struct setting net80211_ssid_setting __setting = { .name = "ssid", .description = "802.11 SSID (network name)", .type = &setting_type_string, }; /** Whether to use active scanning * * In order to associate with a hidden SSID, it's necessary to use an * active scan (send probe packets). If this setting is nonzero, an * active scan on the 2.4GHz band will be used to associate. */ struct setting net80211_active_setting __setting = { .name = "active-scan", .description = "Use an active scan during 802.11 association", .type = &setting_type_int8, }; /** @} */ /* ---------- net_device wrapper ---------- */ /** * Open 802.11 device and start association * * @v netdev Wrapping network device * @ret rc Return status code * * This sets up a default conservative set of channels for probing, * and starts the auto-association task unless the @c * NET80211_NO_ASSOC flag is set in the wrapped 802.11 device's @c * state field. */ static int net80211_netdev_open ( struct net_device *netdev ) { struct net80211_device *dev = netdev->priv; int rc = 0; if ( dev->op == &net80211_null_ops ) return -EFAULT; if ( dev->op->open ) rc = dev->op->open ( dev ); if ( rc < 0 ) return rc; if ( ! ( dev->state & NET80211_NO_ASSOC ) ) net80211_autoassociate ( dev ); return 0; } /** * Close 802.11 device * * @v netdev Wrapping network device. * * If the association task is running, this will stop it. */ static void net80211_netdev_close ( struct net_device *netdev ) { struct net80211_device *dev = netdev->priv; if ( dev->state & NET80211_WORKING ) process_del ( &dev->proc_assoc ); /* Send disassociation frame to AP, to be polite */ if ( dev->state & NET80211_ASSOCIATED ) net80211_send_disassoc ( dev, IEEE80211_REASON_LEAVING ); netdev_link_down ( netdev ); dev->state = 0; if ( dev->op->close ) dev->op->close ( dev ); } /** * Transmit packet on 802.11 device * * @v netdev Wrapping network device * @v iobuf I/O buffer * @ret rc Return status code * * If encryption is enabled for the currently associated network, the * packet will be encrypted prior to transmission. */ static int net80211_netdev_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { struct net80211_device *dev = netdev->priv; int rc = -ENOSYS; if ( dev->crypto ) { struct io_buffer *niob = dev->crypto->encrypt ( dev->crypto, iobuf ); if ( ! niob ) return -ENOMEM; /* only reason encryption could fail */ free_iob ( iobuf ); iobuf = niob; } if ( dev->op->transmit ) rc = dev->op->transmit ( dev, iobuf ); return rc; } /** * Poll 802.11 device for received packets and completed transmissions * * @v netdev Wrapping network device */ static void net80211_netdev_poll ( struct net_device *netdev ) { struct net80211_device *dev = netdev->priv; if ( dev->op->poll ) dev->op->poll ( dev ); } /** * Enable or disable interrupts for 802.11 device * * @v netdev Wrapping network device * @v enable Whether to enable interrupts */ static void net80211_netdev_irq ( struct net_device *netdev, int enable ) { struct net80211_device *dev = netdev->priv; if ( dev->op->irq ) dev->op->irq ( dev, enable ); } /** Network device operations for a wrapped 802.11 device */ static struct net_device_operations net80211_netdev_ops = { .open = net80211_netdev_open, .close = net80211_netdev_close, .transmit = net80211_netdev_transmit, .poll = net80211_netdev_poll, .irq = net80211_netdev_irq, }; /* ---------- 802.11 link-layer protocol ---------- */ /** 802.11 broadcast MAC address */ static u8 net80211_ll_broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; /** * Determine whether a transmission rate uses ERP/OFDM * * @v rate Rate in 100 kbps units * @ret is_erp TRUE if the rate is an ERP/OFDM rate * * 802.11b supports rates of 1.0, 2.0, 5.5, and 11.0 Mbps; any other * rate than these on the 2.4GHz spectrum is an ERP (802.11g) rate. */ static inline int net80211_rate_is_erp ( u16 rate ) { if ( rate == 10 || rate == 20 || rate == 55 || rate == 110 ) return 0; return 1; } /** * Calculate one frame's contribution to 802.11 duration field * * @v dev 802.11 device * @v bytes Amount of data to calculate duration for * @ret dur Duration field in microseconds * * To avoid multiple stations attempting to transmit at once, 802.11 * provides that every packet shall include a duration field * specifying a length of time for which the wireless medium will be * reserved after it is transmitted. The duration is measured in * microseconds and is calculated with respect to the current * physical-layer parameters of the 802.11 device. * * For an unfragmented data or management frame, or the last fragment * of a fragmented frame, the duration captures only the 10 data bytes * of one ACK; call once with bytes = 10. * * For a fragment of a data or management rame that will be followed * by more fragments, the duration captures an ACK, the following * fragment, and its ACK; add the results of three calls, two with * bytes = 10 and one with bytes set to the next fragment's size. * * For an RTS control frame, the duration captures the responding CTS, * the frame being sent, and its ACK; add the results of three calls, * two with bytes = 10 and one with bytes set to the next frame's size * (assuming unfragmented). * * For a CTS-to-self control frame, the duration captures the frame * being protected and its ACK; add the results of two calls, one with * bytes = 10 and one with bytes set to the next frame's size. * * No other frame types are currently supported by gPXE. */ u16 net80211_duration ( struct net80211_device *dev, int bytes, u16 rate ) { struct net80211_channel *chan = &dev->channels[dev->channel]; u32 kbps = rate * 100; if ( chan->band == NET80211_BAND_5GHZ || net80211_rate_is_erp ( rate ) ) { /* OFDM encoding (802.11a/g) */ int bits_per_symbol = ( kbps * 4 ) / 1000; /* 4us/symbol */ int bits = 22 + ( bytes << 3 ); /* 22-bit PLCP */ int symbols = ( bits + bits_per_symbol - 1 ) / bits_per_symbol; return 16 + 20 + ( symbols * 4 ); /* 16us SIFS, 20us preamble */ } else { /* CCK encoding (802.11b) */ int phy_time = 144 + 48; /* preamble + PLCP */ int bits = bytes << 3; int data_time = ( bits * 1000 + kbps - 1 ) / kbps; if ( dev->phy_flags & NET80211_PHY_USE_SHORT_PREAMBLE ) phy_time >>= 1; return 10 + phy_time + data_time; /* 10us SIFS */ } } /** * Add 802.11 link-layer header * * @v netdev Wrapping network device * @v iobuf I/O buffer * @v ll_dest Link-layer destination address * @v ll_source Link-layer source address * @v net_proto Network-layer protocol, in network byte order * @ret rc Return status code * * This adds both the 802.11 frame header and the 802.2 LLC/SNAP * header used on data packets. * * We also check here for state of the link that would make it invalid * to send a data packet; every data packet must pass through here, * and no non-data packet (e.g. management frame) should. */ static int net80211_ll_push ( struct net_device *netdev, struct io_buffer *iobuf, const void *ll_dest, const void *ll_source, uint16_t net_proto ) { struct net80211_device *dev = netdev->priv; struct ieee80211_frame *hdr = iob_push ( iobuf, IEEE80211_LLC_HEADER_LEN + IEEE80211_TYP_FRAME_HEADER_LEN ); struct ieee80211_llc_snap_header *lhdr = ( void * ) hdr + IEEE80211_TYP_FRAME_HEADER_LEN; /* We can't send data packets if we're not associated. */ if ( ! netdev_link_ok ( netdev ) ) { if ( dev->assoc_rc ) return dev->assoc_rc; return -ENETUNREACH; } hdr->fc = IEEE80211_THIS_VERSION | IEEE80211_TYPE_DATA | IEEE80211_STYPE_DATA | IEEE80211_FC_TODS; /* We don't send fragmented frames, so duration is the time for an SIFS + 10-byte ACK. */ hdr->duration = net80211_duration ( dev, 10, dev->rates[dev->rate] ); memcpy ( hdr->addr1, dev->bssid, ETH_ALEN ); memcpy ( hdr->addr2, ll_source, ETH_ALEN ); memcpy ( hdr->addr3, ll_dest, ETH_ALEN ); hdr->seq = IEEE80211_MAKESEQ ( ++dev->last_tx_seqnr, 0 ); lhdr->dsap = IEEE80211_LLC_DSAP; lhdr->ssap = IEEE80211_LLC_SSAP; lhdr->ctrl = IEEE80211_LLC_CTRL; memset ( lhdr->oui, 0x00, 3 ); lhdr->ethertype = net_proto; return 0; } /** * Remove 802.11 link-layer header * * @v netdev Wrapping network device * @v iobuf I/O buffer * @ret ll_dest Link-layer destination address * @ret ll_source Link-layer source * @ret net_proto Network-layer protocol, in network byte order * @ret rc Return status code * * This expects and removes both the 802.11 frame header and the 802.2 * LLC/SNAP header that are used on data packets. */ static int net80211_ll_pull ( struct net_device *netdev __unused, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t * net_proto ) { struct ieee80211_frame *hdr = iobuf->data; struct ieee80211_llc_snap_header *lhdr = ( void * ) hdr + IEEE80211_TYP_FRAME_HEADER_LEN; /* Bunch of sanity checks */ if ( iob_len ( iobuf ) < IEEE80211_TYP_FRAME_HEADER_LEN + IEEE80211_LLC_HEADER_LEN ) { DBGC ( netdev->priv, "802.11 %p packet too short (%zd bytes)\n", netdev->priv, iob_len ( iobuf ) ); return -EINVAL_PKT_TOO_SHORT; } if ( ( hdr->fc & IEEE80211_FC_VERSION ) != IEEE80211_THIS_VERSION ) { DBGC ( netdev->priv, "802.11 %p packet invalid version %04x\n", netdev->priv, hdr->fc & IEEE80211_FC_VERSION ); return -EINVAL_PKT_VERSION; } if ( ( hdr->fc & IEEE80211_FC_TYPE ) != IEEE80211_TYPE_DATA || ( hdr->fc & IEEE80211_FC_SUBTYPE ) != IEEE80211_STYPE_DATA ) { DBGC ( netdev->priv, "802.11 %p packet not data/data (fc=%04x)\n", netdev->priv, hdr->fc ); return -EINVAL_PKT_NOT_DATA; } if ( ( hdr->fc & ( IEEE80211_FC_TODS | IEEE80211_FC_FROMDS ) ) != IEEE80211_FC_FROMDS ) { DBGC ( netdev->priv, "802.11 %p packet not from DS (fc=%04x)\n", netdev->priv, hdr->fc ); return -EINVAL_PKT_NOT_FROMDS; } if ( lhdr->dsap != IEEE80211_LLC_DSAP || lhdr->ssap != IEEE80211_LLC_SSAP || lhdr->ctrl != IEEE80211_LLC_CTRL || lhdr->oui[0] || lhdr->oui[1] || lhdr->oui[2] ) { DBGC ( netdev->priv, "802.11 %p LLC header is not plain EtherType " "encapsulator: %02x->%02x [%02x] %02x:%02x:%02x %04x\n", netdev->priv, lhdr->dsap, lhdr->ssap, lhdr->ctrl, lhdr->oui[0], lhdr->oui[1], lhdr->oui[2], lhdr->ethertype ); return -EINVAL_PKT_LLC_HEADER; } iob_pull ( iobuf, sizeof ( *hdr ) + sizeof ( *lhdr ) ); *ll_dest = hdr->addr1; *ll_source = hdr->addr3; *net_proto = lhdr->ethertype; return 0; } /** 802.11 link-layer protocol */ static struct ll_protocol net80211_ll_protocol __ll_protocol = { .name = "802.11", .push = net80211_ll_push, .pull = net80211_ll_pull, .init_addr = eth_init_addr, .ntoa = eth_ntoa, .mc_hash = eth_mc_hash, .ll_proto = htons ( ARPHRD_ETHER ), /* "encapsulated Ethernet" */ .hw_addr_len = ETH_ALEN, .ll_addr_len = ETH_ALEN, .ll_header_len = IEEE80211_TYP_FRAME_HEADER_LEN + IEEE80211_LLC_HEADER_LEN, }; /* ---------- 802.11 network management API ---------- */ /** * Get 802.11 device from wrapping network device * * @v netdev Wrapping network device * @ret dev 802.11 device wrapped by network device, or NULL * * Returns NULL if the network device does not wrap an 802.11 device. */ struct net80211_device * net80211_get ( struct net_device *netdev ) { struct net80211_device *dev; list_for_each_entry ( dev, &net80211_devices, list ) { if ( netdev->priv == dev ) return netdev->priv; } return NULL; } /** * Set state of 802.11 device keeping management frames * * @v dev 802.11 device * @v enable Whether to keep management frames * @ret oldenab Whether management frames were enabled before this call * * If enable is TRUE, beacon, probe, and action frames will be kept * and may be retrieved by calling net80211_mgmt_dequeue(). */ int net80211_keep_mgmt ( struct net80211_device *dev, int enable ) { int oldenab = dev->keep_mgmt; dev->keep_mgmt = enable; return oldenab; } /** * Get 802.11 management frame * * @v dev 802.11 device * @ret signal Signal strength of returned management frame * @ret iob I/O buffer, or NULL if no management frame is queued * * Frames will only be returned by this function if * net80211_keep_mgmt() has been previously called with enable set to * TRUE. * * The calling function takes ownership of the returned I/O buffer. */ struct io_buffer * net80211_mgmt_dequeue ( struct net80211_device *dev, int *signal ) { struct io_buffer *iobuf; struct net80211_rx_info *rxi; list_for_each_entry ( rxi, &dev->mgmt_info_queue, list ) { list_del ( &rxi->list ); if ( signal ) *signal = rxi->signal; free ( rxi ); list_for_each_entry ( iobuf, &dev->mgmt_queue, list ) { list_del ( &iobuf->list ); return iobuf; } assert ( 0 ); } return NULL; } /** * Transmit 802.11 management frame * * @v dev 802.11 device * @v fc Frame Control flags for management frame * @v dest Destination access point * @v iob I/O buffer * @ret rc Return status code * * The @a fc argument must contain at least an IEEE 802.11 management * subtype number (e.g. IEEE80211_STYPE_PROBE_REQ). If it contains * IEEE80211_FC_PROTECTED, the frame will be encrypted prior to * transmission. * * It is required that @a iob have at least 24 bytes of headroom * reserved before its data start. */ int net80211_tx_mgmt ( struct net80211_device *dev, u16 fc, u8 dest[6], struct io_buffer *iob ) { struct ieee80211_frame *hdr = iob_push ( iob, IEEE80211_TYP_FRAME_HEADER_LEN ); hdr->fc = IEEE80211_THIS_VERSION | IEEE80211_TYPE_MGMT | ( fc & ~IEEE80211_FC_PROTECTED ); hdr->duration = net80211_duration ( dev, 10, dev->rates[dev->rate] ); hdr->seq = IEEE80211_MAKESEQ ( ++dev->last_tx_seqnr, 0 ); memcpy ( hdr->addr1, dest, ETH_ALEN ); /* DA = RA */ memcpy ( hdr->addr2, dev->netdev->ll_addr, ETH_ALEN ); /* SA = TA */ memcpy ( hdr->addr3, dest, ETH_ALEN ); /* BSSID */ if ( fc & IEEE80211_FC_PROTECTED ) { if ( ! dev->crypto ) return -EINVAL_CRYPTO_REQUEST; struct io_buffer *eiob = dev->crypto->encrypt ( dev->crypto, iob ); free_iob ( iob ); iob = eiob; } return netdev_tx ( dev->netdev, iob ); } /* ---------- Driver API ---------- */ /** * Allocate 802.11 device * * @v priv_size Size of driver-private allocation area * @ret dev Newly allocated 802.11 device * * This function allocates a net_device with space in its private area * for both the net80211_device it will wrap and the driver-private * data space requested. It initializes the link-layer-specific parts * of the net_device, and links the net80211_device to the net_device * appropriately. */ struct net80211_device * net80211_alloc ( size_t priv_size ) { struct net80211_device *dev; struct net_device *netdev = alloc_netdev ( sizeof ( *dev ) + priv_size ); if ( ! netdev ) return NULL; netdev->ll_protocol = &net80211_ll_protocol; netdev->ll_broadcast = net80211_ll_broadcast; netdev->max_pkt_len = IEEE80211_MAX_DATA_LEN; netdev_init ( netdev, &net80211_netdev_ops ); dev = netdev->priv; dev->netdev = netdev; dev->priv = ( u8 * ) dev + sizeof ( *dev ); dev->op = &net80211_null_ops; process_init_stopped ( &dev->proc_assoc, net80211_step_associate, &netdev->refcnt ); INIT_LIST_HEAD ( &dev->mgmt_queue ); INIT_LIST_HEAD ( &dev->mgmt_info_queue ); return dev; } /** * Register 802.11 device with network stack * * @v dev 802.11 device * @v ops 802.11 device operations * @v hw 802.11 hardware information * * This also registers the wrapping net_device with the higher network * layers. */ int net80211_register ( struct net80211_device *dev, struct net80211_device_operations *ops, struct net80211_hw_info *hw ) { dev->op = ops; dev->hw = malloc ( sizeof ( *hw ) ); if ( ! dev->hw ) return -ENOMEM; memcpy ( dev->hw, hw, sizeof ( *hw ) ); memcpy ( dev->netdev->hw_addr, hw->hwaddr, ETH_ALEN ); /* Set some sensible channel defaults for driver's open() function */ memcpy ( dev->channels, dev->hw->channels, NET80211_MAX_CHANNELS * sizeof ( dev->channels[0] ) ); dev->channel = 0; list_add_tail ( &dev->list, &net80211_devices ); return register_netdev ( dev->netdev ); } /** * Unregister 802.11 device from network stack * * @v dev 802.11 device * * After this call, the device operations are cleared so that they * will not be called. */ void net80211_unregister ( struct net80211_device *dev ) { unregister_netdev ( dev->netdev ); list_del ( &dev->list ); dev->op = &net80211_null_ops; } /** * Free 802.11 device * * @v dev 802.11 device * * The device should be unregistered before this function is called. */ void net80211_free ( struct net80211_device *dev ) { free ( dev->hw ); rc80211_free ( dev->rctl ); netdev_nullify ( dev->netdev ); netdev_put ( dev->netdev ); } /* ---------- 802.11 network management workhorse code ---------- */ /** * Set state of 802.11 device * * @v dev 802.11 device * @v clear Bitmask of flags to clear * @v set Bitmask of flags to set * @v status Status or reason code for most recent operation * * If @a status represents a reason code, it should be OR'ed with * NET80211_IS_REASON. * * Clearing authentication also clears association; clearing * association also clears security handshaking state. Clearing * association removes the link-up flag from the wrapping net_device, * but setting it does not automatically set the flag; that is left to * the judgment of higher-level code. */ static inline void net80211_set_state ( struct net80211_device *dev, short clear, short set, u16 status ) { /* The conditions in this function are deliberately formulated to be decidable at compile-time in most cases. Since clear and set are generally passed as constants, the body of this function can be reduced down to a few statements by the compiler. */ const int statmsk = NET80211_STATUS_MASK | NET80211_IS_REASON; if ( clear & NET80211_PROBED ) clear |= NET80211_AUTHENTICATED; if ( clear & NET80211_AUTHENTICATED ) clear |= NET80211_ASSOCIATED; if ( clear & NET80211_ASSOCIATED ) clear |= NET80211_CRYPTO_SYNCED; dev->state = ( dev->state & ~clear ) | set; dev->state = ( dev->state & ~statmsk ) | ( status & statmsk ); if ( clear & NET80211_ASSOCIATED ) netdev_link_down ( dev->netdev ); if ( ( clear | set ) & NET80211_ASSOCIATED ) dev->op->config ( dev, NET80211_CFG_ASSOC ); if ( status != 0 ) { if ( status & NET80211_IS_REASON ) dev->assoc_rc = -E80211_REASON ( status ); else dev->assoc_rc = -E80211_STATUS ( status ); netdev_link_err ( dev->netdev, dev->assoc_rc ); } } /** * Add channels to 802.11 device * * @v dev 802.11 device * @v start First channel number to add * @v len Number of channels to add * @v txpower TX power (dBm) to allow on added channels * * To replace the current list of channels instead of adding to it, * set the nr_channels field of the 802.11 device to 0 before calling * this function. */ static void net80211_add_channels ( struct net80211_device *dev, int start, int len, int txpower ) { int i, chan = start; for ( i = dev->nr_channels; len-- && i < NET80211_MAX_CHANNELS; i++ ) { dev->channels[i].channel_nr = chan; dev->channels[i].maxpower = txpower; dev->channels[i].hw_value = 0; if ( chan >= 1 && chan <= 14 ) { dev->channels[i].band = NET80211_BAND_2GHZ; if ( chan == 14 ) dev->channels[i].center_freq = 2484; else dev->channels[i].center_freq = 2407 + 5 * chan; chan++; } else { dev->channels[i].band = NET80211_BAND_5GHZ; dev->channels[i].center_freq = 5000 + 5 * chan; chan += 4; } } dev->nr_channels = i; } /** * Filter 802.11 device channels for hardware capabilities * * @v dev 802.11 device * * Hardware may support fewer channels than regulatory restrictions * allow; this function filters out channels in dev->channels that are * not supported by the hardware list in dev->hwinfo. It also copies * over the net80211_channel::hw_value and limits maximum TX power * appropriately. * * Channels are matched based on center frequency, ignoring band and * channel number. * * If the driver specifies no supported channels, the effect will be * as though all were supported. */ static void net80211_filter_hw_channels ( struct net80211_device *dev ) { int delta = 0, i = 0; int old_freq = dev->channels[dev->channel].center_freq; struct net80211_channel *chan, *hwchan; if ( ! dev->hw->nr_channels ) return; dev->channel = 0; for ( chan = dev->channels; chan < dev->channels + dev->nr_channels; chan++, i++ ) { int ok = 0; for ( hwchan = dev->hw->channels; hwchan < dev->hw->channels + dev->hw->nr_channels; hwchan++ ) { if ( hwchan->center_freq == chan->center_freq ) { ok = 1; break; } } if ( ! ok ) delta++; else { chan->hw_value = hwchan->hw_value; if ( hwchan->maxpower != 0 && chan->maxpower > hwchan->maxpower ) chan->maxpower = hwchan->maxpower; if ( old_freq == chan->center_freq ) dev->channel = i - delta; if ( delta ) chan[-delta] = *chan; } } dev->nr_channels -= delta; if ( dev->channels[dev->channel].center_freq != old_freq ) dev->op->config ( dev, NET80211_CFG_CHANNEL ); } /** * Update 802.11 device state to reflect received capabilities field * * @v dev 802.11 device * @v capab Capabilities field in beacon, probe, or association frame * @ret rc Return status code */ static int net80211_process_capab ( struct net80211_device *dev, u16 capab ) { u16 old_phy = dev->phy_flags; if ( ( capab & ( IEEE80211_CAPAB_MANAGED | IEEE80211_CAPAB_ADHOC ) ) != IEEE80211_CAPAB_MANAGED ) { DBGC ( dev, "802.11 %p cannot handle IBSS network\n", dev ); return -ENOSYS; } if ( capab & IEEE80211_CAPAB_SPECTRUM_MGMT ) { DBGC ( dev, "802.11 %p cannot handle spectrum managed " "network\n", dev ); return -ENOSYS; } dev->phy_flags &= ~( NET80211_PHY_USE_SHORT_PREAMBLE | NET80211_PHY_USE_SHORT_SLOT ); if ( capab & IEEE80211_CAPAB_SHORT_PMBL ) dev->phy_flags |= NET80211_PHY_USE_SHORT_PREAMBLE; if ( capab & IEEE80211_CAPAB_SHORT_SLOT ) dev->phy_flags |= NET80211_PHY_USE_SHORT_SLOT; if ( old_phy != dev->phy_flags ) dev->op->config ( dev, NET80211_CFG_PHY_PARAMS ); return 0; } /** * Update 802.11 device state to reflect received information elements * * @v dev 802.11 device * @v ie Pointer to first information element * @v ie_end Pointer to tail of packet I/O buffer * @ret rc Return status code */ static int net80211_process_ie ( struct net80211_device *dev, union ieee80211_ie *ie, void *ie_end ) { u16 old_rate = dev->rates[dev->rate]; u16 old_phy = dev->phy_flags; int have_rates = 0, i; int ds_channel = 0; int changed = 0; int band = dev->channels[dev->channel].band; if ( ( void * ) ie >= ie_end ) return 0; for ( ; ie; ie = ieee80211_next_ie ( ie, ie_end ) ) { switch ( ie->id ) { case IEEE80211_IE_SSID: if ( ie->len <= 32 ) { memcpy ( dev->essid, ie->ssid, ie->len ); dev->essid[ie->len] = 0; } break; case IEEE80211_IE_RATES: case IEEE80211_IE_EXT_RATES: if ( ! have_rates ) { dev->nr_rates = 0; dev->basic_rates = 0; have_rates = 1; } for ( i = 0; i < ie->len && dev->nr_rates < NET80211_MAX_RATES; i++ ) { u8 rid = ie->rates[i]; u16 rate = ( rid & 0x7f ) * 5; if ( rid & 0x80 ) dev->basic_rates |= ( 1 << dev->nr_rates ); dev->rates[dev->nr_rates++] = rate; } break; case IEEE80211_IE_DS_PARAM: if ( dev->channel < dev->nr_channels && ds_channel == dev->channels[dev->channel].channel_nr ) break; ds_channel = ie->ds_param.current_channel; net80211_change_channel ( dev, ds_channel ); break; case IEEE80211_IE_COUNTRY: dev->nr_channels = 0; DBGC ( dev, "802.11 %p setting country regulations " "for %c%c\n", dev, ie->country.name[0], ie->country.name[1] ); for ( i = 0; i < ( ie->len - 3 ) / 3; i++ ) { union ieee80211_ie_country_triplet *t = &ie->country.triplet[i]; if ( t->first > 200 ) { DBGC ( dev, "802.11 %p ignoring regulatory " "extension information\n", dev ); } else { net80211_add_channels ( dev, t->band.first_channel, t->band.nr_channels, t->band.max_txpower ); } } net80211_filter_hw_channels ( dev ); break; case IEEE80211_IE_ERP_INFO: dev->phy_flags &= ~( NET80211_PHY_USE_PROTECTION | NET80211_PHY_USE_SHORT_PREAMBLE ); if ( ie->erp_info & IEEE80211_ERP_USE_PROTECTION ) dev->phy_flags |= NET80211_PHY_USE_PROTECTION; if ( ! ( ie->erp_info & IEEE80211_ERP_BARKER_LONG ) ) dev->phy_flags |= NET80211_PHY_USE_SHORT_PREAMBLE; break; case IEEE80211_IE_RSN: /* XXX need to implement WPA stuff */ break; } } if ( have_rates ) { /* Allow only those rates that are also supported by the hardware. */ int delta = 0, j; dev->rate = 0; for ( i = 0; i < dev->nr_rates; i++ ) { int ok = 0; for ( j = 0; j < dev->hw->nr_rates[band]; j++ ) { if ( dev->hw->rates[band][j] == dev->rates[i] ){ ok = 1; break; } } if ( ! ok ) delta++; else { dev->rates[i - delta] = dev->rates[i]; if ( old_rate == dev->rates[i] ) dev->rate = i - delta; } } dev->nr_rates -= delta; /* Sort available rates - sorted subclumps tend to already exist, so insertion sort works well. */ for ( i = 1; i < dev->nr_rates; i++ ) { u16 rate = dev->rates[i]; for ( j = i - 1; j >= 0 && dev->rates[j] >= rate; j-- ) dev->rates[j + 1] = dev->rates[j]; dev->rates[j + 1] = rate; } net80211_set_rtscts_rate ( dev ); if ( dev->rates[dev->rate] != old_rate ) changed |= NET80211_CFG_RATE; } if ( dev->hw->flags & NET80211_HW_NO_SHORT_PREAMBLE ) dev->phy_flags &= ~NET80211_PHY_USE_SHORT_PREAMBLE; if ( dev->hw->flags & NET80211_HW_NO_SHORT_SLOT ) dev->phy_flags &= ~NET80211_PHY_USE_SHORT_SLOT; if ( old_phy != dev->phy_flags ) changed |= NET80211_CFG_PHY_PARAMS; if ( changed ) dev->op->config ( dev, changed ); return 0; } /** * Create information elements for outgoing probe or association packet * * @v dev 802.11 device * @v ie Pointer to start of information element area * @ret next_ie Pointer to first byte after added information elements */ static union ieee80211_ie * net80211_marshal_request_info ( struct net80211_device *dev, union ieee80211_ie *ie ) { int i; ie->id = IEEE80211_IE_SSID; ie->len = strlen ( dev->essid ); memcpy ( ie->ssid, dev->essid, ie->len ); ie = ieee80211_next_ie ( ie, NULL ); ie->id = IEEE80211_IE_RATES; ie->len = dev->nr_rates; for ( i = 0; i < ie->len; i++ ) { ie->rates[i] = dev->rates[i] / 5; if ( dev->basic_rates & ( 1 << i ) ) ie->rates[i] |= 0x80; } if ( ie->len > 8 ) { /* 802.11 requires we use an Extended Basic Rates IE for the rates beyond the eighth. */ int rates = ie->len; memmove ( ( void * ) ie + 2 + 8 + 2, ( void * ) ie + 2 + 8, rates - 8 ); ie->len = 8; ie = ieee80211_next_ie ( ie, NULL ); ie->id = IEEE80211_IE_EXT_RATES; ie->len = rates - 8; } ie = ieee80211_next_ie ( ie, NULL ); return ie; } /** Seconds to wait after finding a network, to possibly find better APs for it * * This is used when a specific SSID to scan for is specified. */ #define NET80211_PROBE_GATHER 1 /** Seconds to wait after finding a network, to possibly find other networks * * This is used when an empty SSID is specified, to scan for all * networks. */ #define NET80211_PROBE_GATHER_ALL 2 /** Seconds to allow a probe to take if no network has been found */ #define NET80211_PROBE_TIMEOUT 6 /** * Begin probe of 802.11 networks * * @v dev 802.11 device * @v essid SSID to probe for, or "" to accept any (may not be NULL) * @v active Whether to use active scanning * @ret ctx Probe context * * Active scanning may only be used on channels 1-11 in the 2.4GHz * band, due to gPXE's lack of a complete regulatory database. If * active scanning is used, probe packets will be sent on each * channel; this can allow association with hidden-SSID networks if * the SSID is properly specified. * * A @c NULL return indicates an out-of-memory condition. * * The returned context must be periodically passed to * net80211_probe_step() until that function returns zero. */ struct net80211_probe_ctx * net80211_probe_start ( struct net80211_device *dev, const char *essid, int active ) { struct net80211_probe_ctx *ctx = zalloc ( sizeof ( *ctx ) ); if ( ! ctx ) return NULL; assert ( dev->netdev->state & NETDEV_OPEN ); ctx->dev = dev; ctx->old_keep_mgmt = net80211_keep_mgmt ( dev, 1 ); ctx->essid = essid; if ( dev->essid != ctx->essid ) strcpy ( dev->essid, ctx->essid ); if ( active ) { struct ieee80211_probe_req *probe_req; union ieee80211_ie *ie; ctx->probe = alloc_iob ( 128 ); iob_reserve ( ctx->probe, IEEE80211_TYP_FRAME_HEADER_LEN ); probe_req = ctx->probe->data; ie = net80211_marshal_request_info ( dev, probe_req->info_element ); ie->id = IEEE80211_IE_REQUEST; ie->len = 3; ie->request[0] = IEEE80211_IE_COUNTRY; ie->request[1] = IEEE80211_IE_ERP_INFO; ie->request[2] = IEEE80211_IE_RSN; ie = ieee80211_next_ie ( ie, NULL ); iob_put ( ctx->probe, ( void * ) ie - ctx->probe->data ); } ctx->ticks_start = currticks(); ctx->ticks_beacon = 0; ctx->ticks_channel = currticks(); ctx->hop_time = ticks_per_sec() / ( active ? 2 : 6 ); /* * Channels on 2.4GHz overlap, and the most commonly used * are 1, 6, and 11. We'll get a result faster if we check * every 5 channels, but in order to hit all of them the * number of channels must be relatively prime to 5. If it's * not, tweak the hop. */ ctx->hop_step = 5; while ( dev->nr_channels % ctx->hop_step == 0 && ctx->hop_step > 1 ) ctx->hop_step--; ctx->beacons = malloc ( sizeof ( *ctx->beacons ) ); INIT_LIST_HEAD ( ctx->beacons ); dev->channel = 0; dev->op->config ( dev, NET80211_CFG_CHANNEL ); return ctx; } /** * Continue probe of 802.11 networks * * @v ctx Probe context returned by net80211_probe_start() * @ret rc Probe status * * The return code will be 0 if the probe is still going on (and this * function should be called again), a positive number if the probe * completed successfully, or a negative error code if the probe * failed for that reason. * * Whether the probe succeeded or failed, you must call * net80211_probe_finish_all() or net80211_probe_finish_best() * (depending on whether you want information on all networks or just * the best-signal one) in order to release the probe context. A * failed probe may still have acquired some valid data. */ int net80211_probe_step ( struct net80211_probe_ctx *ctx ) { struct net80211_device *dev = ctx->dev; u32 start_timeout = NET80211_PROBE_TIMEOUT * ticks_per_sec(); u32 gather_timeout = ticks_per_sec(); u32 now = currticks(); struct io_buffer *iob; int signal; int rc; char ssid[IEEE80211_MAX_SSID_LEN + 1]; gather_timeout *= ( ctx->essid[0] ? NET80211_PROBE_GATHER : NET80211_PROBE_GATHER_ALL ); /* Time out if necessary */ if ( now >= ctx->ticks_start + start_timeout ) return list_empty ( ctx->beacons ) ? -ETIMEDOUT : +1; if ( ctx->ticks_beacon > 0 && now >= ctx->ticks_start + gather_timeout ) return +1; /* Change channels if necessary */ if ( now >= ctx->ticks_channel + ctx->hop_time ) { dev->channel = ( dev->channel + ctx->hop_step ) % dev->nr_channels; dev->op->config ( dev, NET80211_CFG_CHANNEL ); udelay ( dev->hw->channel_change_time ); ctx->ticks_channel = now; if ( ctx->probe ) { struct io_buffer *siob = ctx->probe; /* to send */ /* make a copy for future use */ iob = alloc_iob ( siob->tail - siob->head ); iob_reserve ( iob, iob_headroom ( siob ) ); memcpy ( iob_put ( iob, iob_len ( siob ) ), siob->data, iob_len ( siob ) ); ctx->probe = iob; rc = net80211_tx_mgmt ( dev, IEEE80211_STYPE_PROBE_REQ, net80211_ll_broadcast, iob_disown ( siob ) ); if ( rc ) { DBGC ( dev, "802.11 %p send probe failed: " "%s\n", dev, strerror ( rc ) ); return rc; } } } /* Check for new management packets */ while ( ( iob = net80211_mgmt_dequeue ( dev, &signal ) ) != NULL ) { struct ieee80211_frame *hdr; struct ieee80211_beacon *beacon; union ieee80211_ie *ie; struct net80211_wlan *wlan; u16 type; hdr = iob->data; type = hdr->fc & IEEE80211_FC_SUBTYPE; beacon = ( struct ieee80211_beacon * ) hdr->data; if ( type != IEEE80211_STYPE_BEACON && type != IEEE80211_STYPE_PROBE_RESP ) { DBGC2 ( dev, "802.11 %p probe: non-beacon\n", dev ); goto drop; } if ( ( void * ) beacon->info_element >= iob->tail ) { DBGC ( dev, "802.11 %p probe: beacon with no IEs\n", dev ); goto drop; } ie = beacon->info_element; while ( ie && ie->id != IEEE80211_IE_SSID ) ie = ieee80211_next_ie ( ie, iob->tail ); if ( ! ie ) { DBGC ( dev, "802.11 %p probe: beacon with no SSID\n", dev ); goto drop; } memcpy ( ssid, ie->ssid, ie->len ); ssid[ie->len] = 0; if ( ctx->essid[0] && strcmp ( ctx->essid, ssid ) != 0 ) { DBGC2 ( dev, "802.11 %p probe: beacon with wrong SSID " "(%s)\n", dev, ssid ); goto drop; } /* See if we've got an entry for this network */ list_for_each_entry ( wlan, ctx->beacons, list ) { if ( strcmp ( wlan->essid, ssid ) != 0 ) continue; if ( signal < wlan->signal ) { DBGC2 ( dev, "802.11 %p probe: beacon for %s " "(%s) with weaker signal %d\n", dev, ssid, eth_ntoa ( hdr->addr3 ), signal ); goto drop; } goto fill; } /* No entry yet - make one */ wlan = zalloc ( sizeof ( *wlan ) ); strcpy ( wlan->essid, ssid ); list_add_tail ( &wlan->list, ctx->beacons ); /* Whether we're using an old entry or a new one, fill it with new data. */ fill: memcpy ( wlan->bssid, hdr->addr3, ETH_ALEN ); wlan->signal = signal; wlan->channel = dev->channels[dev->channel].channel_nr; /* Copy this I/O buffer into a new wlan->beacon; the * iob we've got probably came from the device driver * and may have the full 2.4k allocation, which we * don't want to keep around wasting memory. */ free_iob ( wlan->beacon ); wlan->beacon = alloc_iob ( iob_len ( iob ) ); memcpy ( iob_put ( wlan->beacon, iob_len ( iob ) ), iob->data, iob_len ( iob ) ); /* XXX actually check capab and RSN ie to figure this out */ wlan->handshaking = NET80211_SECPROT_NONE; wlan->crypto = NET80211_CRYPT_NONE; ctx->ticks_beacon = now; DBGC2 ( dev, "802.11 %p probe: good beacon for %s (%s)\n", dev, wlan->essid, eth_ntoa ( wlan->bssid ) ); drop: free_iob ( iob ); } return 0; } /** * Finish probe of 802.11 networks, returning best-signal network found * * @v ctx Probe context * @ret wlan Best-signal network found, or @c NULL if none were found * * If net80211_probe_start() was called with a particular SSID * parameter as filter, only a network with that SSID (matching * case-sensitively) can be returned from this function. */ struct net80211_wlan * net80211_probe_finish_best ( struct net80211_probe_ctx *ctx ) { struct net80211_wlan *best = NULL, *wlan; if ( ! ctx ) return NULL; list_for_each_entry ( wlan, ctx->beacons, list ) { if ( ! best || best->signal < wlan->signal ) best = wlan; } if ( best ) list_del ( &best->list ); else DBGC ( ctx->dev, "802.11 %p probe: found nothing for '%s'\n", ctx->dev, ctx->essid ); net80211_free_wlanlist ( ctx->beacons ); net80211_keep_mgmt ( ctx->dev, ctx->old_keep_mgmt ); if ( ctx->probe ) free_iob ( ctx->probe ); free ( ctx ); return best; } /** * Finish probe of 802.11 networks, returning all networks found * * @v ctx Probe context * @ret list List of net80211_wlan detailing networks found * * If net80211_probe_start() was called with a particular SSID * parameter as filter, this will always return either an empty or a * one-element list. */ struct list_head *net80211_probe_finish_all ( struct net80211_probe_ctx *ctx ) { struct list_head *beacons = ctx->beacons; if ( ! ctx ) return NULL; net80211_keep_mgmt ( ctx->dev, ctx->old_keep_mgmt ); if ( ctx->probe ) free_iob ( ctx->probe ); free ( ctx ); return beacons; } /** * Free WLAN structure * * @v wlan WLAN structure to free */ void net80211_free_wlan ( struct net80211_wlan *wlan ) { if ( wlan ) { free_iob ( wlan->beacon ); free ( wlan ); } } /** * Free list of WLAN structures * * @v list List of WLAN structures to free */ void net80211_free_wlanlist ( struct list_head *list ) { struct net80211_wlan *wlan, *tmp; if ( ! list ) return; list_for_each_entry_safe ( wlan, tmp, list, list ) { list_del ( &wlan->list ); net80211_free_wlan ( wlan ); } free ( list ); } /** Number of ticks to wait for replies to association management frames */ #define ASSOC_TIMEOUT TICKS_PER_SEC /** Number of times to try sending a particular association management frame */ #define ASSOC_RETRIES 2 /** * Step 802.11 association process * * @v proc Association process */ static void net80211_step_associate ( struct process *proc ) { struct net80211_device *dev = container_of ( proc, struct net80211_device, proc_assoc ); int rc = 0; int status = dev->state & NET80211_STATUS_MASK; /* * We use a sort of state machine implemented using bits in * the dev->state variable. At each call, we take the * logically first step that has not yet succeeded; either it * has not been tried yet, it's being retried, or it failed. * If it failed, we return an error indication; otherwise we * perform the step. If it succeeds, RX handling code will set * the appropriate status bit for us. * * Probe works a bit differently, since we have to step it * on every call instead of waiting for a packet to arrive * that will set the completion bit for us. */ /* If we're waiting for a reply, check for timeout condition */ if ( dev->state & NET80211_WAITING ) { /* Sanity check */ if ( ! dev->associating ) return; if ( currticks() - dev->ctx.assoc->last_packet > ASSOC_TIMEOUT ) { /* Timed out - fail if too many retries, or retry */ dev->ctx.assoc->times_tried++; if ( ++dev->ctx.assoc->times_tried > ASSOC_RETRIES ) { rc = -ETIMEDOUT; goto fail; } } else { /* Didn't time out - let it keep going */ return; } } else { if ( dev->state & NET80211_PROBED ) dev->ctx.assoc->times_tried = 0; } if ( ! ( dev->state & NET80211_PROBED ) ) { /* state: probe */ if ( ! dev->ctx.probe ) { /* start probe */ int active = fetch_intz_setting ( NULL, &net80211_active_setting ); int band = dev->hw->bands; if ( active ) band &= ~NET80211_BAND_BIT_5GHZ; rc = net80211_prepare_probe ( dev, band, active ); if ( rc ) goto fail; dev->ctx.probe = net80211_probe_start ( dev, dev->essid, active ); if ( ! dev->ctx.probe ) { dev->assoc_rc = -ENOMEM; goto fail; } } rc = net80211_probe_step ( dev->ctx.probe ); if ( ! rc ) { return; /* still going */ } dev->associating = net80211_probe_finish_best ( dev->ctx.probe ); dev->ctx.probe = NULL; if ( ! dev->associating ) { if ( rc > 0 ) /* "successful" probe found nothing */ rc = -ETIMEDOUT; goto fail; } /* If we probed using a broadcast SSID, record that fact for the settings applicator before we clobber it with the specific SSID we've chosen. */ if ( ! dev->essid[0] ) dev->state |= NET80211_AUTO_SSID; DBGC ( dev, "802.11 %p found network %s (%s)\n", dev, dev->associating->essid, eth_ntoa ( dev->associating->bssid ) ); dev->ctx.assoc = zalloc ( sizeof ( *dev->ctx.assoc ) ); if ( ! dev->ctx.assoc ) { rc = -ENOMEM; goto fail; } dev->state |= NET80211_PROBED; dev->ctx.assoc->method = IEEE80211_AUTH_OPEN_SYSTEM; return; } /* Record time of sending the packet we're about to send, for timeout */ dev->ctx.assoc->last_packet = currticks(); if ( ! ( dev->state & NET80211_AUTHENTICATED ) ) { /* state: prepare and authenticate */ if ( status != IEEE80211_STATUS_SUCCESS ) { /* we tried authenticating already, but failed */ int method = dev->ctx.assoc->method; if ( method == IEEE80211_AUTH_OPEN_SYSTEM && ( status == IEEE80211_STATUS_AUTH_CHALL_INVALID || status == IEEE80211_STATUS_AUTH_ALGO_UNSUPP ) ) { /* Maybe this network uses Shared Key? */ dev->ctx.assoc->method = IEEE80211_AUTH_SHARED_KEY; } else { goto fail; } } DBGC ( dev, "802.11 %p authenticating with method %d\n", dev, dev->ctx.assoc->method ); rc = net80211_prepare_assoc ( dev, dev->associating ); if ( rc ) goto fail; rc = net80211_send_auth ( dev, dev->associating, dev->ctx.assoc->method ); if ( rc ) goto fail; return; } if ( ! ( dev->state & NET80211_ASSOCIATED ) ) { /* state: associate */ if ( status != IEEE80211_STATUS_SUCCESS ) goto fail; DBGC ( dev, "802.11 %p associating\n", dev ); rc = net80211_send_assoc ( dev, dev->associating ); if ( rc ) goto fail; return; } if ( ! ( dev->state & NET80211_CRYPTO_SYNCED ) ) { /* state: crypto sync */ DBGC ( dev, "802.11 %p security handshaking\n", dev ); dev->state |= NET80211_CRYPTO_SYNCED; /* XXX need to actually do something here once we support WPA */ return; } /* state: done! */ netdev_link_up ( dev->netdev ); dev->assoc_rc = 0; dev->state &= ~NET80211_WORKING; free ( dev->ctx.assoc ); dev->ctx.assoc = NULL; net80211_free_wlan ( dev->associating ); dev->associating = NULL; dev->rctl = rc80211_init ( dev ); process_del ( proc ); DBGC ( dev, "802.11 %p associated with %s (%s)\n", dev, dev->essid, eth_ntoa ( dev->bssid ) ); return; fail: dev->state &= ~( NET80211_WORKING | NET80211_WAITING ); if ( rc ) dev->assoc_rc = rc; netdev_link_err ( dev->netdev, dev->assoc_rc ); /* We never reach here from the middle of a probe, so we don't need to worry about freeing dev->ctx.probe. */ if ( dev->state & NET80211_PROBED ) { free ( dev->ctx.assoc ); dev->ctx.assoc = NULL; } net80211_free_wlan ( dev->associating ); dev->associating = NULL; process_del ( proc ); DBGC ( dev, "802.11 %p association failed (state=%04x): " "%s\n", dev, dev->state, strerror ( dev->assoc_rc ) ); /* Try it again: */ net80211_autoassociate ( dev ); } /** * Check for 802.11 SSID updates * * This acts as a settings applicator; if the user changes netX/ssid, * and netX is currently open, the association task will be invoked * again. */ static int net80211_check_ssid_update ( void ) { struct net80211_device *dev; char ssid[IEEE80211_MAX_SSID_LEN + 1]; list_for_each_entry ( dev, &net80211_devices, list ) { if ( ! ( dev->netdev->state & NETDEV_OPEN ) ) continue; fetch_string_setting ( netdev_settings ( dev->netdev ), &net80211_ssid_setting, ssid, IEEE80211_MAX_SSID_LEN + 1 ); if ( strcmp ( ssid, dev->essid ) != 0 && ! ( ! ssid[0] && ( dev->state & NET80211_AUTO_SSID ) ) ) { DBGC ( dev, "802.11 %p updating association: " "%s -> %s\n", dev, dev->essid, ssid ); net80211_autoassociate ( dev ); } } return 0; } /** * Start 802.11 association process * * @v dev 802.11 device * * If the association process is running, it will be restarted. */ void net80211_autoassociate ( struct net80211_device *dev ) { if ( ! ( dev->state & NET80211_WORKING ) ) { DBGC2 ( dev, "802.11 %p spawning association process\n", dev ); process_add ( &dev->proc_assoc ); } /* Clean up everything an earlier association process might have been in the middle of using */ if ( dev->associating ) net80211_free_wlan ( dev->associating ); if ( ! ( dev->state & NET80211_PROBED ) ) net80211_free_wlan ( net80211_probe_finish_best ( dev->ctx.probe ) ); else free ( dev->ctx.assoc ); /* Reset to a clean state */ fetch_string_setting ( netdev_settings ( dev->netdev ), &net80211_ssid_setting, dev->essid, IEEE80211_MAX_SSID_LEN + 1 ); dev->ctx.probe = NULL; dev->associating = NULL; net80211_set_state ( dev, NET80211_PROBED, NET80211_WORKING, 0 ); } /** * Pick TX rate for RTS/CTS packets based on data rate * * @v dev 802.11 device * * The RTS/CTS rate is the fastest TX rate marked as "basic" that is * not faster than the data rate. */ static void net80211_set_rtscts_rate ( struct net80211_device *dev ) { u16 datarate = dev->rates[dev->rate]; u16 rtsrate = 0; int rts_idx = -1; int i; for ( i = 0; i < dev->nr_rates; i++ ) { u16 rate = dev->rates[i]; if ( ! ( dev->basic_rates & ( 1 << i ) ) || rate > datarate ) continue; if ( rate > rtsrate ) { rtsrate = rate; rts_idx = i; } } /* If this is in initialization, we might not have any basic rates; just use the first data rate in that case. */ if ( rts_idx < 0 ) rts_idx = 0; dev->rtscts_rate = rts_idx; } /** * Set data transmission rate for 802.11 device * * @v dev 802.11 device * @v rate Rate to set, as index into @c dev->rates array */ void net80211_set_rate_idx ( struct net80211_device *dev, int rate ) { assert ( dev->netdev->state & NETDEV_OPEN ); if ( rate >= 0 && rate < dev->nr_rates && rate != dev->rate ) { DBGC2 ( dev, "802.11 %p changing rate from %d->%d Mbps\n", dev, dev->rates[dev->rate] / 10, dev->rates[rate] / 10 ); dev->rate = rate; net80211_set_rtscts_rate ( dev ); dev->op->config ( dev, NET80211_CFG_RATE ); } } /** * Configure 802.11 device to transmit on a certain channel * * @v dev 802.11 device * @v channel Channel number (1-11 for 2.4GHz) to transmit on */ int net80211_change_channel ( struct net80211_device *dev, int channel ) { int i, oldchan = dev->channel; assert ( dev->netdev->state & NETDEV_OPEN ); for ( i = 0; i < dev->nr_channels; i++ ) { if ( dev->channels[i].channel_nr == channel ) { dev->channel = i; break; } } if ( i == dev->nr_channels ) return -ENOENT; if ( i != oldchan ) return dev->op->config ( dev, NET80211_CFG_CHANNEL ); return 0; } /** * Prepare 802.11 device channel and rate set for scanning * * @v dev 802.11 device * @v band RF band(s) on which to prepare for scanning * @v active Whether the scanning will be active * @ret rc Return status code */ int net80211_prepare_probe ( struct net80211_device *dev, int band, int active ) { assert ( dev->netdev->state & NETDEV_OPEN ); if ( active && ( band & NET80211_BAND_BIT_5GHZ ) ) { DBGC ( dev, "802.11 %p cannot perform active scanning on " "5GHz band\n", dev ); return -EINVAL_ACTIVE_SCAN; } if ( band == 0 ) { /* This can happen for a 5GHz-only card with 5GHz scanning masked out by an active request. */ DBGC ( dev, "802.11 %p asked to prepare for scanning nothing\n", dev ); return -EINVAL_ACTIVE_SCAN; } dev->nr_channels = 0; if ( active ) net80211_add_channels ( dev, 1, 11, NET80211_REG_TXPOWER ); else { if ( band & NET80211_BAND_BIT_2GHZ ) net80211_add_channels ( dev, 1, 14, NET80211_REG_TXPOWER ); if ( band & NET80211_BAND_BIT_5GHZ ) net80211_add_channels ( dev, 36, 8, NET80211_REG_TXPOWER ); } net80211_filter_hw_channels ( dev ); /* Use channel 1 for now */ dev->channel = 0; dev->op->config ( dev, NET80211_CFG_CHANNEL ); /* Always do active probes at lowest (presumably first) speed */ dev->rate = 0; dev->nr_rates = 1; dev->rates[0] = dev->hw->rates[dev->channels[0].band][0]; dev->op->config ( dev, NET80211_CFG_RATE ); return 0; } /** * Prepare 802.11 device channel and rate set for communication * * @v dev 802.11 device * @v wlan WLAN to prepare for communication with * @ret rc Return status code */ int net80211_prepare_assoc ( struct net80211_device *dev, struct net80211_wlan *wlan ) { struct ieee80211_frame *hdr = wlan->beacon->data; struct ieee80211_beacon *beacon = ( struct ieee80211_beacon * ) hdr->data; int rc; assert ( dev->netdev->state & NETDEV_OPEN ); net80211_set_state ( dev, NET80211_ASSOCIATED, 0, 0 ); memcpy ( dev->bssid, wlan->bssid, ETH_ALEN ); strcpy ( dev->essid, wlan->essid ); dev->last_beacon_timestamp = beacon->timestamp; dev->tx_beacon_interval = 1024 * beacon->beacon_interval; /* XXX do crypto setup here */ /* Barring an IE that tells us the channel outright, assume the channel we heard this AP best on is the channel it's communicating on. */ net80211_change_channel ( dev, wlan->channel ); rc = net80211_process_capab ( dev, beacon->capability ); if ( rc ) return rc; rc = net80211_process_ie ( dev, beacon->info_element, wlan->beacon->tail ); if ( rc ) return rc; /* Associate at the lowest rate so we know it'll get through */ dev->rate = 0; dev->op->config ( dev, NET80211_CFG_RATE ); return 0; } /** * Send 802.11 initial authentication frame * * @v dev 802.11 device * @v wlan WLAN to authenticate with * @v method Authentication method * @ret rc Return status code * * @a method may be 0 for Open System authentication or 1 for Shared * Key authentication. Open System provides no security in association * whatsoever, relying on encryption for confidentiality, but Shared * Key actively introduces security problems and is very rarely used. */ int net80211_send_auth ( struct net80211_device *dev, struct net80211_wlan *wlan, int method ) { struct io_buffer *iob = alloc_iob ( 64 ); struct ieee80211_auth *auth; net80211_set_state ( dev, 0, NET80211_WAITING, 0 ); iob_reserve ( iob, IEEE80211_TYP_FRAME_HEADER_LEN ); auth = iob_put ( iob, sizeof ( *auth ) ); auth->algorithm = method; auth->tx_seq = 1; auth->status = 0; return net80211_tx_mgmt ( dev, IEEE80211_STYPE_AUTH, wlan->bssid, iob ); } /** * Handle receipt of 802.11 authentication frame * * @v dev 802.11 device * @v iob I/O buffer * * If the authentication method being used is Shared Key, and the * frame that was received included challenge text, the frame is * encrypted using the cryptographic algorithm currently in effect and * sent back to the AP to complete the authentication. */ static void net80211_handle_auth ( struct net80211_device *dev, struct io_buffer *iob ) { struct ieee80211_frame *hdr = iob->data; struct ieee80211_auth *auth = ( struct ieee80211_auth * ) hdr->data; if ( auth->tx_seq & 1 ) { DBGC ( dev, "802.11 %p authentication received improperly " "directed frame (seq. %d)\n", dev, auth->tx_seq ); net80211_set_state ( dev, NET80211_WAITING, 0, IEEE80211_STATUS_FAILURE ); return; } if ( auth->status != IEEE80211_STATUS_SUCCESS ) { DBGC ( dev, "802.11 %p authentication failed: status %d\n", dev, auth->status ); net80211_set_state ( dev, NET80211_WAITING, 0, auth->status ); return; } if ( auth->algorithm == IEEE80211_AUTH_SHARED_KEY && ! dev->crypto ) { DBGC ( dev, "802.11 %p can't perform shared-key authentication " "without a cryptosystem\n", dev ); net80211_set_state ( dev, NET80211_WAITING, 0, IEEE80211_STATUS_FAILURE ); return; } if ( auth->algorithm == IEEE80211_AUTH_SHARED_KEY && auth->tx_seq == 2 ) { /* Since the iob we got is going to be freed as soon as we return, we can do some in-place modification. */ auth->tx_seq = 3; auth->status = 0; memcpy ( hdr->addr2, hdr->addr1, ETH_ALEN ); memcpy ( hdr->addr1, hdr->addr3, ETH_ALEN ); netdev_tx ( dev->netdev, dev->crypto->encrypt ( dev->crypto, iob ) ); return; } net80211_set_state ( dev, NET80211_WAITING, NET80211_AUTHENTICATED, IEEE80211_STATUS_SUCCESS ); return; } /** * Send 802.11 association frame * * @v dev 802.11 device * @v wlan WLAN to associate with * @ret rc Return status code */ int net80211_send_assoc ( struct net80211_device *dev, struct net80211_wlan *wlan ) { struct io_buffer *iob = alloc_iob ( 128 ); struct ieee80211_assoc_req *assoc; union ieee80211_ie *ie; net80211_set_state ( dev, 0, NET80211_WAITING, 0 ); iob_reserve ( iob, IEEE80211_TYP_FRAME_HEADER_LEN ); assoc = iob->data; assoc->capability = IEEE80211_CAPAB_MANAGED; if ( ! ( dev->hw->flags & NET80211_HW_NO_SHORT_PREAMBLE ) ) assoc->capability |= IEEE80211_CAPAB_SHORT_PMBL; if ( ! ( dev->hw->flags & NET80211_HW_NO_SHORT_SLOT ) ) assoc->capability |= IEEE80211_CAPAB_SHORT_SLOT; if ( wlan->crypto ) assoc->capability |= IEEE80211_CAPAB_PRIVACY; assoc->listen_interval = 1; ie = net80211_marshal_request_info ( dev, assoc->info_element ); DBGP ( "802.11 %p about to send association request:\n", dev ); DBGP_HD ( iob->data, ( void * ) ie - iob->data ); /* XXX add RSN ie for WPA support */ iob_put ( iob, ( void * ) ie - iob->data ); return net80211_tx_mgmt ( dev, IEEE80211_STYPE_ASSOC_REQ, wlan->bssid, iob ); } /** * Handle receipt of 802.11 association reply frame * * @v dev 802.11 device * @v iob I/O buffer */ static void net80211_handle_assoc_reply ( struct net80211_device *dev, struct io_buffer *iob ) { struct ieee80211_frame *hdr = iob->data; struct ieee80211_assoc_resp *assoc = ( struct ieee80211_assoc_resp * ) hdr->data; net80211_process_capab ( dev, assoc->capability ); net80211_process_ie ( dev, assoc->info_element, iob->tail ); if ( assoc->status != IEEE80211_STATUS_SUCCESS ) { DBGC ( dev, "802.11 %p association failed: status %d\n", dev, assoc->status ); net80211_set_state ( dev, NET80211_WAITING, 0, assoc->status ); return; } /* ESSID was filled before the association request was sent */ memcpy ( dev->bssid, hdr->addr3, ETH_ALEN ); dev->aid = assoc->aid; net80211_set_state ( dev, NET80211_WAITING, NET80211_ASSOCIATED, IEEE80211_STATUS_SUCCESS ); } /** * Send 802.11 disassociation frame * * @v dev 802.11 device * @v reason Reason for disassociation * @ret rc Return status code */ static int net80211_send_disassoc ( struct net80211_device *dev, int reason ) { struct io_buffer *iob = alloc_iob ( 64 ); struct ieee80211_disassoc *disassoc; if ( ! ( dev->state & NET80211_ASSOCIATED ) ) return -EINVAL; net80211_set_state ( dev, NET80211_ASSOCIATED, 0, 0 ); iob_reserve ( iob, IEEE80211_TYP_FRAME_HEADER_LEN ); disassoc = iob_put ( iob, sizeof ( *disassoc ) ); disassoc->reason = reason; return net80211_tx_mgmt ( dev, IEEE80211_STYPE_DISASSOC, dev->bssid, iob ); } /** Smoothing factor (1-7) for link quality calculation */ #define LQ_SMOOTH 7 /** * Update link quality information based on received beacon * * @v dev 802.11 device * @v iob I/O buffer containing beacon * @ret rc Return status code */ static void net80211_update_link_quality ( struct net80211_device *dev, struct io_buffer *iob ) { struct ieee80211_frame *hdr = iob->data; struct ieee80211_beacon *beacon; u32 dt, rxi; if ( ! ( dev->state & NET80211_ASSOCIATED ) ) return; beacon = ( struct ieee80211_beacon * ) hdr->data; dt = ( u32 ) ( beacon->timestamp - dev->last_beacon_timestamp ); rxi = dev->rx_beacon_interval; rxi = ( LQ_SMOOTH * rxi ) + ( ( 8 - LQ_SMOOTH ) * dt ); dev->rx_beacon_interval = rxi >> 3; dev->last_beacon_timestamp = beacon->timestamp; } /** * Handle receipt of 802.11 management frame * * @v dev 802.11 device * @v iob I/O buffer * @v signal Signal strength of received frame */ static void net80211_handle_mgmt ( struct net80211_device *dev, struct io_buffer *iob, int signal ) { struct ieee80211_frame *hdr = iob->data; struct ieee80211_disassoc *disassoc; u16 stype = hdr->fc & IEEE80211_FC_SUBTYPE; int keep = 0; int is_deauth = ( stype == IEEE80211_STYPE_DEAUTH ); if ( ( hdr->fc & IEEE80211_FC_TYPE ) != IEEE80211_TYPE_MGMT ) { free_iob ( iob ); return; /* only handle management frames */ } switch ( stype ) { /* We reconnect on deauthentication and disassociation. */ case IEEE80211_STYPE_DEAUTH: case IEEE80211_STYPE_DISASSOC: disassoc = ( struct ieee80211_disassoc * ) hdr->data; net80211_set_state ( dev, is_deauth ? NET80211_AUTHENTICATED : NET80211_ASSOCIATED, 0, NET80211_IS_REASON | disassoc->reason ); DBGC ( dev, "802.11 %p %s: reason %d\n", dev, is_deauth ? "deauthenticated" : "disassociated", disassoc->reason ); /* Try to reassociate, in case it's transient. */ net80211_autoassociate ( dev ); break; /* We handle authentication and association. */ case IEEE80211_STYPE_AUTH: if ( ! ( dev->state & NET80211_AUTHENTICATED ) ) net80211_handle_auth ( dev, iob ); break; case IEEE80211_STYPE_ASSOC_RESP: case IEEE80211_STYPE_REASSOC_RESP: if ( ! ( dev->state & NET80211_ASSOCIATED ) ) net80211_handle_assoc_reply ( dev, iob ); break; /* We pass probes and beacons onto network scanning code. Pass actions for future extensibility. */ case IEEE80211_STYPE_BEACON: net80211_update_link_quality ( dev, iob ); /* fall through */ case IEEE80211_STYPE_PROBE_RESP: case IEEE80211_STYPE_ACTION: if ( dev->keep_mgmt ) { struct net80211_rx_info *rxinf; rxinf = zalloc ( sizeof ( *rxinf ) ); if ( ! rxinf ) { DBGC ( dev, "802.11 %p out of memory\n", dev ); break; } rxinf->signal = signal; list_add_tail ( &iob->list, &dev->mgmt_queue ); list_add_tail ( &rxinf->list, &dev->mgmt_info_queue ); keep = 1; } break; case IEEE80211_STYPE_PROBE_REQ: /* Some nodes send these broadcast. Ignore them. */ break; case IEEE80211_STYPE_ASSOC_REQ: case IEEE80211_STYPE_REASSOC_REQ: /* We should never receive these, only send them. */ DBGC ( dev, "802.11 %p received strange management request " "(%04x)\n", dev, stype ); break; default: DBGC ( dev, "802.11 %p received unimplemented management " "packet (%04x)\n", dev, stype ); break; } if ( ! keep ) free_iob ( iob ); } /* ---------- Packet handling functions ---------- */ /** * Free buffers used by 802.11 fragment cache entry * * @v dev 802.11 device * @v fcid Fragment cache entry index * * After this function, the referenced entry will be marked unused. */ static void net80211_free_frags ( struct net80211_device *dev, int fcid ) { int j; struct net80211_frag_cache *frag = &dev->frags[fcid]; for ( j = 0; j < 16; j++ ) { if ( frag->iob[j] ) { free_iob ( frag->iob[j] ); frag->iob[j] = NULL; } } frag->seqnr = 0; frag->start_ticks = 0; frag->in_use = 0; } /** * Accumulate 802.11 fragments into one I/O buffer * * @v dev 802.11 device * @v fcid Fragment cache entry index * @v nfrags Number of fragments received * @v size Sum of sizes of all fragments, including headers * @ret iob I/O buffer containing reassembled packet * * This function does not free the fragment buffers. */ static struct io_buffer *net80211_accum_frags ( struct net80211_device *dev, int fcid, int nfrags, int size ) { struct net80211_frag_cache *frag = &dev->frags[fcid]; int hdrsize = IEEE80211_TYP_FRAME_HEADER_LEN; int nsize = size - hdrsize * ( nfrags - 1 ); int i; struct io_buffer *niob = alloc_iob ( nsize ); struct ieee80211_frame *hdr; /* Add the header from the first one... */ memcpy ( iob_put ( niob, hdrsize ), frag->iob[0]->data, hdrsize ); /* ... and all the data from all of them. */ for ( i = 0; i < nfrags; i++ ) { int len = iob_len ( frag->iob[i] ) - hdrsize; memcpy ( iob_put ( niob, len ), frag->iob[i]->data + hdrsize, len ); } /* Turn off the fragment bit. */ hdr = niob->data; hdr->fc &= ~IEEE80211_FC_MORE_FRAG; return niob; } /** * Handle receipt of 802.11 fragment * * @v dev 802.11 device * @v iob I/O buffer containing fragment * @v signal Signal strength with which fragment was received */ static void net80211_rx_frag ( struct net80211_device *dev, struct io_buffer *iob, int signal ) { struct ieee80211_frame *hdr = iob->data; int fragnr = IEEE80211_FRAG ( hdr->seq ); if ( fragnr == 0 && ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) { /* start a frag cache entry */ int i, newest = -1; u32 curr_ticks = currticks(), newest_ticks = 0; u32 timeout = ticks_per_sec() * NET80211_FRAG_TIMEOUT; for ( i = 0; i < NET80211_NR_CONCURRENT_FRAGS; i++ ) { if ( dev->frags[i].in_use == 0 ) break; if ( dev->frags[i].start_ticks + timeout >= curr_ticks ) { net80211_free_frags ( dev, i ); break; } if ( dev->frags[i].start_ticks > newest_ticks ) { newest = i; newest_ticks = dev->frags[i].start_ticks; } } /* If we're being sent more concurrent fragmented packets than we can handle, drop the newest so the older ones have time to complete. */ if ( i == NET80211_NR_CONCURRENT_FRAGS ) { i = newest; net80211_free_frags ( dev, i ); } dev->frags[i].in_use = 1; dev->frags[i].seqnr = IEEE80211_SEQNR ( hdr->seq ); dev->frags[i].start_ticks = currticks(); dev->frags[i].iob[0] = iob; return; } else { int i; for ( i = 0; i < NET80211_NR_CONCURRENT_FRAGS; i++ ) { if ( dev->frags[i].in_use && dev->frags[i].seqnr == IEEE80211_SEQNR ( hdr->seq ) ) break; } if ( i == NET80211_NR_CONCURRENT_FRAGS ) { /* Drop non-first not-in-cache fragments */ DBGC ( dev, "802.11 %p dropped fragment fc=%04x " "seq=%04x\n", dev, hdr->fc, hdr->seq ); free_iob ( iob ); return; } dev->frags[i].iob[fragnr] = iob; if ( ! ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) { int j, size = 0; for ( j = 0; j < fragnr; j++ ) { size += iob_len ( dev->frags[i].iob[j] ); if ( dev->frags[i].iob[j] == NULL ) break; } if ( j == fragnr ) { /* We've got everything */ struct io_buffer *niob = net80211_accum_frags ( dev, i, fragnr, size ); net80211_free_frags ( dev, i ); net80211_rx ( dev, niob, signal, 0 ); } else { DBGC ( dev, "802.11 %p dropping fragmented " "packet due to out-of-order arrival, " "fc=%04x seq=%04x\n", dev, hdr->fc, hdr->seq ); net80211_free_frags ( dev, i ); } } } } /** * Handle receipt of 802.11 frame * * @v dev 802.11 device * @v iob I/O buffer * @v signal Received signal strength * @v rate Bitrate at which frame was received, in 100 kbps units * * If the rate or signal is unknown, 0 should be passed. */ void net80211_rx ( struct net80211_device *dev, struct io_buffer *iob, int signal, u16 rate ) { struct ieee80211_frame *hdr = iob->data; u16 type = hdr->fc & IEEE80211_FC_TYPE; if ( ( hdr->fc & IEEE80211_FC_VERSION ) != IEEE80211_THIS_VERSION ) goto drop; /* drop invalid-version packets */ if ( type == IEEE80211_TYPE_CTRL ) goto drop; /* we don't handle control packets, the hardware does */ if ( dev->last_rx_seq == hdr->seq ) goto drop; /* avoid duplicate packet */ dev->last_rx_seq = hdr->seq; if ( dev->hw->flags & NET80211_HW_RX_HAS_FCS ) { /* discard the FCS */ iob_unput ( iob, 4 ); } if ( hdr->fc & IEEE80211_FC_PROTECTED ) { struct io_buffer *niob; if ( ! dev->crypto ) goto drop; /* can't decrypt packets on an open network */ niob = dev->crypto->decrypt ( dev->crypto, iob ); if ( ! niob ) goto drop; /* drop failed decryption */ free_iob ( iob ); iob = niob; } dev->last_signal = signal; /* Fragments go into the frag cache or get dropped. */ if ( IEEE80211_FRAG ( hdr->seq ) != 0 || ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) { net80211_rx_frag ( dev, iob, signal ); return; } /* Management frames get handled, enqueued, or dropped. */ if ( type == IEEE80211_TYPE_MGMT ) { net80211_handle_mgmt ( dev, iob, signal ); return; } /* Data frames get dropped or sent to the net_device. */ if ( ( hdr->fc & IEEE80211_FC_SUBTYPE ) != IEEE80211_STYPE_DATA ) goto drop; /* drop QoS, CFP, or null data packets */ /* Update rate-control algorithm */ if ( dev->rctl ) rc80211_update_rx ( dev, hdr->fc & IEEE80211_FC_RETRY, rate ); /* Pass packet onward */ if ( netdev_link_ok ( dev->netdev ) ) { netdev_rx ( dev->netdev, iob ); return; } drop: DBGC2 ( dev, "802.11 %p dropped packet fc=%04x seq=%04x\n", dev, hdr->fc, hdr->seq ); free_iob ( iob ); return; } /** Indicate an error in receiving a packet * * @v dev 802.11 device * @v iob I/O buffer with received packet, or NULL * @v rc Error code * * This logs the error with the wrapping net_device, and frees iob if * it is passed. */ void net80211_rx_err ( struct net80211_device *dev, struct io_buffer *iob, int rc ) { netdev_rx_err ( dev->netdev, iob, rc ); } /** Indicate the completed transmission of a packet * * @v dev 802.11 device * @v iob I/O buffer of transmitted packet * @v retries Number of times this packet was retransmitted * @v rc Error code, or 0 for success * * This logs an error with the wrapping net_device if one occurred, * and removes and frees the I/O buffer from its TX queue. The * provided retry information is used to tune our transmission rate. * * If the packet did not need to be retransmitted because it was * properly ACKed the first time, @a retries should be 0. */ void net80211_tx_complete ( struct net80211_device *dev, struct io_buffer *iob, int retries, int rc ) { /* Update rate-control algorithm */ if ( dev->rctl ) rc80211_update_tx ( dev, retries, rc ); /* Pass completion onward */ netdev_tx_complete_err ( dev->netdev, iob, rc ); } debian/grub-extras/disabled/gpxe/src/net/80211/rc80211.c0000664000000000000000000002610612524662415017355 0ustar /* * Simple 802.11 rate-control algorithm for gPXE. * * Copyright (c) 2009 Joshua Oreman . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include /** * @file * * Simple 802.11 rate-control algorithm */ /** @page rc80211 Rate control philosophy * * We want to maximize our transmission speed, to the extent that we * can do that without dropping undue numbers of packets. We also * don't want to take up very much code space, so our algorithm has to * be pretty simple * * When we receive a packet, we know what rate it was transmitted at, * and whether it had to be retransmitted to get to us. * * When we send a packet, we hear back how many times it had to be * retried to get through, and whether it got through at all. * * Indications of TX success are more reliable than RX success, but RX * information helps us know where to start. * * To handle all of this, we keep for each rate and each direction (TX * and RX separately) some state information for the most recent * packets on that rate and the number of packets for which we have * information. The state is a 32-bit unsigned integer in which two * bits represent a packet: 11 if it went through well, 10 if it went * through with one retry, 01 if it went through with more than one * retry, or 00 if it didn't go through at all. We define the * "goodness" for a particular (rate, direction) combination as the * sum of all the 2-bit fields, times 33, divided by the number of * 2-bit fields containing valid information (16 except when we're * starting out). The number produced is between 0 and 99; we use -1 * for rates with less than 4 RX packets or 1 TX, as an indicator that * we do not have enough information to rely on them. * * In deciding which rates are best, we find the weighted average of * TX and RX goodness, where the weighting is by number of packets * with data and TX packets are worth 4 times as much as RX packets. * The weighted average is called "net goodness" and is also a number * between 0 and 99. If 3 consecutive packets fail transmission * outright, we automatically ratchet down the rate; otherwise, we * switch to the best rate whenever the current rate's goodness falls * below some threshold, and try increasing our rate when the goodness * is very high. * * This system is optimized for gPXE's style of usage. Because normal * operation always involves receiving something, we'll make our way * to the best rate pretty quickly. We tend to follow the lead of the * sending AP in choosing rates, but we won't use rates for long that * don't work well for us in transmission. We assume gPXE won't be * running for long enough that rate patterns will change much, so we * don't have to keep time counters or the like. And if this doesn't * work well in practice there are many ways it could be tweaked. * * To avoid staying at 1Mbps for a long time, we don't track any * transmitted packets until we've set our rate based on received * packets. */ /** Two-bit packet status indicator for a packet with no retries */ #define RC_PKT_OK 0x3 /** Two-bit packet status indicator for a packet with one retry */ #define RC_PKT_RETRIED_ONCE 0x2 /** Two-bit packet status indicator for a TX packet with multiple retries * * It is not possible to tell whether an RX packet had one or multiple * retries; we rely instead on the fact that failed RX packets won't * get to us at all, so if we receive a lot of RX packets on a certain * rate it must be pretty good. */ #define RC_PKT_RETRIED_MULTI 0x1 /** Two-bit packet status indicator for a TX packet that was never ACKed * * It is not possible to tell whether an RX packet was setn if it * didn't get through to us, but if we don't see one we won't increase * the goodness for its rate. This asymmetry is part of why TX packets * are weighted much more heavily than RX. */ #define RC_PKT_FAILED 0x0 /** Number of times to weight TX packets more heavily than RX packets */ #define RC_TX_FACTOR 4 /** Number of consecutive failed TX packets that cause an automatic rate drop */ #define RC_TX_EMERG_FAIL 3 /** Minimum net goodness below which we will search for a better rate */ #define RC_GOODNESS_MIN 85 /** Maximum net goodness above which we will try to increase our rate */ #define RC_GOODNESS_MAX 95 /** Minimum (num RX + @c RC_TX_FACTOR * num TX) to use a certain rate */ #define RC_UNCERTAINTY_THRESH 4 /** TX direction */ #define TX 0 /** RX direction */ #define RX 1 /** A rate control context */ struct rc80211_ctx { /** Goodness state for each rate, TX and RX */ u32 goodness[2][NET80211_MAX_RATES]; /** Number of packets recorded for each rate */ u8 count[2][NET80211_MAX_RATES]; /** Indication of whether we've set the device rate yet */ int started; /** Counter of all packets sent and received */ int packets; }; /** * Initialize rate-control algorithm * * @v dev 802.11 device * @ret ctx Rate-control context, to be stored in @c dev->rctl */ struct rc80211_ctx * rc80211_init ( struct net80211_device *dev __unused ) { struct rc80211_ctx *ret = zalloc ( sizeof ( *ret ) ); return ret; } /** * Calculate net goodness for a certain rate * * @v ctx Rate-control context * @v rate_idx Index of rate to calculate net goodness for */ static int rc80211_calc_net_goodness ( struct rc80211_ctx *ctx, int rate_idx ) { int sum[2], num[2], dir, pkt; for ( dir = 0; dir < 2; dir++ ) { u32 good = ctx->goodness[dir][rate_idx]; num[dir] = ctx->count[dir][rate_idx]; sum[dir] = 0; for ( pkt = 0; pkt < num[dir]; pkt++ ) sum[dir] += ( good >> ( 2 * pkt ) ) & 0x3; } if ( ( num[TX] * RC_TX_FACTOR + num[RX] ) < RC_UNCERTAINTY_THRESH ) return -1; return ( 33 * ( sum[TX] * RC_TX_FACTOR + sum[RX] ) / ( num[TX] * RC_TX_FACTOR + num[RX] ) ); } /** * Determine the best rate to switch to and return it * * @v dev 802.11 device * @ret rate_idx Index of the best rate to switch to */ static int rc80211_pick_best ( struct net80211_device *dev ) { struct rc80211_ctx *ctx = dev->rctl; int best_net_good = 0, best_rate = -1, i; for ( i = 0; i < dev->nr_rates; i++ ) { int net_good = rc80211_calc_net_goodness ( ctx, i ); if ( net_good > best_net_good || ( best_net_good > RC_GOODNESS_MIN && net_good > RC_GOODNESS_MIN ) ) { best_net_good = net_good; best_rate = i; } } if ( best_rate >= 0 ) { int old_good = rc80211_calc_net_goodness ( ctx, dev->rate ); if ( old_good != best_net_good ) DBGC ( ctx, "802.11 RC %p switching from goodness " "%d to %d\n", ctx, old_good, best_net_good ); ctx->started = 1; return best_rate; } return dev->rate; } /** * Set 802.11 device rate * * @v dev 802.11 device * @v rate_idx Index of rate to switch to * * This is a thin wrapper around net80211_set_rate_idx to insert a * debugging message where appropriate. */ static inline void rc80211_set_rate ( struct net80211_device *dev, int rate_idx ) { DBGC ( dev->rctl, "802.11 RC %p changing rate %d->%d Mbps\n", dev->rctl, dev->rates[dev->rate] / 10, dev->rates[rate_idx] / 10 ); net80211_set_rate_idx ( dev, rate_idx ); } /** * Check rate-control state and change rate if necessary * * @v dev 802.11 device */ static void rc80211_maybe_set_new ( struct net80211_device *dev ) { struct rc80211_ctx *ctx = dev->rctl; int net_good; net_good = rc80211_calc_net_goodness ( ctx, dev->rate ); if ( ! ctx->started ) { rc80211_set_rate ( dev, rc80211_pick_best ( dev ) ); return; } if ( net_good < 0 ) /* insufficient data */ return; if ( net_good > RC_GOODNESS_MAX && dev->rate + 1 < dev->nr_rates ) { int higher = rc80211_calc_net_goodness ( ctx, dev->rate + 1 ); if ( higher > net_good || higher < 0 ) rc80211_set_rate ( dev, dev->rate + 1 ); else rc80211_set_rate ( dev, rc80211_pick_best ( dev ) ); } if ( net_good < RC_GOODNESS_MIN ) { rc80211_set_rate ( dev, rc80211_pick_best ( dev ) ); } } /** * Update rate-control state * * @v dev 802.11 device * @v direction One of the direction constants TX or RX * @v rate_idx Index of rate at which packet was sent or received * @v retries Number of times packet was retried before success * @v failed If nonzero, the packet failed to get through */ static void rc80211_update ( struct net80211_device *dev, int direction, int rate_idx, int retries, int failed ) { struct rc80211_ctx *ctx = dev->rctl; u32 goodness = ctx->goodness[direction][rate_idx]; if ( ctx->count[direction][rate_idx] < 16 ) ctx->count[direction][rate_idx]++; goodness <<= 2; if ( failed ) goodness |= RC_PKT_FAILED; else if ( retries > 1 ) goodness |= RC_PKT_RETRIED_MULTI; else if ( retries ) goodness |= RC_PKT_RETRIED_ONCE; else goodness |= RC_PKT_OK; ctx->goodness[direction][rate_idx] = goodness; ctx->packets++; rc80211_maybe_set_new ( dev ); } /** * Update rate-control state for transmitted packet * * @v dev 802.11 device * @v retries Number of times packet was transmitted before success * @v rc Return status code for transmission */ void rc80211_update_tx ( struct net80211_device *dev, int retries, int rc ) { struct rc80211_ctx *ctx = dev->rctl; if ( ! ctx->started ) return; rc80211_update ( dev, TX, dev->rate, retries, rc ); /* Check if the last RC_TX_EMERG_FAIL packets have all failed */ if ( ! ( ctx->goodness[TX][dev->rate] & ( ( 1 << ( 2 * RC_TX_EMERG_FAIL ) ) - 1 ) ) ) { if ( dev->rate == 0 ) DBGC ( dev->rctl, "802.11 RC %p saw %d consecutive " "failed TX, but cannot lower rate any further\n", dev->rctl, RC_TX_EMERG_FAIL ); else { DBGC ( dev->rctl, "802.11 RC %p lowering rate (%d->%d " "Mbps) due to %d consecutive TX failures\n", dev->rctl, dev->rates[dev->rate] / 10, dev->rates[dev->rate - 1] / 10, RC_TX_EMERG_FAIL ); rc80211_set_rate ( dev, dev->rate - 1 ); } } } /** * Update rate-control state for received packet * * @v dev 802.11 device * @v retry Whether the received packet had been retransmitted * @v rate Rate at which packet was received, in 100 kbps units */ void rc80211_update_rx ( struct net80211_device *dev, int retry, u16 rate ) { int ridx; for ( ridx = 0; ridx < dev->nr_rates && dev->rates[ridx] != rate; ridx++ ) ; if ( ridx >= dev->nr_rates ) return; /* couldn't find the rate */ rc80211_update ( dev, RX, ridx, retry, 0 ); } /** * Free rate-control context * * @v ctx Rate-control context */ void rc80211_free ( struct rc80211_ctx *ctx ) { free ( ctx ); } debian/grub-extras/disabled/gpxe/src/net/aoe.c0000664000000000000000000002611612524662415016447 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * AoE protocol * */ FEATURE ( FEATURE_PROTOCOL, "AoE", DHCP_EB_FEATURE_AOE, 1 ); struct net_protocol aoe_protocol; /** List of all AoE sessions */ static LIST_HEAD ( aoe_sessions ); static void aoe_free ( struct refcnt *refcnt ) { struct aoe_session *aoe = container_of ( refcnt, struct aoe_session, refcnt ); netdev_put ( aoe->netdev ); free ( aoe ); } /** * Mark current AoE command complete * * @v aoe AoE session * @v rc Return status code */ static void aoe_done ( struct aoe_session *aoe, int rc ) { /* Record overall command status */ if ( aoe->command ) { aoe->command->cb.cmd_stat = aoe->status; aoe->command->rc = rc; aoe->command = NULL; } /* Stop retransmission timer */ stop_timer ( &aoe->timer ); /* Mark operation as complete */ aoe->rc = rc; } /** * Send AoE command * * @v aoe AoE session * @ret rc Return status code * * This transmits an AoE command packet. It does not wait for a * response. */ static int aoe_send_command ( struct aoe_session *aoe ) { struct ata_command *command = aoe->command; struct io_buffer *iobuf; struct aoehdr *aoehdr; union aoecmd *aoecmd; struct aoeata *aoeata; unsigned int count; unsigned int data_out_len; unsigned int aoecmdlen; /* Fail immediately if we have no netdev to send on */ if ( ! aoe->netdev ) { aoe_done ( aoe, -ENETUNREACH ); return -ENETUNREACH; } /* If we are transmitting anything that requires a response, * start the retransmission timer. Do this before attempting * to allocate the I/O buffer, in case allocation itself * fails. */ start_timer ( &aoe->timer ); /* Calculate count and data_out_len for this subcommand */ switch ( aoe->aoe_cmd_type ) { case AOE_CMD_ATA: count = command->cb.count.native; if ( count > AOE_MAX_COUNT ) count = AOE_MAX_COUNT; data_out_len = ( command->data_out ? ( count * ATA_SECTOR_SIZE ) : 0 ); aoecmdlen = sizeof ( aoecmd->ata ); break; case AOE_CMD_CONFIG: count = 0; data_out_len = 0; aoecmdlen = sizeof ( aoecmd->cfg ); break; default: return -ENOTSUP; } /* Create outgoing I/O buffer */ iobuf = alloc_iob ( ETH_HLEN + sizeof ( *aoehdr ) + aoecmdlen + data_out_len ); if ( ! iobuf ) return -ENOMEM; iob_reserve ( iobuf, ETH_HLEN ); aoehdr = iob_put ( iobuf, sizeof ( *aoehdr ) ); aoecmd = iob_put ( iobuf, aoecmdlen ); memset ( aoehdr, 0, ( sizeof ( *aoehdr ) + aoecmdlen ) ); /* Fill AoE header */ aoehdr->ver_flags = AOE_VERSION; aoehdr->major = htons ( aoe->major ); aoehdr->minor = aoe->minor; aoehdr->command = aoe->aoe_cmd_type; aoehdr->tag = htonl ( ++aoe->tag ); /* Fill AoE payload */ switch ( aoe->aoe_cmd_type ) { case AOE_CMD_ATA: /* Fill AoE command */ aoeata = &aoecmd->ata; linker_assert ( AOE_FL_DEV_HEAD == ATA_DEV_SLAVE, __fix_ata_h__ ); aoeata->aflags = ( ( command->cb.lba48 ? AOE_FL_EXTENDED : 0 )| ( command->cb.device & ATA_DEV_SLAVE ) | ( data_out_len ? AOE_FL_WRITE : 0 ) ); aoeata->err_feat = command->cb.err_feat.bytes.cur; aoeata->count = count; aoeata->cmd_stat = command->cb.cmd_stat; aoeata->lba.u64 = cpu_to_le64 ( command->cb.lba.native ); if ( ! command->cb.lba48 ) aoeata->lba.bytes[3] |= ( command->cb.device & ATA_DEV_MASK ); /* Fill data payload */ copy_from_user ( iob_put ( iobuf, data_out_len ), command->data_out, aoe->command_offset, data_out_len ); break; case AOE_CMD_CONFIG: /* Nothing to do */ break; default: assert ( 0 ); } /* Send packet */ return net_tx ( iobuf, aoe->netdev, &aoe_protocol, aoe->target ); } /** * Handle AoE retry timer expiry * * @v timer AoE retry timer * @v fail Failure indicator */ static void aoe_timer_expired ( struct retry_timer *timer, int fail ) { struct aoe_session *aoe = container_of ( timer, struct aoe_session, timer ); if ( fail ) { aoe_done ( aoe, -ETIMEDOUT ); } else { aoe_send_command ( aoe ); } } /** * Handle AoE configuration command response * * @v aoe AoE session * @v ll_source Link-layer source address * @ret rc Return status code */ static int aoe_rx_cfg ( struct aoe_session *aoe, const void *ll_source ) { /* Record target MAC address */ memcpy ( aoe->target, ll_source, sizeof ( aoe->target ) ); DBGC ( aoe, "AoE %p target MAC address %s\n", aoe, eth_ntoa ( aoe->target ) ); /* Mark config request as complete */ aoe_done ( aoe, 0 ); return 0; } /** * Handle AoE ATA command response * * @v aoe AoE session * @v aoeata AoE ATA command * @v len Length of AoE ATA command * @ret rc Return status code */ static int aoe_rx_ata ( struct aoe_session *aoe, struct aoeata *aoeata, size_t len ) { struct ata_command *command = aoe->command; unsigned int rx_data_len; unsigned int count; unsigned int data_len; /* Sanity check */ if ( len < sizeof ( *aoeata ) ) { /* Ignore packet; allow timer to trigger retransmit */ return -EINVAL; } rx_data_len = ( len - sizeof ( *aoeata ) ); /* Calculate count and data_len for this subcommand */ count = command->cb.count.native; if ( count > AOE_MAX_COUNT ) count = AOE_MAX_COUNT; data_len = count * ATA_SECTOR_SIZE; /* Merge into overall ATA status */ aoe->status |= aoeata->cmd_stat; /* Copy data payload */ if ( command->data_in ) { if ( rx_data_len > data_len ) rx_data_len = data_len; copy_to_user ( command->data_in, aoe->command_offset, aoeata->data, rx_data_len ); } /* Update ATA command and offset */ aoe->command_offset += data_len; command->cb.lba.native += count; command->cb.count.native -= count; /* Check for operation complete */ if ( ! command->cb.count.native ) { aoe_done ( aoe, 0 ); return 0; } /* Transmit next portion of request */ stop_timer ( &aoe->timer ); aoe_send_command ( aoe ); return 0; } /** * Process incoming AoE packets * * @v iobuf I/O buffer * @v netdev Network device * @v ll_source Link-layer source address * @ret rc Return status code * */ static int aoe_rx ( struct io_buffer *iobuf, struct net_device *netdev __unused, const void *ll_source ) { struct aoehdr *aoehdr = iobuf->data; struct aoe_session *aoe; int rc = 0; /* Sanity checks */ if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) { rc = -EINVAL; goto done; } if ( ( aoehdr->ver_flags & AOE_VERSION_MASK ) != AOE_VERSION ) { rc = -EPROTONOSUPPORT; goto done; } if ( ! ( aoehdr->ver_flags & AOE_FL_RESPONSE ) ) { /* Ignore AoE requests that we happen to see */ goto done; } iob_pull ( iobuf, sizeof ( *aoehdr ) ); /* Demultiplex amongst active AoE sessions */ list_for_each_entry ( aoe, &aoe_sessions, list ) { if ( ntohs ( aoehdr->major ) != aoe->major ) continue; if ( aoehdr->minor != aoe->minor ) continue; if ( ntohl ( aoehdr->tag ) != aoe->tag ) continue; if ( aoehdr->ver_flags & AOE_FL_ERROR ) { aoe_done ( aoe, -EIO ); break; } switch ( aoehdr->command ) { case AOE_CMD_ATA: rc = aoe_rx_ata ( aoe, iobuf->data, iob_len ( iobuf )); break; case AOE_CMD_CONFIG: rc = aoe_rx_cfg ( aoe, ll_source ); break; default: DBGC ( aoe, "AoE %p ignoring command %02x\n", aoe, aoehdr->command ); break; } break; } done: free_iob ( iobuf ); return rc; } /** AoE protocol */ struct net_protocol aoe_protocol __net_protocol = { .name = "AoE", .net_proto = htons ( ETH_P_AOE ), .rx = aoe_rx, }; /** * Issue ATA command via an open AoE session * * @v ata ATA device * @v command ATA command * @ret rc Return status code */ static int aoe_command ( struct ata_device *ata, struct ata_command *command ) { struct aoe_session *aoe = container_of ( ata->backend, struct aoe_session, refcnt ); aoe->command = command; aoe->status = 0; aoe->command_offset = 0; aoe->aoe_cmd_type = AOE_CMD_ATA; aoe_send_command ( aoe ); return 0; } /** * Issue AoE config query for AoE target discovery * * @v aoe AoE session * @ret rc Return status code */ static int aoe_discover ( struct aoe_session *aoe ) { int rc; aoe->status = 0; aoe->aoe_cmd_type = AOE_CMD_CONFIG; aoe->command = NULL; aoe_send_command ( aoe ); aoe->rc = -EINPROGRESS; while ( aoe->rc == -EINPROGRESS ) step(); rc = aoe->rc; return rc; } static int aoe_detached_command ( struct ata_device *ata __unused, struct ata_command *command __unused ) { return -ENODEV; } void aoe_detach ( struct ata_device *ata ) { struct aoe_session *aoe = container_of ( ata->backend, struct aoe_session, refcnt ); stop_timer ( &aoe->timer ); ata->command = aoe_detached_command; list_del ( &aoe->list ); ref_put ( ata->backend ); ata->backend = NULL; } static int aoe_parse_root_path ( struct aoe_session *aoe, const char *root_path ) { char *ptr; if ( strncmp ( root_path, "aoe:", 4 ) != 0 ) return -EINVAL; ptr = ( ( char * ) root_path + 4 ); if ( *ptr++ != 'e' ) return -EINVAL; aoe->major = strtoul ( ptr, &ptr, 10 ); if ( *ptr++ != '.' ) return -EINVAL; aoe->minor = strtoul ( ptr, &ptr, 10 ); if ( *ptr ) return -EINVAL; return 0; } int aoe_attach ( struct ata_device *ata, struct net_device *netdev, const char *root_path ) { struct aoe_session *aoe; int rc; /* Allocate and initialise structure */ aoe = zalloc ( sizeof ( *aoe ) ); if ( ! aoe ) return -ENOMEM; aoe->refcnt.free = aoe_free; aoe->netdev = netdev_get ( netdev ); memcpy ( aoe->target, netdev->ll_broadcast, sizeof ( aoe->target ) ); aoe->tag = AOE_TAG_MAGIC; aoe->timer.expired = aoe_timer_expired; /* Parse root path */ if ( ( rc = aoe_parse_root_path ( aoe, root_path ) ) != 0 ) goto err; /* Attach parent interface, transfer reference to connection * list, and return */ ata->backend = ref_get ( &aoe->refcnt ); ata->command = aoe_command; list_add ( &aoe->list, &aoe_sessions ); /* Send discovery packet to find the target MAC address. * Ideally, this ought to be done asynchronously, but the * block device interface does not yet support asynchronous * operation. */ if ( ( rc = aoe_discover( aoe ) ) != 0 ) goto err; return 0; err: ref_put ( &aoe->refcnt ); return rc; } debian/grub-extras/disabled/gpxe/src/net/infiniband.c0000664000000000000000000005440012524662415020001 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * Infiniband protocol * */ /** List of Infiniband devices */ struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices ); /** List of open Infiniband devices, in reverse order of opening */ static struct list_head open_ib_devices = LIST_HEAD_INIT ( open_ib_devices ); /*************************************************************************** * * Completion queues * *************************************************************************** */ /** * Create completion queue * * @v ibdev Infiniband device * @v num_cqes Number of completion queue entries * @v op Completion queue operations * @ret cq New completion queue */ struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes, struct ib_completion_queue_operations *op ) { struct ib_completion_queue *cq; int rc; DBGC ( ibdev, "IBDEV %p creating completion queue\n", ibdev ); /* Allocate and initialise data structure */ cq = zalloc ( sizeof ( *cq ) ); if ( ! cq ) goto err_alloc_cq; cq->ibdev = ibdev; list_add ( &cq->list, &ibdev->cqs ); cq->num_cqes = num_cqes; INIT_LIST_HEAD ( &cq->work_queues ); cq->op = op; /* Perform device-specific initialisation and get CQN */ if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not initialise completion " "queue: %s\n", ibdev, strerror ( rc ) ); goto err_dev_create_cq; } DBGC ( ibdev, "IBDEV %p created %d-entry completion queue %p (%p) " "with CQN %#lx\n", ibdev, num_cqes, cq, ib_cq_get_drvdata ( cq ), cq->cqn ); return cq; ibdev->op->destroy_cq ( ibdev, cq ); err_dev_create_cq: list_del ( &cq->list ); free ( cq ); err_alloc_cq: return NULL; } /** * Destroy completion queue * * @v ibdev Infiniband device * @v cq Completion queue */ void ib_destroy_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq ) { DBGC ( ibdev, "IBDEV %p destroying completion queue %#lx\n", ibdev, cq->cqn ); assert ( list_empty ( &cq->work_queues ) ); ibdev->op->destroy_cq ( ibdev, cq ); list_del ( &cq->list ); free ( cq ); } /** * Poll completion queue * * @v ibdev Infiniband device * @v cq Completion queue */ void ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq ) { struct ib_work_queue *wq; /* Poll completion queue */ ibdev->op->poll_cq ( ibdev, cq ); /* Refill receive work queues */ list_for_each_entry ( wq, &cq->work_queues, list ) { if ( ! wq->is_send ) ib_refill_recv ( ibdev, wq->qp ); } } /*************************************************************************** * * Work queues * *************************************************************************** */ /** * Create queue pair * * @v ibdev Infiniband device * @v type Queue pair type * @v num_send_wqes Number of send work queue entries * @v send_cq Send completion queue * @v num_recv_wqes Number of receive work queue entries * @v recv_cq Receive completion queue * @ret qp Queue pair * * The queue pair will be left in the INIT state; you must call * ib_modify_qp() before it is ready to use for sending and receiving. */ struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev, enum ib_queue_pair_type type, unsigned int num_send_wqes, struct ib_completion_queue *send_cq, unsigned int num_recv_wqes, struct ib_completion_queue *recv_cq ) { struct ib_queue_pair *qp; size_t total_size; int rc; DBGC ( ibdev, "IBDEV %p creating queue pair\n", ibdev ); /* Allocate and initialise data structure */ total_size = ( sizeof ( *qp ) + ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ) + ( num_recv_wqes * sizeof ( qp->recv.iobufs[0] ) ) ); qp = zalloc ( total_size ); if ( ! qp ) goto err_alloc_qp; qp->ibdev = ibdev; list_add ( &qp->list, &ibdev->qps ); qp->type = type; qp->send.qp = qp; qp->send.is_send = 1; qp->send.cq = send_cq; list_add ( &qp->send.list, &send_cq->work_queues ); qp->send.psn = ( random() & 0xffffffUL ); qp->send.num_wqes = num_send_wqes; qp->send.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) ); qp->recv.qp = qp; qp->recv.cq = recv_cq; list_add ( &qp->recv.list, &recv_cq->work_queues ); qp->recv.psn = ( random() & 0xffffffUL ); qp->recv.num_wqes = num_recv_wqes; qp->recv.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) + ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) )); INIT_LIST_HEAD ( &qp->mgids ); /* Perform device-specific initialisation and get QPN */ if ( ( rc = ibdev->op->create_qp ( ibdev, qp ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not initialise queue pair: " "%s\n", ibdev, strerror ( rc ) ); goto err_dev_create_qp; } DBGC ( ibdev, "IBDEV %p created queue pair %p (%p) with QPN %#lx\n", ibdev, qp, ib_qp_get_drvdata ( qp ), qp->qpn ); DBGC ( ibdev, "IBDEV %p QPN %#lx has %d send entries at [%p,%p)\n", ibdev, qp->qpn, num_send_wqes, qp->send.iobufs, qp->recv.iobufs ); DBGC ( ibdev, "IBDEV %p QPN %#lx has %d receive entries at [%p,%p)\n", ibdev, qp->qpn, num_recv_wqes, qp->recv.iobufs, ( ( ( void * ) qp ) + total_size ) ); /* Calculate externally-visible QPN */ switch ( type ) { case IB_QPT_SMI: qp->ext_qpn = IB_QPN_SMI; break; case IB_QPT_GSI: qp->ext_qpn = IB_QPN_GSI; break; default: qp->ext_qpn = qp->qpn; break; } if ( qp->ext_qpn != qp->qpn ) { DBGC ( ibdev, "IBDEV %p QPN %#lx has external QPN %#lx\n", ibdev, qp->qpn, qp->ext_qpn ); } return qp; ibdev->op->destroy_qp ( ibdev, qp ); err_dev_create_qp: list_del ( &qp->send.list ); list_del ( &qp->recv.list ); list_del ( &qp->list ); free ( qp ); err_alloc_qp: return NULL; } /** * Modify queue pair * * @v ibdev Infiniband device * @v qp Queue pair * @v av New address vector, if applicable * @ret rc Return status code */ int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) { int rc; DBGC ( ibdev, "IBDEV %p modifying QPN %#lx\n", ibdev, qp->qpn ); if ( ( rc = ibdev->op->modify_qp ( ibdev, qp ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not modify QPN %#lx: %s\n", ibdev, qp->qpn, strerror ( rc ) ); return rc; } return 0; } /** * Destroy queue pair * * @v ibdev Infiniband device * @v qp Queue pair */ void ib_destroy_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) { struct io_buffer *iobuf; unsigned int i; DBGC ( ibdev, "IBDEV %p destroying QPN %#lx\n", ibdev, qp->qpn ); assert ( list_empty ( &qp->mgids ) ); /* Perform device-specific destruction */ ibdev->op->destroy_qp ( ibdev, qp ); /* Complete any remaining I/O buffers with errors */ for ( i = 0 ; i < qp->send.num_wqes ; i++ ) { if ( ( iobuf = qp->send.iobufs[i] ) != NULL ) ib_complete_send ( ibdev, qp, iobuf, -ECANCELED ); } for ( i = 0 ; i < qp->recv.num_wqes ; i++ ) { if ( ( iobuf = qp->recv.iobufs[i] ) != NULL ) { ib_complete_recv ( ibdev, qp, NULL, iobuf, -ECANCELED ); } } /* Remove work queues from completion queue */ list_del ( &qp->send.list ); list_del ( &qp->recv.list ); /* Free QP */ list_del ( &qp->list ); free ( qp ); } /** * Find queue pair by QPN * * @v ibdev Infiniband device * @v qpn Queue pair number * @ret qp Queue pair, or NULL */ struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev, unsigned long qpn ) { struct ib_queue_pair *qp; list_for_each_entry ( qp, &ibdev->qps, list ) { if ( ( qpn == qp->qpn ) || ( qpn == qp->ext_qpn ) ) return qp; } return NULL; } /** * Find queue pair by multicast GID * * @v ibdev Infiniband device * @v gid Multicast GID * @ret qp Queue pair, or NULL */ struct ib_queue_pair * ib_find_qp_mgid ( struct ib_device *ibdev, struct ib_gid *gid ) { struct ib_queue_pair *qp; struct ib_multicast_gid *mgid; list_for_each_entry ( qp, &ibdev->qps, list ) { list_for_each_entry ( mgid, &qp->mgids, list ) { if ( memcmp ( &mgid->gid, gid, sizeof ( mgid->gid ) ) == 0 ) { return qp; } } } return NULL; } /** * Find work queue belonging to completion queue * * @v cq Completion queue * @v qpn Queue pair number * @v is_send Find send work queue (rather than receive) * @ret wq Work queue, or NULL if not found */ struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq, unsigned long qpn, int is_send ) { struct ib_work_queue *wq; list_for_each_entry ( wq, &cq->work_queues, list ) { if ( ( wq->qp->qpn == qpn ) && ( wq->is_send == is_send ) ) return wq; } return NULL; } /** * Post send work queue entry * * @v ibdev Infiniband device * @v qp Queue pair * @v av Address vector * @v iobuf I/O buffer * @ret rc Return status code */ int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf ) { struct ib_address_vector av_copy; int rc; /* Check queue fill level */ if ( qp->send.fill >= qp->send.num_wqes ) { DBGC ( ibdev, "IBDEV %p QPN %#lx send queue full\n", ibdev, qp->qpn ); return -ENOBUFS; } /* Use default address vector if none specified */ if ( ! av ) av = &qp->av; /* Make modifiable copy of address vector */ memcpy ( &av_copy, av, sizeof ( av_copy ) ); av = &av_copy; /* Fill in optional parameters in address vector */ if ( ! av->qkey ) av->qkey = qp->qkey; if ( ! av->rate ) av->rate = IB_RATE_2_5; /* Post to hardware */ if ( ( rc = ibdev->op->post_send ( ibdev, qp, av, iobuf ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p QPN %#lx could not post send WQE: " "%s\n", ibdev, qp->qpn, strerror ( rc ) ); return rc; } qp->send.fill++; return 0; } /** * Post receive work queue entry * * @v ibdev Infiniband device * @v qp Queue pair * @v iobuf I/O buffer * @ret rc Return status code */ int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf ) { int rc; /* Check packet length */ if ( iob_tailroom ( iobuf ) < IB_MAX_PAYLOAD_SIZE ) { DBGC ( ibdev, "IBDEV %p QPN %#lx wrong RX buffer size (%zd)\n", ibdev, qp->qpn, iob_tailroom ( iobuf ) ); return -EINVAL; } /* Check queue fill level */ if ( qp->recv.fill >= qp->recv.num_wqes ) { DBGC ( ibdev, "IBDEV %p QPN %#lx receive queue full\n", ibdev, qp->qpn ); return -ENOBUFS; } /* Post to hardware */ if ( ( rc = ibdev->op->post_recv ( ibdev, qp, iobuf ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p QPN %#lx could not post receive WQE: " "%s\n", ibdev, qp->qpn, strerror ( rc ) ); return rc; } qp->recv.fill++; return 0; } /** * Complete send work queue entry * * @v ibdev Infiniband device * @v qp Queue pair * @v iobuf I/O buffer * @v rc Completion status code */ void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf, int rc ) { if ( qp->send.cq->op->complete_send ) { qp->send.cq->op->complete_send ( ibdev, qp, iobuf, rc ); } else { free_iob ( iobuf ); } qp->send.fill--; } /** * Complete receive work queue entry * * @v ibdev Infiniband device * @v qp Queue pair * @v av Address vector * @v iobuf I/O buffer * @v rc Completion status code */ void ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf, int rc ) { if ( qp->recv.cq->op->complete_recv ) { qp->recv.cq->op->complete_recv ( ibdev, qp, av, iobuf, rc ); } else { free_iob ( iobuf ); } qp->recv.fill--; } /** * Refill receive work queue * * @v ibdev Infiniband device * @v qp Queue pair */ void ib_refill_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp ) { struct io_buffer *iobuf; int rc; /* Keep filling while unfilled entries remain */ while ( qp->recv.fill < qp->recv.num_wqes ) { /* Allocate I/O buffer */ iobuf = alloc_iob ( IB_MAX_PAYLOAD_SIZE ); if ( ! iobuf ) { /* Non-fatal; we will refill on next attempt */ return; } /* Post I/O buffer */ if ( ( rc = ib_post_recv ( ibdev, qp, iobuf ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not refill: %s\n", ibdev, strerror ( rc ) ); free_iob ( iobuf ); /* Give up */ return; } } } /*************************************************************************** * * Link control * *************************************************************************** */ /** * Open port * * @v ibdev Infiniband device * @ret rc Return status code */ int ib_open ( struct ib_device *ibdev ) { int rc; /* Increment device open request counter */ if ( ibdev->open_count++ > 0 ) { /* Device was already open; do nothing */ return 0; } /* Create subnet management interface */ ibdev->smi = ib_create_mi ( ibdev, IB_QPT_SMI ); if ( ! ibdev->smi ) { DBGC ( ibdev, "IBDEV %p could not create SMI\n", ibdev ); rc = -ENOMEM; goto err_create_smi; } /* Create subnet management agent */ if ( ( rc = ib_create_sma ( ibdev, ibdev->smi ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not create SMA: %s\n", ibdev, strerror ( rc ) ); goto err_create_sma; } /* Create general services interface */ ibdev->gsi = ib_create_mi ( ibdev, IB_QPT_GSI ); if ( ! ibdev->gsi ) { DBGC ( ibdev, "IBDEV %p could not create GSI\n", ibdev ); rc = -ENOMEM; goto err_create_gsi; } /* Open device */ if ( ( rc = ibdev->op->open ( ibdev ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not open: %s\n", ibdev, strerror ( rc ) ); goto err_open; } /* Add to head of open devices list */ list_add ( &ibdev->open_list, &open_ib_devices ); assert ( ibdev->open_count == 1 ); return 0; ibdev->op->close ( ibdev ); err_open: ib_destroy_mi ( ibdev, ibdev->gsi ); err_create_gsi: ib_destroy_sma ( ibdev, ibdev->smi ); err_create_sma: ib_destroy_mi ( ibdev, ibdev->smi ); err_create_smi: assert ( ibdev->open_count == 1 ); ibdev->open_count = 0; return rc; } /** * Close port * * @v ibdev Infiniband device */ void ib_close ( struct ib_device *ibdev ) { /* Decrement device open request counter */ ibdev->open_count--; /* Close device if this was the last remaining requested opening */ if ( ibdev->open_count == 0 ) { list_del ( &ibdev->open_list ); ib_destroy_mi ( ibdev, ibdev->gsi ); ib_destroy_sma ( ibdev, ibdev->smi ); ib_destroy_mi ( ibdev, ibdev->smi ); ibdev->op->close ( ibdev ); } } /*************************************************************************** * * Multicast * *************************************************************************** */ /** * Attach to multicast group * * @v ibdev Infiniband device * @v qp Queue pair * @v gid Multicast GID * @ret rc Return status code * * Note that this function handles only the local device's attachment * to the multicast GID; it does not issue the relevant MADs to join * the multicast group on the subnet. */ int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_gid *gid ) { struct ib_multicast_gid *mgid; int rc; /* Add to software multicast GID list */ mgid = zalloc ( sizeof ( *mgid ) ); if ( ! mgid ) { rc = -ENOMEM; goto err_alloc_mgid; } memcpy ( &mgid->gid, gid, sizeof ( mgid->gid ) ); list_add ( &mgid->list, &qp->mgids ); /* Add to hardware multicast GID list */ if ( ( rc = ibdev->op->mcast_attach ( ibdev, qp, gid ) ) != 0 ) goto err_dev_mcast_attach; return 0; err_dev_mcast_attach: list_del ( &mgid->list ); free ( mgid ); err_alloc_mgid: return rc; } /** * Detach from multicast group * * @v ibdev Infiniband device * @v qp Queue pair * @v gid Multicast GID */ void ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_gid *gid ) { struct ib_multicast_gid *mgid; /* Remove from hardware multicast GID list */ ibdev->op->mcast_detach ( ibdev, qp, gid ); /* Remove from software multicast GID list */ list_for_each_entry ( mgid, &qp->mgids, list ) { if ( memcmp ( &mgid->gid, gid, sizeof ( mgid->gid ) ) == 0 ) { list_del ( &mgid->list ); free ( mgid ); break; } } } /*************************************************************************** * * Miscellaneous * *************************************************************************** */ /** * Get Infiniband HCA information * * @v ibdev Infiniband device * @ret hca_guid HCA GUID * @ret num_ports Number of ports */ int ib_get_hca_info ( struct ib_device *ibdev, struct ib_gid_half *hca_guid ) { struct ib_device *tmp; int num_ports = 0; /* Search for IB devices with the same physical device to * identify port count and a suitable Node GUID. */ for_each_ibdev ( tmp ) { if ( tmp->dev != ibdev->dev ) continue; if ( num_ports == 0 ) { memcpy ( hca_guid, &tmp->gid.u.half[1], sizeof ( *hca_guid ) ); } num_ports++; } return num_ports; } /** * Set port information * * @v ibdev Infiniband device * @v mad Set port information MAD */ int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad ) { int rc; /* Adapters with embedded SMAs do not need to support this method */ if ( ! ibdev->op->set_port_info ) { DBGC ( ibdev, "IBDEV %p does not support setting port " "information\n", ibdev ); return -ENOTSUP; } if ( ( rc = ibdev->op->set_port_info ( ibdev, mad ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not set port information: %s\n", ibdev, strerror ( rc ) ); return rc; } return 0; }; /** * Set partition key table * * @v ibdev Infiniband device * @v mad Set partition key table MAD */ int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad ) { int rc; /* Adapters with embedded SMAs do not need to support this method */ if ( ! ibdev->op->set_pkey_table ) { DBGC ( ibdev, "IBDEV %p does not support setting partition " "key table\n", ibdev ); return -ENOTSUP; } if ( ( rc = ibdev->op->set_pkey_table ( ibdev, mad ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not set partition key table: " "%s\n", ibdev, strerror ( rc ) ); return rc; } return 0; }; /*************************************************************************** * * Event queues * *************************************************************************** */ /** * Handle Infiniband link state change * * @v ibdev Infiniband device */ void ib_link_state_changed ( struct ib_device *ibdev ) { /* Notify IPoIB of link state change */ ipoib_link_state_changed ( ibdev ); } /** * Poll event queue * * @v ibdev Infiniband device */ void ib_poll_eq ( struct ib_device *ibdev ) { struct ib_completion_queue *cq; /* Poll device's event queue */ ibdev->op->poll_eq ( ibdev ); /* Poll all completion queues */ list_for_each_entry ( cq, &ibdev->cqs, list ) ib_poll_cq ( ibdev, cq ); } /** * Single-step the Infiniband event queue * * @v process Infiniband event queue process */ static void ib_step ( struct process *process __unused ) { struct ib_device *ibdev; for_each_ibdev ( ibdev ) ib_poll_eq ( ibdev ); } /** Infiniband event queue process */ struct process ib_process __permanent_process = { .list = LIST_HEAD_INIT ( ib_process.list ), .step = ib_step, }; /*************************************************************************** * * Infiniband device creation/destruction * *************************************************************************** */ /** * Allocate Infiniband device * * @v priv_size Size of driver private data area * @ret ibdev Infiniband device, or NULL */ struct ib_device * alloc_ibdev ( size_t priv_size ) { struct ib_device *ibdev; void *drv_priv; size_t total_len; total_len = ( sizeof ( *ibdev ) + priv_size ); ibdev = zalloc ( total_len ); if ( ibdev ) { drv_priv = ( ( ( void * ) ibdev ) + sizeof ( *ibdev ) ); ib_set_drvdata ( ibdev, drv_priv ); INIT_LIST_HEAD ( &ibdev->cqs ); INIT_LIST_HEAD ( &ibdev->qps ); ibdev->lid = IB_LID_NONE; ibdev->pkey = IB_PKEY_NONE; } return ibdev; } /** * Register Infiniband device * * @v ibdev Infiniband device * @ret rc Return status code */ int register_ibdev ( struct ib_device *ibdev ) { int rc; /* Add to device list */ ibdev_get ( ibdev ); list_add_tail ( &ibdev->list, &ib_devices ); /* Add IPoIB device */ if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not add IPoIB device: %s\n", ibdev, strerror ( rc ) ); goto err_ipoib_probe; } DBGC ( ibdev, "IBDEV %p registered (phys %s)\n", ibdev, ibdev->dev->name ); return 0; err_ipoib_probe: list_del ( &ibdev->list ); ibdev_put ( ibdev ); return rc; } /** * Unregister Infiniband device * * @v ibdev Infiniband device */ void unregister_ibdev ( struct ib_device *ibdev ) { /* Close device */ ipoib_remove ( ibdev ); /* Remove from device list */ list_del ( &ibdev->list ); ibdev_put ( ibdev ); DBGC ( ibdev, "IBDEV %p unregistered\n", ibdev ); } /** * Find Infiniband device by GID * * @v gid GID * @ret ibdev Infiniband device, or NULL */ struct ib_device * find_ibdev ( struct ib_gid *gid ) { struct ib_device *ibdev; for_each_ibdev ( ibdev ) { if ( memcmp ( gid, &ibdev->gid, sizeof ( *gid ) ) == 0 ) return ibdev; } return NULL; } /** * Get most recently opened Infiniband device * * @ret ibdev Most recently opened Infiniband device, or NULL */ struct ib_device * last_opened_ibdev ( void ) { struct ib_device *ibdev; list_for_each_entry ( ibdev, &open_ib_devices, open_list ) { assert ( ibdev->open_count != 0 ); return ibdev; } return NULL; } debian/grub-extras/disabled/gpxe/src/net/dhcpopts.c0000664000000000000000000003036012524662415017523 0ustar /* * Copyright (C) 2008 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include /** @file * * DHCP options * */ /** * Obtain printable version of a DHCP option tag * * @v tag DHCP option tag * @ret name String representation of the tag * */ static inline char * dhcp_tag_name ( unsigned int tag ) { static char name[8]; if ( DHCP_IS_ENCAP_OPT ( tag ) ) { snprintf ( name, sizeof ( name ), "%d.%d", DHCP_ENCAPSULATOR ( tag ), DHCP_ENCAPSULATED ( tag ) ); } else { snprintf ( name, sizeof ( name ), "%d", tag ); } return name; } /** * Get pointer to DHCP option * * @v options DHCP options block * @v offset Offset within options block * @ret option DHCP option */ static inline __attribute__ (( always_inline )) struct dhcp_option * dhcp_option ( struct dhcp_options *options, unsigned int offset ) { return ( ( struct dhcp_option * ) ( options->data + offset ) ); } /** * Get offset of a DHCP option * * @v options DHCP options block * @v option DHCP option * @ret offset Offset within options block */ static inline __attribute__ (( always_inline )) int dhcp_option_offset ( struct dhcp_options *options, struct dhcp_option *option ) { return ( ( ( void * ) option ) - options->data ); } /** * Calculate length of any DHCP option * * @v option DHCP option * @ret len Length (including tag and length field) */ static unsigned int dhcp_option_len ( struct dhcp_option *option ) { if ( ( option->tag == DHCP_END ) || ( option->tag == DHCP_PAD ) ) { return 1; } else { return ( option->len + DHCP_OPTION_HEADER_LEN ); } } /** * Find DHCP option within DHCP options block, and its encapsulator (if any) * * @v options DHCP options block * @v tag DHCP option tag to search for * @ret encap_offset Offset of encapsulating DHCP option * @ret offset Offset of DHCP option, or negative error * * Searches for the DHCP option matching the specified tag within the * DHCP option block. Encapsulated options may be searched for by * using DHCP_ENCAP_OPT() to construct the tag value. * * If the option is encapsulated, and @c encapsulator is non-NULL, it * will be filled in with the offset of the encapsulating option. * * This routine is designed to be paranoid. It does not assume that * the option data is well-formatted, and so must guard against flaws * such as options missing a @c DHCP_END terminator, or options whose * length would take them beyond the end of the data block. */ static int find_dhcp_option_with_encap ( struct dhcp_options *options, unsigned int tag, int *encap_offset ) { unsigned int original_tag __attribute__ (( unused )) = tag; struct dhcp_option *option; int offset = 0; ssize_t remaining = options->len; unsigned int option_len; /* Sanity check */ if ( tag == DHCP_PAD ) return -ENOENT; /* Search for option */ while ( remaining ) { /* Calculate length of this option. Abort processing * if the length is malformed (i.e. takes us beyond * the end of the data block). */ option = dhcp_option ( options, offset ); option_len = dhcp_option_len ( option ); remaining -= option_len; if ( remaining < 0 ) break; /* Check for explicit end marker */ if ( option->tag == DHCP_END ) break; /* Check for matching tag */ if ( option->tag == tag ) { DBGC ( options, "DHCPOPT %p found %s (length %d)\n", options, dhcp_tag_name ( original_tag ), option_len ); return offset; } /* Check for start of matching encapsulation block */ if ( DHCP_IS_ENCAP_OPT ( tag ) && ( option->tag == DHCP_ENCAPSULATOR ( tag ) ) ) { if ( encap_offset ) *encap_offset = offset; /* Continue search within encapsulated option block */ tag = DHCP_ENCAPSULATED ( tag ); remaining = option_len; offset += DHCP_OPTION_HEADER_LEN; continue; } offset += option_len; } return -ENOENT; } /** * Resize a DHCP option * * @v options DHCP option block * @v offset Offset of option to resize * @v encap_offset Offset of encapsulating offset (or -ve for none) * @v old_len Old length (including header) * @v new_len New length (including header) * @v can_realloc Can reallocate options data if necessary * @ret rc Return status code */ static int resize_dhcp_option ( struct dhcp_options *options, int offset, int encap_offset, size_t old_len, size_t new_len, int can_realloc ) { struct dhcp_option *encapsulator; struct dhcp_option *option; ssize_t delta = ( new_len - old_len ); size_t new_options_len; size_t new_encapsulator_len; void *new_data; void *source; void *dest; void *end; /* Check for sufficient space, and update length fields */ if ( new_len > DHCP_MAX_LEN ) { DBGC ( options, "DHCPOPT %p overlength option\n", options ); return -ENOSPC; } new_options_len = ( options->len + delta ); if ( new_options_len > options->max_len ) { /* Reallocate options block if allowed to do so. */ if ( can_realloc ) { new_data = realloc ( options->data, new_options_len ); if ( ! new_data ) { DBGC ( options, "DHCPOPT %p could not " "reallocate to %zd bytes\n", options, new_options_len ); return -ENOMEM; } options->data = new_data; options->max_len = new_options_len; } else { DBGC ( options, "DHCPOPT %p out of space\n", options ); return -ENOMEM; } } if ( encap_offset >= 0 ) { encapsulator = dhcp_option ( options, encap_offset ); new_encapsulator_len = ( encapsulator->len + delta ); if ( new_encapsulator_len > DHCP_MAX_LEN ) { DBGC ( options, "DHCPOPT %p overlength encapsulator\n", options ); return -ENOSPC; } encapsulator->len = new_encapsulator_len; } options->len = new_options_len; /* Move remainder of option data */ option = dhcp_option ( options, offset ); source = ( ( ( void * ) option ) + old_len ); dest = ( ( ( void * ) option ) + new_len ); end = ( options->data + options->max_len ); memmove ( dest, source, ( end - dest ) ); return 0; } /** * Set value of DHCP option * * @v options DHCP option block * @v tag DHCP option tag * @v data New value for DHCP option * @v len Length of value, in bytes * @v can_realloc Can reallocate options data if necessary * @ret offset Offset of DHCP option, or negative error * * Sets the value of a DHCP option within the options block. The * option may or may not already exist. Encapsulators will be created * (and deleted) as necessary. * * This call may fail due to insufficient space in the options block. * If it does fail, and the option existed previously, the option will * be left with its original value. */ static int set_dhcp_option ( struct dhcp_options *options, unsigned int tag, const void *data, size_t len, int can_realloc ) { static const uint8_t empty_encapsulator[] = { DHCP_END }; int offset; int encap_offset = -1; int creation_offset = 0; struct dhcp_option *option; unsigned int encap_tag = DHCP_ENCAPSULATOR ( tag ); size_t old_len = 0; size_t new_len = ( len ? ( len + DHCP_OPTION_HEADER_LEN ) : 0 ); int rc; /* Sanity check */ if ( tag == DHCP_PAD ) return -ENOTTY; /* Find old instance of this option, if any */ offset = find_dhcp_option_with_encap ( options, tag, &encap_offset ); if ( offset >= 0 ) { old_len = dhcp_option_len ( dhcp_option ( options, offset ) ); DBGC ( options, "DHCPOPT %p resizing %s from %zd to %zd\n", options, dhcp_tag_name ( tag ), old_len, new_len ); } else { DBGC ( options, "DHCPOPT %p creating %s (length %zd)\n", options, dhcp_tag_name ( tag ), new_len ); } /* Ensure that encapsulator exists, if required */ if ( encap_tag ) { if ( encap_offset < 0 ) encap_offset = set_dhcp_option ( options, encap_tag, empty_encapsulator, 1, can_realloc ); if ( encap_offset < 0 ) return encap_offset; creation_offset = ( encap_offset + DHCP_OPTION_HEADER_LEN ); } /* Create new option if necessary */ if ( offset < 0 ) offset = creation_offset; /* Resize option to fit new data */ if ( ( rc = resize_dhcp_option ( options, offset, encap_offset, old_len, new_len, can_realloc ) ) != 0 ) return rc; /* Copy new data into option, if applicable */ if ( len ) { option = dhcp_option ( options, offset ); option->tag = tag; option->len = len; memcpy ( &option->data, data, len ); } /* Delete encapsulator if there's nothing else left in it */ if ( encap_offset >= 0 ) { option = dhcp_option ( options, encap_offset ); if ( option->len <= 1 ) set_dhcp_option ( options, encap_tag, NULL, 0, 0 ); } return offset; } /** * Store value of DHCP option setting * * @v options DHCP option block * @v tag Setting tag number * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ int dhcpopt_store ( struct dhcp_options *options, unsigned int tag, const void *data, size_t len ) { int offset; offset = set_dhcp_option ( options, tag, data, len, 0 ); if ( offset < 0 ) return offset; return 0; } /** * Store value of DHCP option setting, extending options block if necessary * * @v options DHCP option block * @v tag Setting tag number * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ int dhcpopt_extensible_store ( struct dhcp_options *options, unsigned int tag, const void *data, size_t len ) { int offset; offset = set_dhcp_option ( options, tag, data, len, 1 ); if ( offset < 0 ) return offset; return 0; } /** * Fetch value of DHCP option setting * * @v options DHCP option block * @v tag Setting tag number * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error */ int dhcpopt_fetch ( struct dhcp_options *options, unsigned int tag, void *data, size_t len ) { int offset; struct dhcp_option *option; size_t option_len; offset = find_dhcp_option_with_encap ( options, tag, NULL ); if ( offset < 0 ) return offset; option = dhcp_option ( options, offset ); option_len = option->len; if ( len > option_len ) len = option_len; memcpy ( data, option->data, len ); return option_len; } /** * Recalculate length of DHCP options block * * @v options Uninitialised DHCP option block * * The "used length" field will be updated based on scanning through * the block to find the end of the options. */ static void dhcpopt_update_len ( struct dhcp_options *options ) { struct dhcp_option *option; int offset = 0; ssize_t remaining = options->max_len; unsigned int option_len; /* Find last non-pad option */ options->len = 0; while ( remaining ) { option = dhcp_option ( options, offset ); option_len = dhcp_option_len ( option ); remaining -= option_len; if ( remaining < 0 ) break; offset += option_len; if ( option->tag != DHCP_PAD ) options->len = offset; } } /** * Initialise prepopulated block of DHCP options * * @v options Uninitialised DHCP option block * @v data Memory for DHCP option data * @v max_len Length of memory for DHCP option data * * The memory content must already be filled with valid DHCP options. * A zeroed block counts as a block of valid DHCP options. */ void dhcpopt_init ( struct dhcp_options *options, void *data, size_t max_len ) { /* Fill in fields */ options->data = data; options->max_len = max_len; /* Update length */ dhcpopt_update_len ( options ); DBGC ( options, "DHCPOPT %p created (data %p len %#zx max_len %#zx)\n", options, options->data, options->len, options->max_len ); } debian/grub-extras/disabled/gpxe/src/net/tcpip.c0000664000000000000000000001025612524662415017020 0ustar #include #include #include #include #include #include #include /** @file * * Transport-network layer interface * * This file contains functions and utilities for the * TCP/IP transport-network layer interface */ FILE_LICENCE ( GPL2_OR_LATER ); /** Process a received TCP/IP packet * * @v iobuf I/O buffer * @v tcpip_proto Transport-layer protocol number * @v st_src Partially-filled source address * @v st_dest Partially-filled destination address * @v pshdr_csum Pseudo-header checksum * @ret rc Return status code * * This function expects a transport-layer segment from the network * layer. The network layer should fill in as much as it can of the * source and destination addresses (i.e. it should fill in the * address family and the network-layer addresses, but leave the ports * and the rest of the structures as zero). */ int tcpip_rx ( struct io_buffer *iobuf, uint8_t tcpip_proto, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ) { struct tcpip_protocol *tcpip; /* Hand off packet to the appropriate transport-layer protocol */ for_each_table_entry ( tcpip, TCPIP_PROTOCOLS ) { if ( tcpip->tcpip_proto == tcpip_proto ) { DBG ( "TCP/IP received %s packet\n", tcpip->name ); return tcpip->rx ( iobuf, st_src, st_dest, pshdr_csum ); } } DBG ( "Unrecognised TCP/IP protocol %d\n", tcpip_proto ); free_iob ( iobuf ); return -EPROTONOSUPPORT; } /** Transmit a TCP/IP packet * * @v iobuf I/O buffer * @v tcpip_protocol Transport-layer protocol * @v st_src Source address, or NULL to use route default * @v st_dest Destination address * @v netdev Network device to use if no route found, or NULL * @v trans_csum Transport-layer checksum to complete, or NULL * @ret rc Return status code */ int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, struct net_device *netdev, uint16_t *trans_csum ) { struct tcpip_net_protocol *tcpip_net; /* Hand off packet to the appropriate network-layer protocol */ for_each_table_entry ( tcpip_net, TCPIP_NET_PROTOCOLS ) { if ( tcpip_net->sa_family == st_dest->st_family ) { DBG ( "TCP/IP sending %s packet\n", tcpip_net->name ); return tcpip_net->tx ( iobuf, tcpip_protocol, st_src, st_dest, netdev, trans_csum ); } } DBG ( "Unrecognised TCP/IP address family %d\n", st_dest->st_family ); free_iob ( iobuf ); return -EAFNOSUPPORT; } /** * Calculate continued TCP/IP checkum * * @v partial Checksum of already-summed data, in network byte order * @v data Data buffer * @v len Length of data buffer * @ret cksum Updated checksum, in network byte order * * Calculates a TCP/IP-style 16-bit checksum over the data block. The * checksum is returned in network byte order. * * This function may be used to add new data to an existing checksum. * The function assumes that both the old data and the new data start * on even byte offsets; if this is not the case then you will need to * byte-swap either the input partial checksum, the output checksum, * or both. Deciding which to swap is left as an exercise for the * interested reader. */ uint16_t tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ) { unsigned int cksum = ( ( ~partial ) & 0xffff ); unsigned int value; unsigned int i; for ( i = 0 ; i < len ; i++ ) { value = * ( ( uint8_t * ) data + i ); if ( i & 1 ) { /* Odd bytes: swap on little-endian systems */ value = be16_to_cpu ( value ); } else { /* Even bytes: swap on big-endian systems */ value = le16_to_cpu ( value ); } cksum += value; if ( cksum > 0xffff ) cksum -= 0xffff; } return ( ~cksum ); } /** * Calculate TCP/IP checkum * * @v data Data buffer * @v len Length of data buffer * @ret cksum Checksum, in network byte order * * Calculates a TCP/IP-style 16-bit checksum over the data block. The * checksum is returned in network byte order. */ uint16_t tcpip_chksum ( const void *data, size_t len ) { return tcpip_continue_chksum ( TCPIP_EMPTY_CSUM, data, len ); } debian/grub-extras/disabled/gpxe/src/net/retry.c0000664000000000000000000001240412524662415017043 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include /** @file * * Retry timers * * A retry timer is a binary exponential backoff timer. It can be * used to build automatic retransmission into network protocols. * * This implementation of the timer is designed to satisfy RFC 2988 * and therefore be usable as a TCP retransmission timer. * * */ /* The theoretical minimum that the algorithm in stop_timer() can * adjust the timeout back down to is seven ticks, so set the minimum * timeout to at least that value for the sake of consistency. */ #define MIN_TIMEOUT 7 /** List of running timers */ static LIST_HEAD ( timers ); /** * Start timer * * @v timer Retry timer * * This starts the timer running with the current timeout value. If * stop_timer() is not called before the timer expires, the timer will * be stopped and the timer's callback function will be called. */ void start_timer ( struct retry_timer *timer ) { if ( ! timer->running ) list_add ( &timer->list, &timers ); timer->start = currticks(); timer->running = 1; /* 0 means "use default timeout" */ if ( timer->min_timeout == 0 ) timer->min_timeout = DEFAULT_MIN_TIMEOUT; /* We must never be less than MIN_TIMEOUT under any circumstances */ if ( timer->min_timeout < MIN_TIMEOUT ) timer->min_timeout = MIN_TIMEOUT; /* Honor user-specified minimum timeout */ if ( timer->timeout < timer->min_timeout ) timer->timeout = timer->min_timeout; DBG2 ( "Timer %p started at time %ld (expires at %ld)\n", timer, timer->start, ( timer->start + timer->timeout ) ); } /** * Start timer with a specified fixed timeout * * @v timer Retry timer * @v timeout Timeout, in ticks */ void start_timer_fixed ( struct retry_timer *timer, unsigned long timeout ) { start_timer ( timer ); timer->timeout = timeout; DBG2 ( "Timer %p expiry time changed to %ld\n", timer, ( timer->start + timer->timeout ) ); } /** * Stop timer * * @v timer Retry timer * * This stops the timer and updates the timer's timeout value. */ void stop_timer ( struct retry_timer *timer ) { unsigned long old_timeout = timer->timeout; unsigned long now = currticks(); unsigned long runtime; /* If timer was already stopped, do nothing */ if ( ! timer->running ) return; list_del ( &timer->list ); runtime = ( now - timer->start ); timer->running = 0; DBG2 ( "Timer %p stopped at time %ld (ran for %ld)\n", timer, now, runtime ); /* Update timer. Variables are: * * r = round-trip time estimate (i.e. runtime) * t = timeout value (i.e. timer->timeout) * s = smoothed round-trip time * * By choice, we set t = 4s, i.e. allow for four times the * normal round-trip time to pass before retransmitting. * * We want to smooth according to s := ( 7 s + r ) / 8 * * Since we don't actually store s, this reduces to * t := ( 7 t / 8 ) + ( r / 2 ) * */ if ( timer->count ) { timer->count--; } else { timer->timeout -= ( timer->timeout >> 3 ); timer->timeout += ( runtime >> 1 ); if ( timer->timeout != old_timeout ) { DBG ( "Timer %p timeout updated to %ld\n", timer, timer->timeout ); } } } /** * Handle expired timer * * @v timer Retry timer */ static void timer_expired ( struct retry_timer *timer ) { int fail; /* Stop timer without performing RTT calculations */ DBG2 ( "Timer %p stopped at time %ld on expiry\n", timer, currticks() ); assert ( timer->running ); list_del ( &timer->list ); timer->running = 0; timer->count++; /* Back off the timeout value */ timer->timeout <<= 1; if ( timer->max_timeout == 0 ) /* 0 means "use default timeout" */ timer->max_timeout = DEFAULT_MAX_TIMEOUT; if ( ( fail = ( timer->timeout > timer->max_timeout ) ) ) timer->timeout = timer->max_timeout; DBG ( "Timer %p timeout backed off to %ld\n", timer, timer->timeout ); /* Call expiry callback */ timer->expired ( timer, fail ); } /** * Single-step the retry timer list * * @v process Retry timer process */ static void retry_step ( struct process *process __unused ) { struct retry_timer *timer; struct retry_timer *tmp; unsigned long now = currticks(); unsigned long used; list_for_each_entry_safe ( timer, tmp, &timers, list ) { used = ( now - timer->start ); if ( used >= timer->timeout ) timer_expired ( timer ); } } /** Retry timer process */ struct process retry_process __permanent_process = { .list = LIST_HEAD_INIT ( retry_process.list ), .step = retry_step, }; debian/grub-extras/disabled/gpxe/src/net/icmp.c0000664000000000000000000000516412524662415016633 0ustar /* * Copyright (C) 2009 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include /** @file * * ICMP protocol * */ struct tcpip_protocol icmp_protocol __tcpip_protocol; /** * Process a received packet * * @v iobuf I/O buffer * @v st_src Partially-filled source address * @v st_dest Partially-filled destination address * @v pshdr_csum Pseudo-header checksum * @ret rc Return status code */ static int icmp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum __unused ) { struct icmp_header *icmp = iobuf->data; size_t len = iob_len ( iobuf ); unsigned int csum; int rc; /* Sanity check */ if ( len < sizeof ( *icmp ) ) { DBG ( "ICMP packet too short at %zd bytes (min %zd bytes)\n", len, sizeof ( *icmp ) ); rc = -EINVAL; goto done; } /* Verify checksum */ csum = tcpip_chksum ( icmp, len ); if ( csum != 0 ) { DBG ( "ICMP checksum incorrect (is %04x, should be 0000)\n", csum ); DBG_HD ( icmp, len ); rc = -EINVAL; goto done; } /* We respond only to pings */ if ( icmp->type != ICMP_ECHO_REQUEST ) { DBG ( "ICMP ignoring type %d\n", icmp->type ); rc = 0; goto done; } DBG ( "ICMP responding to ping\n" ); /* Change type to response and recalculate checksum */ icmp->type = ICMP_ECHO_RESPONSE; icmp->chksum = 0; icmp->chksum = tcpip_chksum ( icmp, len ); /* Transmit the response */ if ( ( rc = tcpip_tx ( iob_disown ( iobuf ), &icmp_protocol, st_dest, st_src, NULL, NULL ) ) != 0 ) { DBG ( "ICMP could not transmit ping response: %s\n", strerror ( rc ) ); goto done; } done: free_iob ( iobuf ); return rc; } /** ICMP TCP/IP protocol */ struct tcpip_protocol icmp_protocol __tcpip_protocol = { .name = "ICMP", .rx = icmp_rx, .tcpip_proto = IP_ICMP, }; debian/grub-extras/disabled/gpxe/src/net/iobpad.c0000664000000000000000000000360512524662415017137 0ustar /* * Copyright (C) 2007 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); /** * @file * * I/O buffer padding * */ #include #include /** * Pad I/O buffer * * @v iobuf I/O buffer * @v min_len Minimum length * * This function pads and aligns I/O buffers, for devices that * aren't capable of padding in hardware, or that require specific * alignment in TX buffers. The packet data will end up aligned to a * multiple of @c IOB_ALIGN. * * @c min_len must not exceed @v IOB_ZLEN. */ void iob_pad ( struct io_buffer *iobuf, size_t min_len ) { void *data; size_t len; size_t headroom; signed int pad_len; assert ( min_len <= IOB_ZLEN ); /* Move packet data to start of I/O buffer. This will both * align the data (since I/O buffers are aligned to * IOB_ALIGN) and give us sufficient space for the * zero-padding */ data = iobuf->data; len = iob_len ( iobuf ); headroom = iob_headroom ( iobuf ); iob_push ( iobuf, headroom ); memmove ( iobuf->data, data, len ); iob_unput ( iobuf, headroom ); /* Pad to minimum packet length */ pad_len = ( min_len - iob_len ( iobuf ) ); if ( pad_len > 0 ) memset ( iob_put ( iobuf, pad_len ), 0, pad_len ); } debian/grub-extras/disabled/gpxe/src/net/netdevice.c0000664000000000000000000003665512524662415017662 0ustar /* * Copyright (C) 2006 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @file * * Network device management * */ /** List of network devices */ struct list_head net_devices = LIST_HEAD_INIT ( net_devices ); /** List of open network devices, in reverse order of opening */ static struct list_head open_net_devices = LIST_HEAD_INIT ( open_net_devices ); /** Default link status code */ #define EUNKNOWN_LINK_STATUS EINPROGRESS /** Human-readable message for the default link status */ struct errortab netdev_errors[] __errortab = { { EUNKNOWN_LINK_STATUS, "Unknown" }, }; /** * Mark network device as having link down * * @v netdev Network device */ void netdev_link_down ( struct net_device *netdev ) { switch ( netdev->link_rc ) { case 0: case -EUNKNOWN_LINK_STATUS: netdev->link_rc = -ENOTCONN; break; default: /* Avoid clobbering a more detailed link status code, * if one is already set. */ break; } } /** * Record network device statistic * * @v stats Network device statistics * @v rc Status code */ static void netdev_record_stat ( struct net_device_stats *stats, int rc ) { struct net_device_error *error; struct net_device_error *least_common_error; unsigned int i; /* If this is not an error, just update the good counter */ if ( rc == 0 ) { stats->good++; return; } /* Update the bad counter */ stats->bad++; /* Locate the appropriate error record */ least_common_error = &stats->errors[0]; for ( i = 0 ; i < ( sizeof ( stats->errors ) / sizeof ( stats->errors[0] ) ) ; i++ ) { error = &stats->errors[i]; /* Update matching record, if found */ if ( error->rc == rc ) { error->count++; return; } if ( error->count < least_common_error->count ) least_common_error = error; } /* Overwrite the least common error record */ least_common_error->rc = rc; least_common_error->count = 1; } /** * Transmit raw packet via network device * * @v netdev Network device * @v iobuf I/O buffer * @ret rc Return status code * * Transmits the packet via the specified network device. This * function takes ownership of the I/O buffer. */ int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ) { int rc; DBGC ( netdev, "NETDEV %p transmitting %p (%p+%zx)\n", netdev, iobuf, iobuf->data, iob_len ( iobuf ) ); list_add_tail ( &iobuf->list, &netdev->tx_queue ); if ( ! ( netdev->state & NETDEV_OPEN ) ) { rc = -ENETUNREACH; goto err; } if ( ( rc = netdev->op->transmit ( netdev, iobuf ) ) != 0 ) goto err; return 0; err: netdev_tx_complete_err ( netdev, iobuf, rc ); return rc; } /** * Complete network transmission * * @v netdev Network device * @v iobuf I/O buffer * @v rc Packet status code * * The packet must currently be in the network device's TX queue. */ void netdev_tx_complete_err ( struct net_device *netdev, struct io_buffer *iobuf, int rc ) { /* Update statistics counter */ netdev_record_stat ( &netdev->tx_stats, rc ); if ( rc == 0 ) { DBGC ( netdev, "NETDEV %p transmission %p complete\n", netdev, iobuf ); } else { DBGC ( netdev, "NETDEV %p transmission %p failed: %s\n", netdev, iobuf, strerror ( rc ) ); } /* Catch data corruption as early as possible */ assert ( iobuf->list.next != NULL ); assert ( iobuf->list.prev != NULL ); /* Dequeue and free I/O buffer */ list_del ( &iobuf->list ); free_iob ( iobuf ); } /** * Complete network transmission * * @v netdev Network device * @v rc Packet status code * * Completes the oldest outstanding packet in the TX queue. */ void netdev_tx_complete_next_err ( struct net_device *netdev, int rc ) { struct io_buffer *iobuf; list_for_each_entry ( iobuf, &netdev->tx_queue, list ) { netdev_tx_complete_err ( netdev, iobuf, rc ); return; } } /** * Flush device's transmit queue * * @v netdev Network device */ static void netdev_tx_flush ( struct net_device *netdev ) { /* Discard any packets in the TX queue */ while ( ! list_empty ( &netdev->tx_queue ) ) { netdev_tx_complete_next_err ( netdev, -ECANCELED ); } } /** * Add packet to receive queue * * @v netdev Network device * @v iobuf I/O buffer, or NULL * * The packet is added to the network device's RX queue. This * function takes ownership of the I/O buffer. */ void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) { DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n", netdev, iobuf, iobuf->data, iob_len ( iobuf ) ); /* Enqueue packet */ list_add_tail ( &iobuf->list, &netdev->rx_queue ); /* Update statistics counter */ netdev_record_stat ( &netdev->rx_stats, 0 ); } /** * Discard received packet * * @v netdev Network device * @v iobuf I/O buffer, or NULL * @v rc Packet status code * * The packet is discarded and an RX error is recorded. This function * takes ownership of the I/O buffer. @c iobuf may be NULL if, for * example, the net device wishes to report an error due to being * unable to allocate an I/O buffer. */ void netdev_rx_err ( struct net_device *netdev, struct io_buffer *iobuf, int rc ) { DBGC ( netdev, "NETDEV %p failed to receive %p: %s\n", netdev, iobuf, strerror ( rc ) ); /* Discard packet */ free_iob ( iobuf ); /* Update statistics counter */ netdev_record_stat ( &netdev->rx_stats, rc ); } /** * Poll for completed and received packets on network device * * @v netdev Network device * * Polls the network device for completed transmissions and received * packets. Any received packets will be added to the RX packet queue * via netdev_rx(). */ void netdev_poll ( struct net_device *netdev ) { if ( netdev->state & NETDEV_OPEN ) netdev->op->poll ( netdev ); } /** * Remove packet from device's receive queue * * @v netdev Network device * @ret iobuf I/O buffer, or NULL * * Removes the first packet from the device's RX queue and returns it. * Ownership of the packet is transferred to the caller. */ struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev ) { struct io_buffer *iobuf; list_for_each_entry ( iobuf, &netdev->rx_queue, list ) { list_del ( &iobuf->list ); return iobuf; } return NULL; } /** * Flush device's receive queue * * @v netdev Network device */ static void netdev_rx_flush ( struct net_device *netdev ) { struct io_buffer *iobuf; /* Discard any packets in the RX queue */ while ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) { netdev_rx_err ( netdev, iobuf, -ECANCELED ); } } /** * Free network device * * @v refcnt Network device reference counter */ static void free_netdev ( struct refcnt *refcnt ) { struct net_device *netdev = container_of ( refcnt, struct net_device, refcnt ); netdev_tx_flush ( netdev ); netdev_rx_flush ( netdev ); clear_settings ( netdev_settings ( netdev ) ); free ( netdev ); } /** * Allocate network device * * @v priv_size Size of private data area (net_device::priv) * @ret netdev Network device, or NULL * * Allocates space for a network device and its private data area. */ struct net_device * alloc_netdev ( size_t priv_size ) { struct net_device *netdev; size_t total_len; total_len = ( sizeof ( *netdev ) + priv_size ); netdev = zalloc ( total_len ); if ( netdev ) { netdev->refcnt.free = free_netdev; netdev->link_rc = -EUNKNOWN_LINK_STATUS; INIT_LIST_HEAD ( &netdev->tx_queue ); INIT_LIST_HEAD ( &netdev->rx_queue ); netdev_settings_init ( netdev ); netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) ); } return netdev; } /** * Register network device * * @v netdev Network device * @ret rc Return status code * * Gives the network device a name and adds it to the list of network * devices. */ int register_netdev ( struct net_device *netdev ) { static unsigned int ifindex = 0; int rc; /* Create device name */ snprintf ( netdev->name, sizeof ( netdev->name ), "net%d", ifindex++ ); /* Set initial link-layer address */ netdev->ll_protocol->init_addr ( netdev->hw_addr, netdev->ll_addr ); /* Register per-netdev configuration settings */ if ( ( rc = register_settings ( netdev_settings ( netdev ), NULL ) ) != 0 ) { DBGC ( netdev, "NETDEV %p could not register settings: %s\n", netdev, strerror ( rc ) ); return rc; } /* Add to device list */ netdev_get ( netdev ); list_add_tail ( &netdev->list, &net_devices ); DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n", netdev, netdev->name, netdev->dev->name, netdev_addr ( netdev ) ); return 0; } /** * Open network device * * @v netdev Network device * @ret rc Return status code */ int netdev_open ( struct net_device *netdev ) { int rc; /* Do nothing if device is already open */ if ( netdev->state & NETDEV_OPEN ) return 0; DBGC ( netdev, "NETDEV %p opening\n", netdev ); /* Open the device */ if ( ( rc = netdev->op->open ( netdev ) ) != 0 ) return rc; /* Mark as opened */ netdev->state |= NETDEV_OPEN; /* Add to head of open devices list */ list_add ( &netdev->open_list, &open_net_devices ); return 0; } /** * Close network device * * @v netdev Network device */ void netdev_close ( struct net_device *netdev ) { /* Do nothing if device is already closed */ if ( ! ( netdev->state & NETDEV_OPEN ) ) return; DBGC ( netdev, "NETDEV %p closing\n", netdev ); /* Close the device */ netdev->op->close ( netdev ); /* Flush TX and RX queues */ netdev_tx_flush ( netdev ); netdev_rx_flush ( netdev ); /* Mark as closed */ netdev->state &= ~NETDEV_OPEN; /* Remove from open devices list */ list_del ( &netdev->open_list ); } /** * Unregister network device * * @v netdev Network device * * Removes the network device from the list of network devices. */ void unregister_netdev ( struct net_device *netdev ) { /* Ensure device is closed */ netdev_close ( netdev ); /* Unregister per-netdev configuration settings */ unregister_settings ( netdev_settings ( netdev ) ); /* Remove from device list */ list_del ( &netdev->list ); netdev_put ( netdev ); DBGC ( netdev, "NETDEV %p unregistered\n", netdev ); } /** Enable or disable interrupts * * @v netdev Network device * @v enable Interrupts should be enabled */ void netdev_irq ( struct net_device *netdev, int enable ) { netdev->op->irq ( netdev, enable ); } /** * Get network device by name * * @v name Network device name * @ret netdev Network device, or NULL */ struct net_device * find_netdev ( const char *name ) { struct net_device *netdev; list_for_each_entry ( netdev, &net_devices, list ) { if ( strcmp ( netdev->name, name ) == 0 ) return netdev; } return NULL; } /** * Get network device by PCI bus:dev.fn address * * @v bus_type Bus type * @v location Bus location * @ret netdev Network device, or NULL */ struct net_device * find_netdev_by_location ( unsigned int bus_type, unsigned int location ) { struct net_device *netdev; list_for_each_entry ( netdev, &net_devices, list ) { if ( ( netdev->dev->desc.bus_type == bus_type ) && ( netdev->dev->desc.location == location ) ) return netdev; } return NULL; } /** * Get most recently opened network device * * @ret netdev Most recently opened network device, or NULL */ struct net_device * last_opened_netdev ( void ) { struct net_device *netdev; list_for_each_entry ( netdev, &open_net_devices, open_list ) { assert ( netdev->state & NETDEV_OPEN ); return netdev; } return NULL; } /** * Transmit network-layer packet * * @v iobuf I/O buffer * @v netdev Network device * @v net_protocol Network-layer protocol * @v ll_dest Destination link-layer address * @ret rc Return status code * * Prepends link-layer headers to the I/O buffer and transmits the * packet via the specified network device. This function takes * ownership of the I/O buffer. */ int net_tx ( struct io_buffer *iobuf, struct net_device *netdev, struct net_protocol *net_protocol, const void *ll_dest ) { struct ll_protocol *ll_protocol = netdev->ll_protocol; int rc; /* Force a poll on the netdevice to (potentially) clear any * backed-up TX completions. This is needed on some network * devices to avoid excessive losses due to small TX ring * sizes. */ netdev_poll ( netdev ); /* Add link-layer header */ if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest, netdev->ll_addr, net_protocol->net_proto ) ) != 0 ) { free_iob ( iobuf ); return rc; } /* Transmit packet */ return netdev_tx ( netdev, iobuf ); } /** * Process received network-layer packet * * @v iobuf I/O buffer * @v netdev Network device * @v net_proto Network-layer protocol, in network-byte order * @v ll_source Source link-layer address * @ret rc Return status code */ int net_rx ( struct io_buffer *iobuf, struct net_device *netdev, uint16_t net_proto, const void *ll_source ) { struct net_protocol *net_protocol; /* Hand off to network-layer protocol, if any */ for_each_table_entry ( net_protocol, NET_PROTOCOLS ) { if ( net_protocol->net_proto == net_proto ) return net_protocol->rx ( iobuf, netdev, ll_source ); } DBGC ( netdev, "NETDEV %p unknown network protocol %04x\n", netdev, ntohs ( net_proto ) ); free_iob ( iobuf ); return 0; } /** * Single-step the network stack * * @v process Network stack process * * This polls all interfaces for received packets, and processes * packets from the RX queue. */ static void net_step ( struct process *process __unused ) { struct net_device *netdev; struct io_buffer *iobuf; struct ll_protocol *ll_protocol; const void *ll_dest; const void *ll_source; uint16_t net_proto; int rc; /* Poll and process each network device */ list_for_each_entry ( netdev, &net_devices, list ) { /* Poll for new packets */ netdev_poll ( netdev ); /* Process at most one received packet. Give priority * to getting packets out of the NIC over processing * the received packets, because we advertise a window * that assumes that we can receive packets from the * NIC faster than they arrive. */ if ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) { DBGC ( netdev, "NETDEV %p processing %p (%p+%zx)\n", netdev, iobuf, iobuf->data, iob_len ( iobuf ) ); /* Remove link-layer header */ ll_protocol = netdev->ll_protocol; if ( ( rc = ll_protocol->pull ( netdev, iobuf, &ll_dest, &ll_source, &net_proto ) ) != 0 ) { free_iob ( iobuf ); continue; } net_rx ( iobuf, netdev, net_proto, ll_source ); } } } /** Networking stack process */ struct process net_process __permanent_process = { .list = LIST_HEAD_INIT ( net_process.list ), .step = net_step, }; debian/grub-extras/disabled/gpxe/Makefile.core.def0000664000000000000000000002525012524662415017304 0ustar AutoGen definitions Makefile.tpl; module = { name = gpxe; common = contrib/gpxe/wrap/wrap.c; common = contrib/gpxe/wrap/pci.c; common = contrib/gpxe/wrap/nic.c; common = contrib/gpxe/src/net/80211/net80211.c; common = contrib/gpxe/src/net/80211/rc80211.c; common = contrib/gpxe/src/net/arp.c; common = contrib/gpxe/src/net/dhcpopts.c; common = contrib/gpxe/src/net/dhcppkt.c; common = contrib/gpxe/src/net/ethernet.c; common = contrib/gpxe/src/net/fakedhcp.c; common = contrib/gpxe/src/net/icmp.c; common = contrib/gpxe/src/net/iobpad.c; common = contrib/gpxe/src/net/ipv4.c; common = contrib/gpxe/src/net/netdevice.c; common = contrib/gpxe/src/net/netdev_settings.c; common = contrib/gpxe/src/net/nullnet.c; common = contrib/gpxe/src/net/rarp.c; common = contrib/gpxe/src/net/retry.c; common = contrib/gpxe/src/net/tcp/http.c; common = contrib/gpxe/src/net/tcp.c; common = contrib/gpxe/src/net/tcpip.c; common = contrib/gpxe/src/net/udp/dhcp.c; common = contrib/gpxe/src/net/udp/dns.c; common = contrib/gpxe/src/net/udp/slam.c; common = contrib/gpxe/src/net/udp/tftp.c; common = contrib/gpxe/src/net/udp.c; common = contrib/gpxe/src/core/base64.c; common = contrib/gpxe/src/core/nvo.c; common = contrib/gpxe/src/core/uri.c; common = contrib/gpxe/src/core/uuid.c; common = contrib/gpxe/src/core/random.c; common = contrib/gpxe/src/core/open.c; common = contrib/gpxe/src/core/cwuri.c; common = contrib/gpxe/src/core/linebuf.c; common = contrib/gpxe/src/core/xfer.c; common = contrib/gpxe/src/core/settings.c; common = contrib/gpxe/src/core/iobuf.c; common = contrib/gpxe/src/core/refcnt.c; common = contrib/gpxe/src/core/bitmap.c; common = contrib/gpxe/src/core/process.c; common = contrib/gpxe/src/core/job.c; common = contrib/gpxe/src/core/resolv.c; common = contrib/gpxe/src/core/interface.c; common = contrib/gpxe/src/core/basename.c; common = contrib/gpxe/src/core/misc.c; common = contrib/gpxe/src/hci/strerror.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_infiniband; common = contrib/gpxe/src/net/infiniband/ib_cm.c; common = contrib/gpxe/src/net/infiniband/ib_cmrc.c; common = contrib/gpxe/src/net/infiniband/ib_mcast.c; common = contrib/gpxe/src/net/infiniband/ib_mi.c; common = contrib/gpxe/src/net/infiniband/ib_packet.c; common = contrib/gpxe/src/net/infiniband/ib_pathrec.c; common = contrib/gpxe/src/net/infiniband/ib_sma.c; common = contrib/gpxe/src/net/infiniband/ib_smc.c; common = contrib/gpxe/src/net/infiniband/ib_srp.c; common = contrib/gpxe/src/net/infiniband.c; common = contrib/gpxe/src/drivers/net/ipoib.c; common = contrib/gpxe/src/drivers/block/scsi.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_3c529; common = contrib/gpxe/src/drivers/net/3c529.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_3c595; common = contrib/gpxe/src/drivers/net/3c595.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_3c5x9; common = contrib/gpxe/src/drivers/net/3c5x9.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_3c90x; common = contrib/gpxe/src/drivers/net/3c90x.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_davicom; common = contrib/gpxe/src/drivers/net/davicom.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; #if 0 /* Not fixed for relocation yet. */ module = { name = gpxe_depca; common = contrib/gpxe/src/drivers/net/depca.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; #endif module = { name = gpxe_dmfe; common = contrib/gpxe/src/drivers/net/dmfe.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_eepro100; common = contrib/gpxe/src/drivers/net/eepro100.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_eepro; common = contrib/gpxe/src/drivers/net/eepro.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_epic100; common = contrib/gpxe/src/drivers/net/epic100.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_ipoib; common = contrib/gpxe/src/drivers/net/ipoib.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_legacy; common = contrib/gpxe/src/drivers/net/legacy.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_natsemi; common = contrib/gpxe/src/drivers/net/natsemi.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_ne2k_isa; common = contrib/gpxe/src/drivers/net/ne2k_isa.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_ns83820; common = contrib/gpxe/src/drivers/net/ns83820.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_ns8390; common = contrib/gpxe/src/drivers/net/ns8390.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_pnic; common = contrib/gpxe/src/drivers/net/pnic.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_rtl8139; common = contrib/gpxe/src/drivers/net/rtl8139.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_sis900; common = contrib/gpxe/src/drivers/net/sis900.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_smc9000; common = contrib/gpxe/src/drivers/net/smc9000.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_tulip; common = contrib/gpxe/src/drivers/net/tulip.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_w89c840; common = contrib/gpxe/src/drivers/net/w89c840.c; /* Fails to preprocess without -Os! */ cppflags = '$(GPXE_CPPFLAGS) -Os'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_nvs; common = contrib/gpxe/src/drivers/nvs/nvs.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_spi; common = contrib/gpxe/src/drivers/nvs/spi.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_threewire; common = contrib/gpxe/src/drivers/nvs/threewire.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_bitbash; common = contrib/gpxe/src/drivers/bitbash/bitbash.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_i2c_bit; common = contrib/gpxe/src/drivers/bitbash/i2c_bit.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_spi_bit; common = contrib/gpxe/src/drivers/bitbash/spi_bit.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; #if 0 /* Following ones require MII support which is GPLv2. */ module = { name = gpxe_amd8111e; common = contrib/gpxe/src/drivers/net/amd8111e.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_atl1e; common = contrib/gpxe/src/drivers/net/atl1e.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_b44; common = contrib/gpxe/src/drivers/net/b44.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_bnx2; common = contrib/gpxe/src/drivers/net/bnx2.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_etherfabric; common = contrib/gpxe/src/drivers/net/etherfabric.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_forcedeth; common = contrib/gpxe/src/drivers/net/forcedeth.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_pcnet32; common = contrib/gpxe/src/drivers/net/pcnet32.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_mtd80x; common = contrib/gpxe/src/drivers/net/mtd80x.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_r8169; common = contrib/gpxe/src/drivers/net/r8169.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_sundance; common = contrib/gpxe/src/drivers/net/sundance.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_tlan; common = contrib/gpxe/src/drivers/net/tlan.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; /* Following is wireless (disabled for now). */ module = { name = gpxe_prism2; common = contrib/gpxe/src/drivers/net/prism2.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_prism2_plx; common = contrib/gpxe/src/drivers/net/prism2_plx.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_ath5k; common = contrib/gpxe/src/drivers/net/ath5k/ath5k_attach.c; common = contrib/gpxe/src/drivers/net/ath5k/ath5k.c; common = contrib/gpxe/src/drivers/net/ath5k/ath5k_caps.c; common = contrib/gpxe/src/drivers/net/ath5k/ath5k_desc.c; common = contrib/gpxe/src/drivers/net/ath5k/ath5k_dma.c; common = contrib/gpxe/src/drivers/net/ath5k/ath5k_eeprom.c; common = contrib/gpxe/src/drivers/net/ath5k/ath5k_gpio.c; common = contrib/gpxe/src/drivers/net/ath5k/ath5k_initvals.c; common = contrib/gpxe/src/drivers/net/ath5k/ath5k_pcu.c; common = contrib/gpxe/src/drivers/net/ath5k/ath5k_phy.c; common = contrib/gpxe/src/drivers/net/ath5k/ath5k_qcu.c; common = contrib/gpxe/src/drivers/net/ath5k/ath5k_reset.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; /* Following require ISA/ISAPNP. Disable for now. */ module = { name = gpxe_3c509; common = contrib/gpxe/src/drivers/net/3c509.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = gpxe_3c515; common = contrib/gpxe/src/drivers/net/3c515.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; /* Following uses crypto. Disable for now. */ module = { name = https; common = contrib/gpxe/src/net/tcp/https.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = tls; common = contrib/gpxe/src/net/tls.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = aoe; common = contrib/gpxe/src/net/aoe.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; module = { name = iscsi; common = contrib/gpxe/src/net/tcp/iscsi.c; cppflags = '$(GPXE_CPPFLAGS)'; cflags = '$(GPXE_CFLAGS)'; }; #endif debian/grub-extras/lua/0000775000000000000000000000000012524676037012230 5ustar debian/grub-extras/lua/lua.h0000664000000000000000000002653112524662415013164 0ustar /* ** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $ ** Lua - An Extensible Extension Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file */ #ifndef lua_h #define lua_h #include #include #include "luaconf.h" #define LUA_VERSION "Lua 5.1" #define LUA_RELEASE "Lua 5.1.4" #define LUA_VERSION_NUM 501 #define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" /* mark for precompiled code (`Lua') */ #define LUA_SIGNATURE "\033Lua" /* option for multiple returns in `lua_pcall' and `lua_call' */ #define LUA_MULTRET (-1) /* ** pseudo-indices */ #define LUA_REGISTRYINDEX (-10000) #define LUA_ENVIRONINDEX (-10001) #define LUA_GLOBALSINDEX (-10002) #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) /* thread status; 0 is OK */ #define LUA_YIELD 1 #define LUA_ERRRUN 2 #define LUA_ERRSYNTAX 3 #define LUA_ERRMEM 4 #define LUA_ERRERR 5 typedef struct lua_State lua_State; typedef int (*lua_CFunction) (lua_State *L); /* ** functions that read/write blocks when loading/dumping Lua chunks */ typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); /* ** prototype for memory-allocation functions */ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); /* ** basic types */ #define LUA_TNONE (-1) #define LUA_TNIL 0 #define LUA_TBOOLEAN 1 #define LUA_TLIGHTUSERDATA 2 #define LUA_TNUMBER 3 #define LUA_TSTRING 4 #define LUA_TTABLE 5 #define LUA_TFUNCTION 6 #define LUA_TUSERDATA 7 #define LUA_TTHREAD 8 /* minimum Lua stack available to a C function */ #define LUA_MINSTACK 20 /* ** generic extra include file */ #if defined(LUA_USER_H) #include LUA_USER_H #endif /* type of numbers in Lua */ typedef LUA_NUMBER lua_Number; /* type for integer functions */ typedef LUA_INTEGER lua_Integer; /* ** state manipulation */ LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); LUA_API void (lua_close) (lua_State *L); LUA_API lua_State *(lua_newthread) (lua_State *L); LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); /* ** basic stack manipulation */ LUA_API int (lua_gettop) (lua_State *L); LUA_API void (lua_settop) (lua_State *L, int idx); LUA_API void (lua_pushvalue) (lua_State *L, int idx); LUA_API void (lua_remove) (lua_State *L, int idx); LUA_API void (lua_insert) (lua_State *L, int idx); LUA_API void (lua_replace) (lua_State *L, int idx); LUA_API int (lua_checkstack) (lua_State *L, int sz); LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); /* ** access functions (stack -> C) */ LUA_API int (lua_isnumber) (lua_State *L, int idx); LUA_API int (lua_isstring) (lua_State *L, int idx); LUA_API int (lua_iscfunction) (lua_State *L, int idx); LUA_API int (lua_isuserdata) (lua_State *L, int idx); LUA_API int (lua_type) (lua_State *L, int idx); LUA_API const char *(lua_typename) (lua_State *L, int tp); LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); LUA_API int (lua_toboolean) (lua_State *L, int idx); LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); LUA_API size_t (lua_objlen) (lua_State *L, int idx); LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); LUA_API void *(lua_touserdata) (lua_State *L, int idx); LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); LUA_API const void *(lua_topointer) (lua_State *L, int idx); /* ** push functions (C -> stack) */ LUA_API void (lua_pushnil) (lua_State *L); LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); LUA_API void (lua_pushstring) (lua_State *L, const char *s); LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, va_list argp); LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); LUA_API void (lua_pushboolean) (lua_State *L, int b); LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); LUA_API int (lua_pushthread) (lua_State *L); /* ** get functions (Lua -> stack) */ LUA_API void (lua_gettable) (lua_State *L, int idx); LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); LUA_API void (lua_rawget) (lua_State *L, int idx); LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); LUA_API int (lua_getmetatable) (lua_State *L, int objindex); LUA_API void (lua_getfenv) (lua_State *L, int idx); /* ** set functions (stack -> Lua) */ LUA_API void (lua_settable) (lua_State *L, int idx); LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); LUA_API void (lua_rawset) (lua_State *L, int idx); LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); LUA_API int (lua_setmetatable) (lua_State *L, int objindex); LUA_API int (lua_setfenv) (lua_State *L, int idx); /* ** `load' and `call' functions (load and run Lua code) */ LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, const char *chunkname); LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); /* ** coroutine functions */ LUA_API int (lua_yield) (lua_State *L, int nresults); LUA_API int (lua_resume) (lua_State *L, int narg); LUA_API int (lua_status) (lua_State *L); /* ** garbage-collection function and options */ #define LUA_GCSTOP 0 #define LUA_GCRESTART 1 #define LUA_GCCOLLECT 2 #define LUA_GCCOUNT 3 #define LUA_GCCOUNTB 4 #define LUA_GCSTEP 5 #define LUA_GCSETPAUSE 6 #define LUA_GCSETSTEPMUL 7 LUA_API int (lua_gc) (lua_State *L, int what, int data); /* ** miscellaneous functions */ LUA_API int (lua_error) (lua_State *L); LUA_API int (lua_next) (lua_State *L, int idx); LUA_API void (lua_concat) (lua_State *L, int n); LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); /* ** =============================================================== ** some useful macros ** =============================================================== */ #define lua_pop(L,n) lua_settop(L, -(n)-1) #define lua_newtable(L) lua_createtable(L, 0, 0) #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) #define lua_strlen(L,i) lua_objlen(L, (i)) #define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) #define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) #define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) #define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) #define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) #define lua_pushliteral(L, s) \ lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) #define lua_tostring(L,i) lua_tolstring(L, (i), NULL) /* ** compatibility macros and functions */ #define lua_open() luaL_newstate() #define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) #define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) #define lua_Chunkreader lua_Reader #define lua_Chunkwriter lua_Writer /* hack */ LUA_API void lua_setlevel (lua_State *from, lua_State *to); /* ** {====================================================================== ** Debug API ** ======================================================================= */ /* ** Event codes */ #define LUA_HOOKCALL 0 #define LUA_HOOKRET 1 #define LUA_HOOKLINE 2 #define LUA_HOOKCOUNT 3 #define LUA_HOOKTAILRET 4 /* ** Event masks */ #define LUA_MASKCALL (1 << LUA_HOOKCALL) #define LUA_MASKRET (1 << LUA_HOOKRET) #define LUA_MASKLINE (1 << LUA_HOOKLINE) #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) typedef struct lua_Debug lua_Debug; /* activation record */ /* Functions to be called by the debuger in specific events */ typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); LUA_API lua_Hook lua_gethook (lua_State *L); LUA_API int lua_gethookmask (lua_State *L); LUA_API int lua_gethookcount (lua_State *L); struct lua_Debug { int event; const char *name; /* (n) */ const char *namewhat; /* (n) `global', `local', `field', `method' */ const char *what; /* (S) `Lua', `C', `main', `tail' */ const char *source; /* (S) */ int currentline; /* (l) */ int nups; /* (u) number of upvalues */ int linedefined; /* (S) */ int lastlinedefined; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ int i_ci; /* active function */ }; /* }====================================================================== */ /****************************************************************************** * Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ #endif debian/grub-extras/lua/lparser.h0000664000000000000000000000432512524662415014050 0ustar /* ** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ #ifndef lparser_h #define lparser_h #include "llimits.h" #include "lobject.h" #include "lzio.h" /* ** Expression descriptor */ typedef enum { VVOID, /* no value */ VNIL, VTRUE, VFALSE, VK, /* info = index of constant in `k' */ VKNUM, /* nval = numerical value */ VLOCAL, /* info = local register */ VUPVAL, /* info = index of upvalue in `upvalues' */ VGLOBAL, /* info = index of table; aux = index of global name in `k' */ VINDEXED, /* info = table register; aux = index register (or `k') */ VJMP, /* info = instruction pc */ VRELOCABLE, /* info = instruction pc */ VNONRELOC, /* info = result register */ VCALL, /* info = instruction pc */ VVARARG /* info = instruction pc */ } expkind; typedef struct expdesc { expkind k; union { struct { int info, aux; } s; lua_Number nval; } u; int t; /* patch list of `exit when true' */ int f; /* patch list of `exit when false' */ } expdesc; typedef struct upvaldesc { lu_byte k; lu_byte info; } upvaldesc; struct BlockCnt; /* defined in lparser.c */ /* state needed to generate code for a given function */ typedef struct FuncState { Proto *f; /* current function header */ Table *h; /* table to find (and reuse) elements in `k' */ struct FuncState *prev; /* enclosing function */ struct LexState *ls; /* lexical state */ struct lua_State *L; /* copy of the Lua state */ struct BlockCnt *bl; /* chain of current blocks */ int pc; /* next position to code (equivalent to `ncode') */ int lasttarget; /* `pc' of last `jump target' */ int jpc; /* list of pending jumps to `pc' */ int freereg; /* first free register */ int nk; /* number of elements in `k' */ int np; /* number of elements in `p' */ short nlocvars; /* number of elements in `locvars' */ lu_byte nactvar; /* number of active local variables */ upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ } FuncState; LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name); #endif debian/grub-extras/lua/lfunc.c0000664000000000000000000001101212524662415013471 0ustar /* ** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ #include #define lfunc_c #define LUA_CORE #include "lua.h" #include "lfunc.h" #include "lgc.h" #include "lmem.h" #include "lobject.h" #include "lstate.h" Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); luaC_link(L, obj2gco(c), LUA_TFUNCTION); c->c.isC = 1; c->c.env = e; c->c.nupvalues = cast_byte(nelems); return c; } Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); luaC_link(L, obj2gco(c), LUA_TFUNCTION); c->l.isC = 0; c->l.env = e; c->l.nupvalues = cast_byte(nelems); while (nelems--) c->l.upvals[nelems] = NULL; return c; } UpVal *luaF_newupval (lua_State *L) { UpVal *uv = luaM_new(L, UpVal); luaC_link(L, obj2gco(uv), LUA_TUPVAL); uv->v = &uv->u.value; setnilvalue(uv->v); return uv; } UpVal *luaF_findupval (lua_State *L, StkId level) { global_State *g = G(L); GCObject **pp = &L->openupval; UpVal *p; UpVal *uv; while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { lua_assert(p->v != &p->u.value); if (p->v == level) { /* found a corresponding upvalue? */ if (isdead(g, obj2gco(p))) /* is it dead? */ changewhite(obj2gco(p)); /* ressurect it */ return p; } pp = &p->next; } uv = luaM_new(L, UpVal); /* not found: create a new one */ uv->tt = LUA_TUPVAL; uv->marked = luaC_white(g); uv->v = level; /* current value lives in the stack */ uv->next = *pp; /* chain it in the proper position */ *pp = obj2gco(uv); uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ uv->u.l.next = g->uvhead.u.l.next; uv->u.l.next->u.l.prev = uv; g->uvhead.u.l.next = uv; lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); return uv; } static void unlinkupval (UpVal *uv) { lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ uv->u.l.prev->u.l.next = uv->u.l.next; } void luaF_freeupval (lua_State *L, UpVal *uv) { if (uv->v != &uv->u.value) /* is it open? */ unlinkupval(uv); /* remove from open list */ luaM_free(L, uv); /* free upvalue */ } void luaF_close (lua_State *L, StkId level) { UpVal *uv; global_State *g = G(L); while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { GCObject *o = obj2gco(uv); lua_assert(!isblack(o) && uv->v != &uv->u.value); L->openupval = uv->next; /* remove from `open' list */ if (isdead(g, o)) luaF_freeupval(L, uv); /* free upvalue */ else { unlinkupval(uv); setobj(L, &uv->u.value, uv->v); uv->v = &uv->u.value; /* now current value lives here */ luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ } } } Proto *luaF_newproto (lua_State *L) { Proto *f = luaM_new(L, Proto); luaC_link(L, obj2gco(f), LUA_TPROTO); f->k = NULL; f->sizek = 0; f->p = NULL; f->sizep = 0; f->code = NULL; f->sizecode = 0; f->sizelineinfo = 0; f->sizeupvalues = 0; f->nups = 0; f->upvalues = NULL; f->numparams = 0; f->is_vararg = 0; f->maxstacksize = 0; f->lineinfo = NULL; f->sizelocvars = 0; f->locvars = NULL; f->linedefined = 0; f->lastlinedefined = 0; f->source = NULL; return f; } void luaF_freeproto (lua_State *L, Proto *f) { luaM_freearray(L, f->code, f->sizecode, Instruction); luaM_freearray(L, f->p, f->sizep, Proto *); luaM_freearray(L, f->k, f->sizek, TValue); luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); luaM_free(L, f); } void luaF_freeclosure (lua_State *L, Closure *c) { int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : sizeLclosure(c->l.nupvalues); luaM_freemem(L, c, size); } /* ** Look for n-th local variable at line `line' in function `func'. ** Returns NULL if not found. */ const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { int i; for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { if (pc < f->locvars[i].endpc) { /* is variable active? */ local_number--; if (local_number == 0) return getstr(f->locvars[i].varname); } } return NULL; /* not found */ } debian/grub-extras/lua/lbaselib.c0000664000000000000000000004124012524662415014145 0ustar /* ** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ #if 0 #include #include #include #include #endif #define lbaselib_c #define LUA_LIB #include "lua.h" #include "lauxlib.h" #include "lualib.h" /* ** If your system does not support `stdout', you can just remove this function. ** If you need, you can define your own `print' function, following this ** model but changing `fputs' to put the strings at a proper place ** (a console window or a log file, for instance). */ static int luaB_print (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ int i; lua_getglobal(L, "tostring"); for (i=1; i<=n; i++) { const char *s; lua_pushvalue(L, -1); /* function to be called */ lua_pushvalue(L, i); /* value to print */ lua_call(L, 1, 1); s = lua_tostring(L, -1); /* get result */ if (s == NULL) return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("print")); if (i>1) fputs("\t", stdout); fputs(s, stdout); lua_pop(L, 1); /* pop result */ } fputs("\n", stdout); return 0; } static int luaB_tonumber (lua_State *L) { int base = luaL_optint(L, 2, 10); if (base == 10) { /* standard conversion */ luaL_checkany(L, 1); if (lua_isnumber(L, 1)) { lua_pushnumber(L, lua_tonumber(L, 1)); return 1; } } else { const char *s1 = luaL_checkstring(L, 1); char *s2; unsigned long n; luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); n = strtoul(s1, &s2, base); if (s1 != s2) { /* at least one valid digit? */ while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ if (*s2 == '\0') { /* no invalid trailing characters? */ lua_pushnumber(L, (lua_Number)n); return 1; } } } lua_pushnil(L); /* else not a number */ return 1; } static int luaB_error (lua_State *L) { int level = luaL_optint(L, 2, 1); lua_settop(L, 1); if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ luaL_where(L, level); lua_pushvalue(L, 1); lua_concat(L, 2); } return lua_error(L); } static int luaB_getmetatable (lua_State *L) { luaL_checkany(L, 1); if (!lua_getmetatable(L, 1)) { lua_pushnil(L); return 1; /* no metatable */ } luaL_getmetafield(L, 1, "__metatable"); return 1; /* returns either __metatable field (if present) or metatable */ } static int luaB_setmetatable (lua_State *L) { int t = lua_type(L, 2); luaL_checktype(L, 1, LUA_TTABLE); luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table expected"); if (luaL_getmetafield(L, 1, "__metatable")) luaL_error(L, "cannot change a protected metatable"); lua_settop(L, 2); lua_setmetatable(L, 1); return 1; } static void getfunc (lua_State *L, int opt) { if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); else { lua_Debug ar; int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); if (lua_getstack(L, level, &ar) == 0) luaL_argerror(L, 1, "invalid level"); lua_getinfo(L, "f", &ar); if (lua_isnil(L, -1)) luaL_error(L, "no function environment for tail call at level %d", level); } } static int luaB_getfenv (lua_State *L) { getfunc(L, 1); if (lua_iscfunction(L, -1)) /* is a C function? */ lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ else lua_getfenv(L, -1); return 1; } static int luaB_setfenv (lua_State *L) { luaL_checktype(L, 2, LUA_TTABLE); getfunc(L, 0); lua_pushvalue(L, 2); if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { /* change environment of current thread */ lua_pushthread(L); lua_insert(L, -2); lua_setfenv(L, -2); return 0; } else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) luaL_error(L, LUA_QL("setfenv") " cannot change environment of given object"); return 1; } static int luaB_rawequal (lua_State *L) { luaL_checkany(L, 1); luaL_checkany(L, 2); lua_pushboolean(L, lua_rawequal(L, 1, 2)); return 1; } static int luaB_rawget (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checkany(L, 2); lua_settop(L, 2); lua_rawget(L, 1); return 1; } static int luaB_rawset (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checkany(L, 2); luaL_checkany(L, 3); lua_settop(L, 3); lua_rawset(L, 1); return 1; } static int luaB_gcinfo (lua_State *L) { lua_pushinteger(L, lua_getgccount(L)); return 1; } static int luaB_collectgarbage (lua_State *L) { static const char *const opts[] = {"stop", "restart", "collect", "count", "step", "setpause", "setstepmul", NULL}; static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL}; int o = luaL_checkoption(L, 1, "collect", opts); int ex = luaL_optint(L, 2, 0); int res = lua_gc(L, optsnum[o], ex); switch (optsnum[o]) { case LUA_GCCOUNT: { int b = lua_gc(L, LUA_GCCOUNTB, 0); lua_pushnumber(L, res + ((lua_Number)b/1024)); return 1; } case LUA_GCSTEP: { lua_pushboolean(L, res); return 1; } default: { lua_pushnumber(L, res); return 1; } } } static int luaB_type (lua_State *L) { luaL_checkany(L, 1); lua_pushstring(L, luaL_typename(L, 1)); return 1; } static int luaB_next (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 2); /* create a 2nd argument if there isn't one */ if (lua_next(L, 1)) return 2; else { lua_pushnil(L); return 1; } } static int luaB_pairs (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ lua_pushvalue(L, 1); /* state, */ lua_pushnil(L); /* and initial value */ return 3; } static int ipairsaux (lua_State *L) { int i = luaL_checkint(L, 2); luaL_checktype(L, 1, LUA_TTABLE); i++; /* next value */ lua_pushinteger(L, i); lua_rawgeti(L, 1, i); return (lua_isnil(L, -1)) ? 0 : 2; } static int luaB_ipairs (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ lua_pushvalue(L, 1); /* state, */ lua_pushinteger(L, 0); /* and initial value */ return 3; } static int load_aux (lua_State *L, int status) { if (status == 0) /* OK? */ return 1; else { lua_pushnil(L); lua_insert(L, -2); /* put before error message */ return 2; /* return nil plus error message */ } } static int luaB_loadstring (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); const char *chunkname = luaL_optstring(L, 2, s); return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); } static int luaB_loadfile (lua_State *L) { const char *fname = luaL_optstring(L, 1, NULL); return load_aux(L, luaL_loadfile(L, fname)); } /* ** Reader for generic `load' function: `lua_load' uses the ** stack for internal stuff, so the reader cannot change the ** stack top. Instead, it keeps its resulting string in a ** reserved slot inside the stack. */ static const char *generic_reader (lua_State *L, void *ud, size_t *size) { (void)ud; /* to avoid warnings */ luaL_checkstack(L, 2, "too many nested functions"); lua_pushvalue(L, 1); /* get function */ lua_call(L, 0, 1); /* call it */ if (lua_isnil(L, -1)) { *size = 0; return NULL; } else if (lua_isstring(L, -1)) { lua_replace(L, 3); /* save string in a reserved stack slot */ return lua_tolstring(L, 3, size); } else luaL_error(L, "reader function must return a string"); return NULL; /* to avoid warnings */ } static int luaB_load (lua_State *L) { int status; const char *cname = luaL_optstring(L, 2, "=(load)"); luaL_checktype(L, 1, LUA_TFUNCTION); lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ status = lua_load(L, generic_reader, NULL, cname); return load_aux(L, status); } static int luaB_dofile (lua_State *L) { const char *fname = luaL_optstring(L, 1, NULL); int n = lua_gettop(L); if (luaL_loadfile(L, fname) != 0) lua_error(L); lua_call(L, 0, LUA_MULTRET); return lua_gettop(L) - n; } static int luaB_assert (lua_State *L) { luaL_checkany(L, 1); if (!lua_toboolean(L, 1)) return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); return lua_gettop(L); } static int luaB_unpack (lua_State *L) { int i, e, n; luaL_checktype(L, 1, LUA_TTABLE); i = luaL_optint(L, 2, 1); e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); if (i > e) return 0; /* empty range */ n = e - i + 1; /* number of elements */ if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ return luaL_error(L, "too many results to unpack"); lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ while (i++ < e) /* push arg[i + 1...e] */ lua_rawgeti(L, 1, i); return n; } static int luaB_select (lua_State *L) { int n = lua_gettop(L); if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { lua_pushinteger(L, n-1); return 1; } else { int i = luaL_checkint(L, 1); if (i < 0) i = n + i; else if (i > n) i = n; luaL_argcheck(L, 1 <= i, 1, "index out of range"); return n - i; } } static int luaB_pcall (lua_State *L) { int status; luaL_checkany(L, 1); status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); lua_pushboolean(L, (status == 0)); lua_insert(L, 1); return lua_gettop(L); /* return status + all results */ } static int luaB_xpcall (lua_State *L) { int status; luaL_checkany(L, 2); lua_settop(L, 2); lua_insert(L, 1); /* put error function under function to be called */ status = lua_pcall(L, 0, LUA_MULTRET, 1); lua_pushboolean(L, (status == 0)); lua_replace(L, 1); return lua_gettop(L); /* return status + all results */ } static int luaB_tostring (lua_State *L) { luaL_checkany(L, 1); if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ return 1; /* use its value */ switch (lua_type(L, 1)) { case LUA_TNUMBER: lua_pushstring(L, lua_tostring(L, 1)); break; case LUA_TSTRING: lua_pushvalue(L, 1); break; case LUA_TBOOLEAN: lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); break; case LUA_TNIL: lua_pushliteral(L, "nil"); break; default: lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); break; } return 1; } static int luaB_newproxy (lua_State *L) { lua_settop(L, 1); lua_newuserdata(L, 0); /* create proxy */ if (lua_toboolean(L, 1) == 0) return 1; /* no metatable */ else if (lua_isboolean(L, 1)) { lua_newtable(L); /* create a new metatable `m' ... */ lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ lua_pushboolean(L, 1); lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ } else { int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ if (lua_getmetatable(L, 1)) { lua_rawget(L, lua_upvalueindex(1)); validproxy = lua_toboolean(L, -1); lua_pop(L, 1); /* remove value */ } luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); lua_getmetatable(L, 1); /* metatable is valid; get it */ } lua_setmetatable(L, 2); return 1; } static const luaL_Reg base_funcs[] = { {"assert", luaB_assert}, {"collectgarbage", luaB_collectgarbage}, {"dofile", luaB_dofile}, {"error", luaB_error}, {"gcinfo", luaB_gcinfo}, {"getfenv", luaB_getfenv}, {"getmetatable", luaB_getmetatable}, {"loadfile", luaB_loadfile}, {"load", luaB_load}, {"loadstring", luaB_loadstring}, {"next", luaB_next}, {"pcall", luaB_pcall}, {"print", luaB_print}, {"rawequal", luaB_rawequal}, {"rawget", luaB_rawget}, {"rawset", luaB_rawset}, {"select", luaB_select}, {"setfenv", luaB_setfenv}, {"setmetatable", luaB_setmetatable}, {"tonumber", luaB_tonumber}, {"tostring", luaB_tostring}, {"type", luaB_type}, {"unpack", luaB_unpack}, {"xpcall", luaB_xpcall}, {NULL, NULL} }; /* ** {====================================================== ** Coroutine library ** ======================================================= */ #define CO_RUN 0 /* running */ #define CO_SUS 1 /* suspended */ #define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ #define CO_DEAD 3 static const char *const statnames[] = {"running", "suspended", "normal", "dead"}; static int costatus (lua_State *L, lua_State *co) { if (L == co) return CO_RUN; switch (lua_status(co)) { case LUA_YIELD: return CO_SUS; case 0: { lua_Debug ar; if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ return CO_NOR; /* it is running */ else if (lua_gettop(co) == 0) return CO_DEAD; else return CO_SUS; /* initial state */ } default: /* some error occured */ return CO_DEAD; } } static int luaB_costatus (lua_State *L) { lua_State *co = lua_tothread(L, 1); luaL_argcheck(L, co, 1, "coroutine expected"); lua_pushstring(L, statnames[costatus(L, co)]); return 1; } static int auxresume (lua_State *L, lua_State *co, int narg) { int status = costatus(L, co); if (!lua_checkstack(co, narg)) luaL_error(L, "too many arguments to resume"); if (status != CO_SUS) { lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); return -1; /* error flag */ } lua_xmove(L, co, narg); lua_setlevel(L, co); status = lua_resume(co, narg); if (status == 0 || status == LUA_YIELD) { int nres = lua_gettop(co); if (!lua_checkstack(L, nres + 1)) luaL_error(L, "too many results to resume"); lua_xmove(co, L, nres); /* move yielded values */ return nres; } else { lua_xmove(co, L, 1); /* move error message */ return -1; /* error flag */ } } static int luaB_coresume (lua_State *L) { lua_State *co = lua_tothread(L, 1); int r; luaL_argcheck(L, co, 1, "coroutine expected"); r = auxresume(L, co, lua_gettop(L) - 1); if (r < 0) { lua_pushboolean(L, 0); lua_insert(L, -2); return 2; /* return false + error message */ } else { lua_pushboolean(L, 1); lua_insert(L, -(r + 1)); return r + 1; /* return true + `resume' returns */ } } static int luaB_auxwrap (lua_State *L) { lua_State *co = lua_tothread(L, lua_upvalueindex(1)); int r = auxresume(L, co, lua_gettop(L)); if (r < 0) { if (lua_isstring(L, -1)) { /* error object is a string? */ luaL_where(L, 1); /* add extra info */ lua_insert(L, -2); lua_concat(L, 2); } lua_error(L); /* propagate error */ } return r; } static int luaB_cocreate (lua_State *L) { lua_State *NL = lua_newthread(L); luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, "Lua function expected"); lua_pushvalue(L, 1); /* move function to top */ lua_xmove(L, NL, 1); /* move function from L to NL */ return 1; } static int luaB_cowrap (lua_State *L) { luaB_cocreate(L); lua_pushcclosure(L, luaB_auxwrap, 1); return 1; } static int luaB_yield (lua_State *L) { return lua_yield(L, lua_gettop(L)); } static int luaB_corunning (lua_State *L) { if (lua_pushthread(L)) lua_pushnil(L); /* main thread is not a coroutine */ return 1; } static const luaL_Reg co_funcs[] = { {"create", luaB_cocreate}, {"resume", luaB_coresume}, {"running", luaB_corunning}, {"status", luaB_costatus}, {"wrap", luaB_cowrap}, {"yield", luaB_yield}, {NULL, NULL} }; /* }====================================================== */ static void auxopen (lua_State *L, const char *name, lua_CFunction f, lua_CFunction u) { lua_pushcfunction(L, u); lua_pushcclosure(L, f, 1); lua_setfield(L, -2, name); } static void base_open (lua_State *L) { /* set global _G */ lua_pushvalue(L, LUA_GLOBALSINDEX); lua_setglobal(L, "_G"); /* open lib into global table */ luaL_register(L, "_G", base_funcs); lua_pushliteral(L, LUA_VERSION); lua_setglobal(L, "_VERSION"); /* set global _VERSION */ /* `ipairs' and `pairs' need auxliliary functions as upvalues */ auxopen(L, "ipairs", luaB_ipairs, ipairsaux); auxopen(L, "pairs", luaB_pairs, luaB_next); /* `newproxy' needs a weaktable as upvalue */ lua_createtable(L, 0, 1); /* new table `w' */ lua_pushvalue(L, -1); /* `w' will be its own metatable */ lua_setmetatable(L, -2); lua_pushliteral(L, "kv"); lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ lua_pushcclosure(L, luaB_newproxy, 1); lua_setglobal(L, "newproxy"); /* set global `newproxy' */ } LUALIB_API int luaopen_base (lua_State *L) { base_open(L); luaL_register(L, LUA_COLIBNAME, co_funcs); return 2; } debian/grub-extras/lua/ldblib.c0000664000000000000000000002353512524662415013627 0ustar /* ** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ #if 0 #include #include #include #endif #define ldblib_c #define LUA_LIB #include "lua.h" #include "lauxlib.h" #include "lualib.h" static int db_getregistry (lua_State *L) { lua_pushvalue(L, LUA_REGISTRYINDEX); return 1; } static int db_getmetatable (lua_State *L) { luaL_checkany(L, 1); if (!lua_getmetatable(L, 1)) { lua_pushnil(L); /* no metatable */ } return 1; } static int db_setmetatable (lua_State *L) { int t = lua_type(L, 2); luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table expected"); lua_settop(L, 2); lua_pushboolean(L, lua_setmetatable(L, 1)); return 1; } static int db_getfenv (lua_State *L) { lua_getfenv(L, 1); return 1; } static int db_setfenv (lua_State *L) { luaL_checktype(L, 2, LUA_TTABLE); lua_settop(L, 2); if (lua_setfenv(L, 1) == 0) luaL_error(L, LUA_QL("setfenv") " cannot change environment of given object"); return 1; } static void settabss (lua_State *L, const char *i, const char *v) { lua_pushstring(L, v); lua_setfield(L, -2, i); } static void settabsi (lua_State *L, const char *i, int v) { lua_pushinteger(L, v); lua_setfield(L, -2, i); } static lua_State *getthread (lua_State *L, int *arg) { if (lua_isthread(L, 1)) { *arg = 1; return lua_tothread(L, 1); } else { *arg = 0; return L; } } static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { if (L == L1) { lua_pushvalue(L, -2); lua_remove(L, -3); } else lua_xmove(L1, L, 1); lua_setfield(L, -2, fname); } static int db_getinfo (lua_State *L) { lua_Debug ar; int arg; lua_State *L1 = getthread(L, &arg); const char *options = luaL_optstring(L, arg+2, "flnSu"); if (lua_isnumber(L, arg+1)) { if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { lua_pushnil(L); /* level out of range */ return 1; } } else if (lua_isfunction(L, arg+1)) { lua_pushfstring(L, ">%s", options); options = lua_tostring(L, -1); lua_pushvalue(L, arg+1); lua_xmove(L, L1, 1); } else return luaL_argerror(L, arg+1, "function or level expected"); if (!lua_getinfo(L1, options, &ar)) return luaL_argerror(L, arg+2, "invalid option"); lua_createtable(L, 0, 2); if (strchr(options, 'S')) { settabss(L, "source", ar.source); settabss(L, "short_src", ar.short_src); settabsi(L, "linedefined", ar.linedefined); settabsi(L, "lastlinedefined", ar.lastlinedefined); settabss(L, "what", ar.what); } if (strchr(options, 'l')) settabsi(L, "currentline", ar.currentline); if (strchr(options, 'u')) settabsi(L, "nups", ar.nups); if (strchr(options, 'n')) { settabss(L, "name", ar.name); settabss(L, "namewhat", ar.namewhat); } if (strchr(options, 'L')) treatstackoption(L, L1, "activelines"); if (strchr(options, 'f')) treatstackoption(L, L1, "func"); return 1; /* return table */ } static int db_getlocal (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); lua_Debug ar; const char *name; if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ return luaL_argerror(L, arg+1, "level out of range"); name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); if (name) { lua_xmove(L1, L, 1); lua_pushstring(L, name); lua_pushvalue(L, -2); return 2; } else { lua_pushnil(L); return 1; } } static int db_setlocal (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); lua_Debug ar; if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ return luaL_argerror(L, arg+1, "level out of range"); luaL_checkany(L, arg+3); lua_settop(L, arg+3); lua_xmove(L, L1, 1); lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); return 1; } static int auxupvalue (lua_State *L, int get) { const char *name; int n = luaL_checkint(L, 2); luaL_checktype(L, 1, LUA_TFUNCTION); if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); if (name == NULL) return 0; lua_pushstring(L, name); lua_insert(L, -(get+1)); return get + 1; } static int db_getupvalue (lua_State *L) { return auxupvalue(L, 1); } static int db_setupvalue (lua_State *L) { luaL_checkany(L, 3); return auxupvalue(L, 0); } static const char KEY_HOOK = 'h'; static void hookf (lua_State *L, lua_Debug *ar) { static const char *const hooknames[] = {"call", "return", "line", "count", "tail return"}; lua_pushlightuserdata(L, (void *)&KEY_HOOK); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushlightuserdata(L, L); lua_rawget(L, -2); if (lua_isfunction(L, -1)) { lua_pushstring(L, hooknames[(int)ar->event]); if (ar->currentline >= 0) lua_pushinteger(L, ar->currentline); else lua_pushnil(L); lua_assert(lua_getinfo(L, "lS", ar)); lua_call(L, 2, 0); } } static int makemask (const char *smask, int count) { int mask = 0; if (strchr(smask, 'c')) mask |= LUA_MASKCALL; if (strchr(smask, 'r')) mask |= LUA_MASKRET; if (strchr(smask, 'l')) mask |= LUA_MASKLINE; if (count > 0) mask |= LUA_MASKCOUNT; return mask; } static char *unmakemask (int mask, char *smask) { int i = 0; if (mask & LUA_MASKCALL) smask[i++] = 'c'; if (mask & LUA_MASKRET) smask[i++] = 'r'; if (mask & LUA_MASKLINE) smask[i++] = 'l'; smask[i] = '\0'; return smask; } static void gethooktable (lua_State *L) { lua_pushlightuserdata(L, (void *)&KEY_HOOK); lua_rawget(L, LUA_REGISTRYINDEX); if (!lua_istable(L, -1)) { lua_pop(L, 1); lua_createtable(L, 0, 1); lua_pushlightuserdata(L, (void *)&KEY_HOOK); lua_pushvalue(L, -2); lua_rawset(L, LUA_REGISTRYINDEX); } } static int db_sethook (lua_State *L) { int arg, mask, count; lua_Hook func; lua_State *L1 = getthread(L, &arg); if (lua_isnoneornil(L, arg+1)) { lua_settop(L, arg+1); func = NULL; mask = 0; count = 0; /* turn off hooks */ } else { const char *smask = luaL_checkstring(L, arg+2); luaL_checktype(L, arg+1, LUA_TFUNCTION); count = luaL_optint(L, arg+3, 0); func = hookf; mask = makemask(smask, count); } gethooktable(L); lua_pushlightuserdata(L, L1); lua_pushvalue(L, arg+1); lua_rawset(L, -3); /* set new hook */ lua_pop(L, 1); /* remove hook table */ lua_sethook(L1, func, mask, count); /* set hooks */ return 0; } static int db_gethook (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); char buff[5]; int mask = lua_gethookmask(L1); lua_Hook hook = lua_gethook(L1); if (hook != NULL && hook != hookf) /* external hook? */ lua_pushliteral(L, "external hook"); else { gethooktable(L); lua_pushlightuserdata(L, L1); lua_rawget(L, -2); /* get hook */ lua_remove(L, -2); /* remove hook table */ } lua_pushstring(L, unmakemask(mask, buff)); lua_pushinteger(L, lua_gethookcount(L1)); return 3; } static int db_debug (lua_State *L) { for (;;) { char buffer[250]; fputs("lua_debug> ", stderr); if (fgets(buffer, sizeof(buffer), stdin) == 0 || strcmp(buffer, "cont\n") == 0) return 0; if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || lua_pcall(L, 0, 0, 0)) { fputs(lua_tostring(L, -1), stderr); fputs("\n", stderr); } lua_settop(L, 0); /* remove eventual returns */ } } #define LEVELS1 12 /* size of the first part of the stack */ #define LEVELS2 10 /* size of the second part of the stack */ static int db_errorfb (lua_State *L) { int level; int firstpart = 1; /* still before eventual `...' */ int arg; lua_State *L1 = getthread(L, &arg); lua_Debug ar; if (lua_isnumber(L, arg+2)) { level = (int)lua_tointeger(L, arg+2); lua_pop(L, 1); } else level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ if (lua_gettop(L) == arg) lua_pushliteral(L, ""); else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ else lua_pushliteral(L, "\n"); lua_pushliteral(L, "stack traceback:"); while (lua_getstack(L1, level++, &ar)) { if (level > LEVELS1 && firstpart) { /* no more than `LEVELS2' more levels? */ if (!lua_getstack(L1, level+LEVELS2, &ar)) level--; /* keep going */ else { lua_pushliteral(L, "\n\t..."); /* too many levels */ while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ level++; } firstpart = 0; continue; } lua_pushliteral(L, "\n\t"); lua_getinfo(L1, "Snl", &ar); lua_pushfstring(L, "%s:", ar.short_src); if (ar.currentline > 0) lua_pushfstring(L, "%d:", ar.currentline); if (*ar.namewhat != '\0') /* is there a name? */ lua_pushfstring(L, " in function " LUA_QS, ar.name); else { if (*ar.what == 'm') /* main? */ lua_pushfstring(L, " in main chunk"); else if (*ar.what == 'C' || *ar.what == 't') lua_pushliteral(L, " ?"); /* C function or tail call */ else lua_pushfstring(L, " in function <%s:%d>", ar.short_src, ar.linedefined); } lua_concat(L, lua_gettop(L) - arg); } lua_concat(L, lua_gettop(L) - arg); return 1; } static const luaL_Reg dblib[] = { {"debug", db_debug}, {"getfenv", db_getfenv}, {"gethook", db_gethook}, {"getinfo", db_getinfo}, {"getlocal", db_getlocal}, {"getregistry", db_getregistry}, {"getmetatable", db_getmetatable}, {"getupvalue", db_getupvalue}, {"setfenv", db_setfenv}, {"sethook", db_sethook}, {"setlocal", db_setlocal}, {"setmetatable", db_setmetatable}, {"setupvalue", db_setupvalue}, {"traceback", db_errorfb}, {NULL, NULL} }; LUALIB_API int luaopen_debug (lua_State *L) { luaL_register(L, LUA_DBLIBNAME, dblib); return 1; } debian/grub-extras/lua/lvm.h0000664000000000000000000000220712524662415013173 0ustar /* ** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ #ifndef lvm_h #define lvm_h #include "ldo.h" #include "lobject.h" #include "ltm.h" #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) #define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ (((o) = luaV_tonumber(o,n)) != NULL)) #define equalobj(L,o1,o2) \ (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val); LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val); LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); #endif debian/grub-extras/lua/grub_lua.h0000664000000000000000000000253512524662415014201 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GRUB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ #ifndef GRUB_LUA_HEADER #define GRUB_LUA_HEADER 1 #include #include #include #include #include #include #include #include #include #include #undef UNUSED #define UNUSED (void) #define strtoul grub_strtoul #define strtod(s,e) grub_strtoul(s,e,0) #define exit(a) grub_exit() #define jmp_buf grub_jmp_buf #define setjmp grub_setjmp #define longjmp grub_longjmp #define fputs(s,f) grub_printf("%s", s) int strcspn (const char *s1, const char *s2); char *strpbrk (const char *s1, const char *s2); #endif debian/grub-extras/lua/ltable.h0000664000000000000000000000224012524662415013635 0ustar /* ** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ #ifndef ltable_h #define ltable_h #include "lobject.h" #define gnode(t,i) (&(t)->node[i]) #define gkey(n) (&(n)->i_key.nk) #define gval(n) (&(n)->i_val) #define gnext(n) ((n)->i_key.nk.next) #define key2tval(n) (&(n)->i_key.tvk) LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); LUAI_FUNC void luaH_free (lua_State *L, Table *t); LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); LUAI_FUNC int luaH_getn (Table *t); #if defined(LUA_DEBUG) LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); LUAI_FUNC int luaH_isdummy (Node *n); #endif #endif debian/grub-extras/lua/lobject.c0000664000000000000000000001305012524662415014010 0ustar /* ** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ #if 0 #include #include #include #include #include #endif #define lobject_c #define LUA_CORE #include "lua.h" #include "ldo.h" #include "lmem.h" #include "lobject.h" #include "lstate.h" #include "lstring.h" #include "lvm.h" const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; /* ** converts an integer to a "floating point byte", represented as ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if ** eeeee != 0 and (xxx) otherwise. */ int luaO_int2fb (unsigned int x) { int e = 0; /* expoent */ while (x >= 16) { x = (x+1) >> 1; e++; } if (x < 8) return x; else return ((e+1) << 3) | (cast_int(x) - 8); } /* converts back */ int luaO_fb2int (int x) { int e = (x >> 3) & 31; if (e == 0) return x; else return ((x & 7)+8) << (e - 1); } int luaO_log2 (unsigned int x) { static const lu_byte log_2[256] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 }; int l = -1; while (x >= 256) { l += 8; x >>= 8; } return l + log_2[x]; } int luaO_rawequalObj (const TValue *t1, const TValue *t2) { if (ttype(t1) != ttype(t2)) return 0; else switch (ttype(t1)) { case LUA_TNIL: return 1; case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); default: lua_assert(iscollectable(t1)); return gcvalue(t1) == gcvalue(t2); } } int luaO_str2d (const char *s, lua_Number *result) { char *endptr; *result = lua_str2number(s, &endptr); if (endptr == s) return 0; /* conversion failed */ if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ *result = cast_num(strtoul(s, &endptr, 16)); if (*endptr == '\0') return 1; /* most common case */ while (isspace(cast(unsigned char, *endptr))) endptr++; if (*endptr != '\0') return 0; /* invalid trailing characters? */ return 1; } static void pushstr (lua_State *L, const char *str) { setsvalue2s(L, L->top, luaS_new(L, str)); incr_top(L); } /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { int n = 1; pushstr(L, ""); for (;;) { const char *e = strchr(fmt, '%'); if (e == NULL) break; setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); incr_top(L); switch (*(e+1)) { case 's': { const char *s = va_arg(argp, char *); if (s == NULL) s = "(null)"; pushstr(L, s); break; } case 'c': { char buff[2]; buff[0] = cast(char, va_arg(argp, int)); buff[1] = '\0'; pushstr(L, buff); break; } case 'd': { setnvalue(L->top, cast_num(va_arg(argp, int))); incr_top(L); break; } case 'f': { setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); incr_top(L); break; } case 'p': { char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ snprintf(buff, sizeof (buff), "%p", va_arg(argp, void *)); pushstr(L, buff); break; } case '%': { pushstr(L, "%"); break; } default: { char buff[3]; buff[0] = '%'; buff[1] = *(e+1); buff[2] = '\0'; pushstr(L, buff); break; } } n += 2; fmt = e+2; } pushstr(L, fmt); luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); L->top -= n; return svalue(L->top - 1); } const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { const char *msg; va_list argp; va_start(argp, fmt); msg = luaO_pushvfstring(L, fmt, argp); va_end(argp); return msg; } void luaO_chunkid (char *out, const char *source, size_t bufflen) { if (*source == '=') { strncpy(out, source+1, bufflen); /* remove first char */ out[bufflen-1] = '\0'; /* ensures null termination */ } else { /* out = "source", or "...source" */ if (*source == '@') { size_t l; char *ptr; source++; /* skip the `@' */ bufflen -= sizeof(" '...' "); l = strlen(source); ptr = out; if (l > bufflen) { source += (l-bufflen); /* get last part of file name */ ptr = grub_stpcpy (ptr, "..."); } ptr = grub_stpcpy(ptr, source); *ptr = '\0'; } else { /* out = [string "string"] */ size_t len = strcspn(source, "\n\r"); /* stop at first newline */ char *ptr; bufflen -= sizeof(" [string \"...\"] "); if (len > bufflen) len = bufflen; ptr = grub_stpcpy(out, "[string \""); if (source[len] != '\0') { /* must truncate? */ memcpy(ptr, source, len); ptr += len; ptr = grub_stpcpy(ptr, "..."); } else ptr = grub_stpcpy(ptr, source); ptr = grub_stpcpy(ptr, "\"]"); *ptr = '\0'; } } } debian/grub-extras/lua/ltm.h0000664000000000000000000000177212524662415013177 0ustar /* ** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $ ** Tag methods ** See Copyright Notice in lua.h */ #ifndef ltm_h #define ltm_h #include "lobject.h" /* * WARNING: if you change the order of this enumeration, * grep "ORDER TM" */ typedef enum { TM_INDEX, TM_NEWINDEX, TM_GC, TM_MODE, TM_EQ, /* last tag method with `fast' access */ TM_ADD, TM_SUB, TM_MUL, TM_DIV, TM_MOD, TM_POW, TM_UNM, TM_LEN, TM_LT, TM_LE, TM_CONCAT, TM_CALL, TM_N /* number of elements in the enum */ } TMS; #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) #define fasttm(l,et,e) gfasttm(G(l), et, e) LUAI_DATA const char *const luaT_typenames[]; LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event); LUAI_FUNC void luaT_init (lua_State *L); #endif debian/grub-extras/lua/lundump.c0000664000000000000000000001103412524662415014052 0ustar /* ** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ #if 0 #include #endif #define lundump_c #define LUA_CORE #include "lua.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lmem.h" #include "lobject.h" #include "lstring.h" #include "lundump.h" #include "lzio.h" typedef struct { lua_State* L; ZIO* Z; Mbuffer* b; const char* name; } LoadState; #ifdef LUAC_TRUST_BINARIES #define IF(c,s) #define error(S,s) #else #define IF(c,s) if (c) error(S,s) static void error(LoadState* S, const char* why) { luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); luaD_throw(S->L,LUA_ERRSYNTAX); } #endif #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) #define LoadByte(S) (lu_byte)LoadChar(S) #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) static void LoadBlock(LoadState* S, void* b, size_t size) { size_t r=luaZ_read(S->Z,b,size); IF (r!=0, "unexpected end"); } static int LoadChar(LoadState* S) { char x; LoadVar(S,x); return x; } static int LoadInt(LoadState* S) { int x; LoadVar(S,x); IF (x<0, "bad integer"); return x; } static lua_Number LoadNumber(LoadState* S) { lua_Number x; LoadVar(S,x); return x; } static TString* LoadString(LoadState* S) { size_t size; LoadVar(S,size); if (size==0) return NULL; else { char* s=luaZ_openspace(S->L,S->b,size); LoadBlock(S,s,size); return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ } } static void LoadCode(LoadState* S, Proto* f) { int n=LoadInt(S); f->code=luaM_newvector(S->L,n,Instruction); f->sizecode=n; LoadVector(S,f->code,n,sizeof(Instruction)); } static Proto* LoadFunction(LoadState* S, TString* p); static void LoadConstants(LoadState* S, Proto* f) { int i,n; n=LoadInt(S); f->k=luaM_newvector(S->L,n,TValue); f->sizek=n; for (i=0; ik[i]); for (i=0; ik[i]; int t=LoadChar(S); switch (t) { case LUA_TNIL: setnilvalue(o); break; case LUA_TBOOLEAN: setbvalue(o,LoadChar(S)!=0); break; case LUA_TNUMBER: setnvalue(o,LoadNumber(S)); break; case LUA_TSTRING: setsvalue2n(S->L,o,LoadString(S)); break; default: error(S,"bad constant"); break; } } n=LoadInt(S); f->p=luaM_newvector(S->L,n,Proto*); f->sizep=n; for (i=0; ip[i]=NULL; for (i=0; ip[i]=LoadFunction(S,f->source); } static void LoadDebug(LoadState* S, Proto* f) { int i,n; n=LoadInt(S); f->lineinfo=luaM_newvector(S->L,n,int); f->sizelineinfo=n; LoadVector(S,f->lineinfo,n,sizeof(int)); n=LoadInt(S); f->locvars=luaM_newvector(S->L,n,LocVar); f->sizelocvars=n; for (i=0; ilocvars[i].varname=NULL; for (i=0; ilocvars[i].varname=LoadString(S); f->locvars[i].startpc=LoadInt(S); f->locvars[i].endpc=LoadInt(S); } n=LoadInt(S); f->upvalues=luaM_newvector(S->L,n,TString*); f->sizeupvalues=n; for (i=0; iupvalues[i]=NULL; for (i=0; iupvalues[i]=LoadString(S); } static Proto* LoadFunction(LoadState* S, TString* p) { Proto* f; if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); f=luaF_newproto(S->L); setptvalue2s(S->L,S->L->top,f); incr_top(S->L); f->source=LoadString(S); if (f->source==NULL) f->source=p; f->linedefined=LoadInt(S); f->lastlinedefined=LoadInt(S); f->nups=LoadByte(S); f->numparams=LoadByte(S); f->is_vararg=LoadByte(S); f->maxstacksize=LoadByte(S); LoadCode(S,f); LoadConstants(S,f); LoadDebug(S,f); IF (!luaG_checkcode(f), "bad code"); S->L->top--; S->L->nCcalls--; return f; } static void LoadHeader(LoadState* S) { char h[LUAC_HEADERSIZE]; char s[LUAC_HEADERSIZE]; luaU_header(h); LoadBlock(S,s,LUAC_HEADERSIZE); IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); } /* ** load precompiled chunk */ Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) { LoadState S; if (*name=='@' || *name=='=') S.name=name+1; else if (*name==LUA_SIGNATURE[0]) S.name="binary string"; else S.name=name; S.L=L; S.Z=Z; S.b=buff; LoadHeader(&S); return LoadFunction(&S,luaS_newliteral(L,"=?")); } /* * make header */ void luaU_header (char* h) { int x=1; memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); h+=sizeof(LUA_SIGNATURE)-1; *h++=(char)LUAC_VERSION; *h++=(char)LUAC_FORMAT; *h++=(char)*(char*)&x; /* endianness */ *h++=(char)sizeof(int); *h++=(char)sizeof(size_t); *h++=(char)sizeof(Instruction); *h++=(char)sizeof(lua_Number); *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ } debian/grub-extras/lua/lopcodes.h0000664000000000000000000001756612524662415014223 0ustar /* ** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ #ifndef lopcodes_h #define lopcodes_h #include "llimits.h" /*=========================================================================== We assume that instructions are unsigned numbers. All instructions have an opcode in the first 6 bits. Instructions can have the following fields: `A' : 8 bits `B' : 9 bits `C' : 9 bits `Bx' : 18 bits (`B' and `C' together) `sBx' : signed Bx A signed argument is represented in excess K; that is, the number value is the unsigned value minus K. K is exactly the maximum value for that argument (so that -max is represented by 0, and +max is represented by 2*max), which is half the maximum for the corresponding unsigned argument. ===========================================================================*/ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ /* ** size and position of opcode arguments. */ #define SIZE_C 9 #define SIZE_B 9 #define SIZE_Bx (SIZE_C + SIZE_B) #define SIZE_A 8 #define SIZE_OP 6 #define POS_OP 0 #define POS_A (POS_OP + SIZE_OP) #define POS_C (POS_A + SIZE_A) #define POS_B (POS_C + SIZE_C) #define POS_Bx POS_C /* ** limits for opcode arguments. ** we use (signed) int to manipulate most arguments, ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) */ #if SIZE_Bx < LUAI_BITSINT-1 #define MAXARG_Bx ((1<>1) /* `sBx' is signed */ #else #define MAXARG_Bx MAX_INT #define MAXARG_sBx MAX_INT #endif #define MAXARG_A ((1<>POS_OP) & MASK1(SIZE_OP,0))) #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ ((cast(Instruction, o)<>POS_A) & MASK1(SIZE_A,0))) #define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0))) #define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) #define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) #define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ ((cast(Instruction, b)< C) then pc++ */ OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) =) R(A)*/ OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ } OpCode; #define NUM_OPCODES (cast(int, OP_VARARG) + 1) /*=========================================================================== Notes: (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, and can be 0: OP_CALL then sets `top' to last_result+1, so next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. (*) In OP_VARARG, if (B == 0) then use actual number of varargs and set top (like in OP_CALL with C == 0). (*) In OP_RETURN, if (B == 0) then return up to `top' (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next `instruction' is real C (*) For comparisons, A specifies what condition the test should accept (true or false). (*) All `skips' (pc++) assume that next instruction is a jump ===========================================================================*/ /* ** masks for instruction properties. The format is: ** bits 0-1: op mode ** bits 2-3: C arg mode ** bits 4-5: B arg mode ** bit 6: instruction set register A ** bit 7: operator is a test */ enum OpArgMask { OpArgN, /* argument is not used */ OpArgU, /* argument is used */ OpArgR, /* argument is a register or a jump offset */ OpArgK /* argument is a constant or register/constant */ }; LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) #define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) #define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) #define testAMode(m) (luaP_opmodes[m] & (1 << 6)) #define testTMode(m) (luaP_opmodes[m] & (1 << 7)) LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ /* number of list items to accumulate before a SETLIST instruction */ #define LFIELDS_PER_FLUSH 50 #endif debian/grub-extras/lua/lualib.h0000664000000000000000000000200112524662415013635 0ustar /* ** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lua standard libraries ** See Copyright Notice in lua.h */ #ifndef lualib_h #define lualib_h #include "lua.h" /* Key to file-handle type */ #define LUA_FILEHANDLE "FILE*" #define LUA_COLIBNAME "coroutine" LUALIB_API int (luaopen_base) (lua_State *L); #define LUA_TABLIBNAME "table" LUALIB_API int (luaopen_table) (lua_State *L); #define LUA_IOLIBNAME "io" LUALIB_API int (luaopen_io) (lua_State *L); #define LUA_OSLIBNAME "os" LUALIB_API int (luaopen_os) (lua_State *L); #define LUA_STRLIBNAME "string" LUALIB_API int (luaopen_string) (lua_State *L); #define LUA_MATHLIBNAME "math" LUALIB_API int (luaopen_math) (lua_State *L); #define LUA_DBLIBNAME "debug" LUALIB_API int (luaopen_debug) (lua_State *L); #define LUA_LOADLIBNAME "package" LUALIB_API int (luaopen_package) (lua_State *L); /* open all previous libraries */ LUALIB_API void (luaL_openlibs) (lua_State *L); #ifndef lua_assert #define lua_assert(x) ((void)0) #endif #endif debian/grub-extras/lua/lauxlib.c0000664000000000000000000004304112524662415014031 0ustar /* ** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ #if 0 #include #include #include #include #include #include #endif #include /* This file uses only the official API of Lua. ** Any function declared here could be written as an application function. */ #define lauxlib_c #define LUA_LIB #include "lua.h" #include "lauxlib.h" #define FREELIST_REF 0 /* free list of references */ /* convert a stack index to positive */ #define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ lua_gettop(L) + (i) + 1) /* ** {====================================================== ** Error-report functions ** ======================================================= */ LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { lua_Debug ar; if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); lua_getinfo(L, "n", &ar); if (strcmp(ar.namewhat, "method") == 0) { narg--; /* do not count `self' */ if (narg == 0) /* error is in the self argument itself? */ return luaL_error(L, "calling " LUA_QS " on bad self (%s)", ar.name, extramsg); } if (ar.name == NULL) ar.name = "?"; return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", narg, ar.name, extramsg); } LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { const char *msg = lua_pushfstring(L, "%s expected, got %s", tname, luaL_typename(L, narg)); return luaL_argerror(L, narg, msg); } static void tag_error (lua_State *L, int narg, int tag) { luaL_typerror(L, narg, lua_typename(L, tag)); } LUALIB_API void luaL_where (lua_State *L, int level) { lua_Debug ar; if (lua_getstack(L, level, &ar)) { /* check function at level */ lua_getinfo(L, "Sl", &ar); /* get info about it */ if (ar.currentline > 0) { /* is there info? */ lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); return; } } lua_pushliteral(L, ""); /* else, no information available... */ } LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { va_list argp; va_start(argp, fmt); luaL_where(L, 1); lua_pushvfstring(L, fmt, argp); va_end(argp); lua_concat(L, 2); return lua_error(L); } /* }====================================================== */ LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, const char *const lst[]) { const char *name = (def) ? luaL_optstring(L, narg, def) : luaL_checkstring(L, narg); int i; for (i=0; lst[i]; i++) if (strcmp(lst[i], name) == 0) return i; return luaL_argerror(L, narg, lua_pushfstring(L, "invalid option " LUA_QS, name)); } LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ if (!lua_isnil(L, -1)) /* name already in use? */ return 0; /* leave previous value on top, but return 0 */ lua_pop(L, 1); lua_newtable(L); /* create metatable */ lua_pushvalue(L, -1); lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ return 1; } LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { void *p = lua_touserdata(L, ud); if (p != NULL) { /* value is a userdata? */ if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ lua_pop(L, 2); /* remove both metatables */ return p; } } } luaL_typerror(L, ud, tname); /* else error */ return NULL; /* to avoid warnings */ } LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { if (!lua_checkstack(L, space)) luaL_error(L, "stack overflow (%s)", mes); } LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { if (lua_type(L, narg) != t) tag_error(L, narg, t); } LUALIB_API void luaL_checkany (lua_State *L, int narg) { if (lua_type(L, narg) == LUA_TNONE) luaL_argerror(L, narg, "value expected"); } LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { const char *s = lua_tolstring(L, narg, len); if (!s) tag_error(L, narg, LUA_TSTRING); return s; } LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, const char *def, size_t *len) { if (lua_isnoneornil(L, narg)) { if (len) *len = (def ? strlen(def) : 0); return def; } else return luaL_checklstring(L, narg, len); } LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { lua_Number d = lua_tonumber(L, narg); if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ tag_error(L, narg, LUA_TNUMBER); return d; } LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { return luaL_opt(L, luaL_checknumber, narg, def); } LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { lua_Integer d = lua_tointeger(L, narg); if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ tag_error(L, narg, LUA_TNUMBER); return d; } LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, lua_Integer def) { return luaL_opt(L, luaL_checkinteger, narg, def); } LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { if (!lua_getmetatable(L, obj)) /* no metatable? */ return 0; lua_pushstring(L, event); lua_rawget(L, -2); if (lua_isnil(L, -1)) { lua_pop(L, 2); /* remove metatable and metafield */ return 0; } else { lua_remove(L, -2); /* remove only metatable */ return 1; } } LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { obj = abs_index(L, obj); if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ return 0; lua_pushvalue(L, obj); lua_call(L, 1, 1); return 1; } LUALIB_API void (luaL_register) (lua_State *L, const char *libname, const luaL_Reg *l) { luaI_openlib(L, libname, l, 0); } static int libsize (const luaL_Reg *l) { int size = 0; for (; l->name; l++) size++; return size; } LUALIB_API void luaI_openlib (lua_State *L, const char *libname, const luaL_Reg *l, int nup) { if (libname) { int size = libsize(l); /* check whether lib already exists */ luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); lua_getfield(L, -1, libname); /* get _LOADED[libname] */ if (!lua_istable(L, -1)) { /* not found? */ lua_pop(L, 1); /* remove previous result */ /* try global variable (and create one if it does not exist) */ if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) luaL_error(L, "name conflict for module " LUA_QS, libname); lua_pushvalue(L, -1); lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ } lua_remove(L, -2); /* remove _LOADED table */ lua_insert(L, -(nup+1)); /* move library table to below upvalues */ } for (; l->name; l++) { int i; for (i=0; ifunc, nup); lua_setfield(L, -(nup+2), l->name); } lua_pop(L, nup); /* remove upvalues */ } /* ** {====================================================== ** getn-setn: size for arrays ** ======================================================= */ #if defined(LUA_COMPAT_GETN) static int checkint (lua_State *L, int topop) { int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; lua_pop(L, topop); return n; } static void getsizes (lua_State *L) { lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); if (lua_isnil(L, -1)) { /* no `size' table? */ lua_pop(L, 1); /* remove nil */ lua_newtable(L); /* create it */ lua_pushvalue(L, -1); /* `size' will be its own metatable */ lua_setmetatable(L, -2); lua_pushliteral(L, "kv"); lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ lua_pushvalue(L, -1); lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ } } LUALIB_API void luaL_setn (lua_State *L, int t, int n) { t = abs_index(L, t); lua_pushliteral(L, "n"); lua_rawget(L, t); if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ lua_pushliteral(L, "n"); /* use it */ lua_pushinteger(L, n); lua_rawset(L, t); } else { /* use `sizes' */ getsizes(L); lua_pushvalue(L, t); lua_pushinteger(L, n); lua_rawset(L, -3); /* sizes[t] = n */ lua_pop(L, 1); /* remove `sizes' */ } } LUALIB_API int luaL_getn (lua_State *L, int t) { int n; t = abs_index(L, t); lua_pushliteral(L, "n"); /* try t.n */ lua_rawget(L, t); if ((n = checkint(L, 1)) >= 0) return n; getsizes(L); /* else try sizes[t] */ lua_pushvalue(L, t); lua_rawget(L, -2); if ((n = checkint(L, 2)) >= 0) return n; return (int)lua_objlen(L, t); } #endif /* }====================================================== */ LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, const char *r) { const char *wild; size_t l = strlen(p); luaL_Buffer b; luaL_buffinit(L, &b); while ((wild = strstr(s, p)) != NULL) { luaL_addlstring(&b, s, wild - s); /* push prefix */ luaL_addstring(&b, r); /* push replacement in place of pattern */ s = wild + l; /* continue after `p' */ } luaL_addstring(&b, s); /* push last suffix */ luaL_pushresult(&b); return lua_tostring(L, -1); } LUALIB_API const char *luaL_findtable (lua_State *L, int idx, const char *fname, int szhint) { const char *e; lua_pushvalue(L, idx); do { e = strchr(fname, '.'); if (e == NULL) e = fname + strlen(fname); lua_pushlstring(L, fname, e - fname); lua_rawget(L, -2); if (lua_isnil(L, -1)) { /* no such field? */ lua_pop(L, 1); /* remove this nil */ lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ lua_pushlstring(L, fname, e - fname); lua_pushvalue(L, -2); lua_settable(L, -4); /* set new table into field */ } else if (!lua_istable(L, -1)) { /* field has a non-table value? */ lua_pop(L, 2); /* remove table and value */ return fname; /* return problematic part of the name */ } lua_remove(L, -2); /* remove previous table */ fname = e + 1; } while (*e == '.'); return NULL; } /* ** {====================================================== ** Generic Buffer manipulation ** ======================================================= */ #define bufflen(B) ((B)->p - (B)->buffer) #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) #define LIMIT (LUA_MINSTACK/2) static int emptybuffer (luaL_Buffer *B) { size_t l = bufflen(B); if (l == 0) return 0; /* put nothing on stack */ else { lua_pushlstring(B->L, B->buffer, l); B->p = B->buffer; B->lvl++; return 1; } } static void adjuststack (luaL_Buffer *B) { if (B->lvl > 1) { lua_State *L = B->L; int toget = 1; /* number of levels to concat */ size_t toplen = lua_strlen(L, -1); do { size_t l = lua_strlen(L, -(toget+1)); if (B->lvl - toget + 1 >= LIMIT || toplen > l) { toplen += l; toget++; } else break; } while (toget < B->lvl); lua_concat(L, toget); B->lvl = B->lvl - toget + 1; } } LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { if (emptybuffer(B)) adjuststack(B); return B->buffer; } LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { while (l--) luaL_addchar(B, *s++); } LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { luaL_addlstring(B, s, strlen(s)); } LUALIB_API void luaL_pushresult (luaL_Buffer *B) { emptybuffer(B); lua_concat(B->L, B->lvl); B->lvl = 1; } LUALIB_API void luaL_addvalue (luaL_Buffer *B) { lua_State *L = B->L; size_t vl; const char *s = lua_tolstring(L, -1, &vl); if (vl <= bufffree(B)) { /* fit into buffer? */ memcpy(B->p, s, vl); /* put it there */ B->p += vl; lua_pop(L, 1); /* remove from stack */ } else { if (emptybuffer(B)) lua_insert(L, -2); /* put buffer before new value */ B->lvl++; /* add new value into B stack */ adjuststack(B); } } LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { B->L = L; B->p = B->buffer; B->lvl = 0; } /* }====================================================== */ LUALIB_API int luaL_ref (lua_State *L, int t) { int ref; t = abs_index(L, t); if (lua_isnil(L, -1)) { lua_pop(L, 1); /* remove from stack */ return LUA_REFNIL; /* `nil' has a unique fixed reference */ } lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ lua_pop(L, 1); /* remove it from stack */ if (ref != 0) { /* any free element? */ lua_rawgeti(L, t, ref); /* remove it from list */ lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ } else { /* no free elements */ ref = (int)lua_objlen(L, t); ref++; /* create new reference */ } lua_rawseti(L, t, ref); return ref; } LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { if (ref >= 0) { t = abs_index(L, t); lua_rawgeti(L, t, FREELIST_REF); lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ lua_pushinteger(L, ref); lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ } } /* ** {====================================================== ** Load functions ** ======================================================= */ #define GRUB_EOF -1 static int grub_getc (grub_file_t file) { grub_uint8_t c = 0; return (grub_file_read (file, &c, 1) != 1) ? GRUB_EOF : c; return GRUB_EOF; } #define grub_eof(file) (file->offset >= file->size) typedef struct LoadF { int extraline; grub_file_t f; int ungetc; char buff[LUAL_BUFFERSIZE]; } LoadF; static const char *getF (lua_State *L, void *ud, size_t *size) { LoadF *lf = (LoadF *)ud; char *p; int s; (void)L; if (lf->extraline) { lf->extraline = 0; *size = 1; return "\n"; } s = sizeof (lf->buff); p = lf->buff; if (lf->ungetc >= 0) { lf->buff[0] = lf->ungetc; lf->ungetc = -1; s--; p++; } if (grub_eof(lf->f)) return NULL; s = grub_file_read(lf->f, p, s); if (s <= 0) return NULL; *size = s + (p - lf->buff); return (*size > 0) ? lf->buff : NULL; } static int errfile (lua_State *L, const char *what, int fnameindex) { const char *serr = grub_errmsg; const char *filename = lua_tostring(L, fnameindex) + 1; lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); lua_remove(L, fnameindex); return LUA_ERRFILE; } LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { LoadF lf; int status, readstatus; int c; int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ lf.extraline = 0; if (filename == NULL) { lua_pushliteral(L, "=stdin"); return errfile(L, "open", fnameindex); } else { lua_pushfstring(L, "@%s", filename); lf.f = grub_file_open(filename); if (lf.f == NULL) return errfile(L, "open", fnameindex); } c = grub_getc(lf.f); if (c == '#') { /* Unix exec. file? */ lf.extraline = 1; while ((c = grub_getc(lf.f)) != GRUB_EOF && c != '\n') ; /* skip first line */ if (c == '\n') c = grub_getc(lf.f); } if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ /* skip eventual `#!...' */ while ((c = grub_getc(lf.f)) != GRUB_EOF && c != LUA_SIGNATURE[0]) ; lf.extraline = 0; } lf.ungetc = c; status = lua_load(L, getF, &lf, lua_tostring(L, -1)); readstatus = grub_errno; grub_file_close(lf.f); /* close file (even in case of errors) */ if (readstatus) { lua_settop(L, fnameindex); /* ignore results from `lua_load' */ return errfile(L, "read", fnameindex); } lua_remove(L, fnameindex); return status; } typedef struct LoadS { const char *s; size_t size; } LoadS; static const char *getS (lua_State *L, void *ud, size_t *size) { LoadS *ls = (LoadS *)ud; (void)L; if (ls->size == 0) return NULL; *size = ls->size; ls->size = 0; return ls->s; } LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, const char *name) { LoadS ls; ls.s = buff; ls.size = size; return lua_load(L, getS, &ls, name); } LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { return luaL_loadbuffer(L, s, strlen(s), s); } /* }====================================================== */ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { (void)ud; (void)osize; if (nsize == 0) { free(ptr); return NULL; } else return realloc(ptr, nsize); } static int panic (lua_State *L) { (void)L; /* to avoid warnings */ #if 0 fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1)); #else grub_fatal ("PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1)); #endif return 0; } LUALIB_API lua_State *luaL_newstate (void) { lua_State *L = lua_newstate(l_alloc, NULL); if (L) lua_atpanic(L, &panic); return L; } debian/grub-extras/lua/grub_lib.c0000664000000000000000000002416412524662415014163 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GRUB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include "grub_lib.h" #include #include #include #include #include #include #ifdef ENABLE_LUA_PCI #include #endif /* Updates the globals grub_errno and grub_msg, leaving their values on the top of the stack, and clears grub_errno. When grub_errno is zero, grub_msg is not left on the stack. The value returned is the number of values left on the stack. */ static int push_result (lua_State *state) { int saved_errno; int num_results; saved_errno = grub_errno; grub_errno = 0; /* Push once for setfield, and again to leave on the stack */ lua_pushinteger (state, saved_errno); lua_pushinteger (state, saved_errno); lua_setfield (state, LUA_GLOBALSINDEX, "grub_errno"); if (saved_errno) { /* Push once for setfield, and again to leave on the stack */ lua_pushstring (state, grub_errmsg); lua_pushstring (state, grub_errmsg); num_results = 2; } else { lua_pushnil (state); num_results = 1; } lua_setfield (state, LUA_GLOBALSINDEX, "grub_errmsg"); return num_results; } /* Updates the globals grub_errno and grub_msg ( without leaving them on the stack ), clears grub_errno, and returns the value of grub_errno before it was cleared. */ static int save_errno (lua_State *state) { int saved_errno; saved_errno = grub_errno; lua_pop(state, push_result(state)); return saved_errno; } static int grub_lua_run (lua_State *state) { int n; char **args; const char *s; s = luaL_checkstring (state, 1); if ((! grub_parser_split_cmdline (s, 0, 0, &n, &args)) && (n >= 0)) { grub_command_t cmd; cmd = grub_command_find (args[0]); if (cmd) (cmd->func) (cmd, n-1, &args[1]); else grub_error (GRUB_ERR_FILE_NOT_FOUND, "command not found"); grub_free (args[0]); grub_free (args); } return push_result (state); } static int grub_lua_getenv (lua_State *state) { int n, i; n = lua_gettop (state); for (i = 1; i <= n; i++) { const char *name, *value; name = luaL_checkstring (state, i); value = grub_env_get (name); if (value) lua_pushstring (state, value); else lua_pushnil (state); } return n; } static int grub_lua_setenv (lua_State *state) { const char *name, *value; name = luaL_checkstring (state, 1); value = luaL_checkstring (state, 2); if (name[0]) grub_env_set (name, value); return 0; } /* Helper for grub_lua_enum_device. */ static int grub_lua_enum_device_iter (const char *name, void *data) { lua_State *state = data; int result; grub_device_t dev; result = 0; dev = grub_device_open (name); if (dev) { grub_fs_t fs; fs = grub_fs_probe (dev); if (fs) { lua_pushvalue (state, 1); lua_pushstring (state, name); lua_pushstring (state, fs->name); if (! fs->uuid) lua_pushnil (state); else { int err; char *uuid; err = fs->uuid (dev, &uuid); if (err) { grub_errno = 0; lua_pushnil (state); } else { lua_pushstring (state, uuid); grub_free (uuid); } } lua_call (state, 3, 1); result = lua_tointeger (state, -1); lua_pop (state, 1); } else grub_errno = 0; grub_device_close (dev); } else grub_errno = 0; return result; } static int grub_lua_enum_device (lua_State *state) { luaL_checktype (state, 1, LUA_TFUNCTION); grub_device_iterate (grub_lua_enum_device_iter, state); return push_result (state); } static int enum_file (const char *name, const struct grub_dirhook_info *info, void *data) { int result; lua_State *state = data; lua_pushvalue (state, 1); lua_pushstring (state, name); lua_pushinteger (state, info->dir != 0); lua_call (state, 2, 1); result = lua_tointeger (state, -1); lua_pop (state, 1); return result; } static int grub_lua_enum_file (lua_State *state) { char *device_name; const char *arg; grub_device_t dev; luaL_checktype (state, 1, LUA_TFUNCTION); arg = luaL_checkstring (state, 2); device_name = grub_file_get_device_name (arg); dev = grub_device_open (device_name); if (dev) { grub_fs_t fs; const char *path; fs = grub_fs_probe (dev); path = grub_strchr (arg, ')'); if (! path) path = arg; else path++; if (fs) { (fs->dir) (dev, path, enum_file, state); } grub_device_close (dev); } grub_free (device_name); return push_result (state); } #ifdef ENABLE_LUA_PCI /* Helper for grub_lua_enum_pci. */ static int grub_lua_enum_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) { lua_State *state = data; int result; grub_pci_address_t addr; grub_uint32_t class; lua_pushvalue (state, 1); lua_pushinteger (state, grub_pci_get_bus (dev)); lua_pushinteger (state, grub_pci_get_device (dev)); lua_pushinteger (state, grub_pci_get_function (dev)); lua_pushinteger (state, pciid); addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); lua_pushinteger (state, class); lua_call (state, 5, 1); result = lua_tointeger (state, -1); lua_pop (state, 1); return result; } static int grub_lua_enum_pci (lua_State *state) { luaL_checktype (state, 1, LUA_TFUNCTION); grub_pci_iterate (grub_lua_enum_pci_iter, state); return push_result (state); } #endif static int grub_lua_file_open (lua_State *state) { grub_file_t file; const char *name; name = luaL_checkstring (state, 1); file = grub_file_open (name); save_errno (state); if (! file) return 0; lua_pushlightuserdata (state, file); return 1; } static int grub_lua_file_close (lua_State *state) { grub_file_t file; luaL_checktype (state, 1, LUA_TLIGHTUSERDATA); file = lua_touserdata (state, 1); grub_file_close (file); return push_result (state); } static int grub_lua_file_seek (lua_State *state) { grub_file_t file; grub_off_t offset; luaL_checktype (state, 1, LUA_TLIGHTUSERDATA); file = lua_touserdata (state, 1); offset = luaL_checkinteger (state, 2); offset = grub_file_seek (file, offset); save_errno (state); lua_pushinteger (state, offset); return 1; } static int grub_lua_file_read (lua_State *state) { grub_file_t file; luaL_Buffer b; int n; luaL_checktype (state, 1, LUA_TLIGHTUSERDATA); file = lua_touserdata (state, 1); n = luaL_checkinteger (state, 2); luaL_buffinit (state, &b); while (n) { char *p; int nr; nr = (n > LUAL_BUFFERSIZE) ? LUAL_BUFFERSIZE : n; p = luaL_prepbuffer (&b); nr = grub_file_read (file, p, nr); if (nr <= 0) break; luaL_addsize (&b, nr); n -= nr; } save_errno (state); luaL_pushresult (&b); return 1; } static int grub_lua_file_getline (lua_State *state) { grub_file_t file; char *line; luaL_checktype (state, 1, LUA_TLIGHTUSERDATA); file = lua_touserdata (state, 1); line = grub_file_getline (file); save_errno (state); if (! line) return 0; lua_pushstring (state, line); grub_free (line); return 1; } static int grub_lua_file_getsize (lua_State *state) { grub_file_t file; luaL_checktype (state, 1, LUA_TLIGHTUSERDATA); file = lua_touserdata (state, 1); lua_pushinteger (state, file->size); return 1; } static int grub_lua_file_getpos (lua_State *state) { grub_file_t file; luaL_checktype (state, 1, LUA_TLIGHTUSERDATA); file = lua_touserdata (state, 1); lua_pushinteger (state, file->offset); return 1; } static int grub_lua_file_eof (lua_State *state) { grub_file_t file; luaL_checktype (state, 1, LUA_TLIGHTUSERDATA); file = lua_touserdata (state, 1); lua_pushboolean (state, file->offset >= file->size); return 1; } static int grub_lua_file_exist (lua_State *state) { grub_file_t file; const char *name; int result; result = 0; name = luaL_checkstring (state, 1); file = grub_file_open (name); if (file) { result++; grub_file_close (file); } else grub_errno = 0; lua_pushboolean (state, result); return 1; } static int grub_lua_add_menu (lua_State *state) { int n; const char *source; source = luaL_checklstring (state, 1, 0); n = lua_gettop (state) - 1; if (n > 0) { const char **args; char *p; int i; args = grub_malloc (n * sizeof (args[0])); if (!args) return push_result (state); for (i = 0; i < n; i++) args[i] = luaL_checkstring (state, 2 + i); p = grub_strdup (source); if (! p) return push_result (state); grub_normal_add_menu_entry (n, args, NULL, NULL, NULL, NULL, NULL, p, 0); } else { lua_pushstring (state, "not enough parameter"); lua_error (state); } return push_result (state); } luaL_Reg grub_lua_lib[] = { {"run", grub_lua_run}, {"getenv", grub_lua_getenv}, {"setenv", grub_lua_setenv}, {"enum_device", grub_lua_enum_device}, {"enum_file", grub_lua_enum_file}, #ifdef ENABLE_LUA_PCI {"enum_pci", grub_lua_enum_pci}, #endif {"file_open", grub_lua_file_open}, {"file_close", grub_lua_file_close}, {"file_seek", grub_lua_file_seek}, {"file_read", grub_lua_file_read}, {"file_getline", grub_lua_file_getline}, {"file_getsize", grub_lua_file_getsize}, {"file_getpos", grub_lua_file_getpos}, {"file_eof", grub_lua_file_eof}, {"file_exist", grub_lua_file_exist}, {"add_menu", grub_lua_add_menu}, {0, 0} }; debian/grub-extras/lua/lapi.h0000664000000000000000000000040612524662415013321 0ustar /* ** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions from Lua API ** See Copyright Notice in lua.h */ #ifndef lapi_h #define lapi_h #include "lobject.h" LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); #endif debian/grub-extras/lua/luaconf.h0000664000000000000000000005576112524662415014041 0ustar /* ** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ #ifndef lconfig_h #define lconfig_h #if 0 #include #include #endif #include "grub_lua.h" /* ** ================================================================== ** Search for "@@" to find all configurable definitions. ** =================================================================== */ /* @@ LUA_ANSI controls the use of non-ansi features. ** CHANGE it (define it) if you want Lua to avoid the use of any ** non-ansi feature or library. */ #if defined(__STRICT_ANSI__) #define LUA_ANSI #endif #if !defined(LUA_ANSI) && defined(_WIN32) #define LUA_WIN #endif #if defined(LUA_USE_LINUX) #define LUA_USE_POSIX #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ #define LUA_USE_READLINE /* needs some extra libraries */ #endif #if defined(LUA_USE_MACOSX) #define LUA_USE_POSIX #define LUA_DL_DYLD /* does not need extra library */ #endif /* @@ LUA_USE_POSIX includes all functionallity listed as X/Open System @* Interfaces Extension (XSI). ** CHANGE it (define it) if your system is XSI compatible. */ #if 0 #if defined(LUA_USE_POSIX) #define LUA_USE_MKSTEMP #define LUA_USE_ISATTY #define LUA_USE_POPEN #define LUA_USE_ULONGJMP #endif #endif /* @@ LUA_PATH and LUA_CPATH are the names of the environment variables that @* Lua check to set its paths. @@ LUA_INIT is the name of the environment variable that Lua @* checks for initialization code. ** CHANGE them if you want different names. */ #define LUA_PATH "LUA_PATH" #define LUA_CPATH "LUA_CPATH" #define LUA_INIT "LUA_INIT" /* @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for @* Lua libraries. @@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for @* C libraries. ** CHANGE them if your machine has a non-conventional directory ** hierarchy or if you want to install your libraries in ** non-conventional directories. */ #if defined(_WIN32) /* ** In Windows, any exclamation mark ('!') in the path is replaced by the ** path of the directory of the executable file of the current process. */ #define LUA_LDIR "!\\lua\\" #define LUA_CDIR "!\\" #define LUA_PATH_DEFAULT \ ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" #define LUA_CPATH_DEFAULT \ ".\\?.dll;" ".\\?51.dll;" LUA_CDIR"?.dll;" LUA_CDIR"?51.dll;" LUA_CDIR"clibs\\?.dll;" LUA_CDIR"clibs\\?51.dll;" LUA_CDIR"loadall.dll;" LUA_CDIR"clibs\\loadall.dll" #else #define LUA_ROOT "/usr/local/" #define LUA_LDIR LUA_ROOT "share/lua/5.1/" #define LUA_CDIR LUA_ROOT "lib/lua/5.1/" #define LUA_PATH_DEFAULT \ "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" #define LUA_CPATH_DEFAULT \ "./?.so;" "./lib?51.so;" LUA_CDIR"?.so;" LUA_CDIR"lib?51.so;" LUA_CDIR"loadall.so" #endif /* @@ LUA_DIRSEP is the directory separator (for submodules). ** CHANGE it if your machine does not use "/" as the directory separator ** and is not Windows. (On Windows Lua automatically uses "\".) */ #if defined(_WIN32) #define LUA_DIRSEP "\\" #else #define LUA_DIRSEP "/" #endif /* @@ LUA_PATHSEP is the character that separates templates in a path. @@ LUA_PATH_MARK is the string that marks the substitution points in a @* template. @@ LUA_EXECDIR in a Windows path is replaced by the executable's @* directory. @@ LUA_IGMARK is a mark to ignore all before it when bulding the @* luaopen_ function name. ** CHANGE them if for some reason your system cannot use those ** characters. (E.g., if one of those characters is a common character ** in file/directory names.) Probably you do not need to change them. */ #define LUA_PATHSEP ";" #define LUA_PATH_MARK "?" #define LUA_EXECDIR "!" #define LUA_IGMARK "-" /* @@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. ** CHANGE that if ptrdiff_t is not adequate on your machine. (On most ** machines, ptrdiff_t gives a good choice between int or long.) */ #define LUA_INTEGER ptrdiff_t /* @@ LUA_API is a mark for all core API functions. @@ LUALIB_API is a mark for all standard library functions. ** CHANGE them if you need to define those functions in some special way. ** For instance, if you want to create one Windows DLL with the core and ** the libraries, you may want to use the following definition (define ** LUA_BUILD_AS_DLL to get it). */ #if defined(LUA_BUILD_AS_DLL) #if defined(LUA_CORE) || defined(LUA_LIB) #define LUA_API __declspec(dllexport) #else #define LUA_API __declspec(dllimport) #endif #else #define LUA_API extern #endif /* more often than not the libs go together with the core */ #define LUALIB_API LUA_API /* @@ LUAI_FUNC is a mark for all extern functions that are not to be @* exported to outside modules. @@ LUAI_DATA is a mark for all extern (const) variables that are not to @* be exported to outside modules. ** CHANGE them if you need to mark them in some special way. Elf/gcc ** (versions 3.2 and later) mark them as "hidden" to optimize access ** when Lua is compiled as a shared library. */ #if defined(luaall_c) #define LUAI_FUNC static #define LUAI_DATA /* empty */ #elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ defined(__ELF__) #define LUAI_FUNC __attribute__((visibility("hidden"))) extern #define LUAI_DATA LUAI_FUNC #else #define LUAI_FUNC extern #define LUAI_DATA extern #endif /* @@ LUA_QL describes how error messages quote program elements. ** CHANGE it if you want a different appearance. */ #define LUA_QL(x) "'" x "'" #define LUA_QS LUA_QL("%s") /* @@ LUA_IDSIZE gives the maximum size for the description of the source @* of a function in debug information. ** CHANGE it if you want a different size. */ #define LUA_IDSIZE 60 /* ** {================================================================== ** Stand-alone configuration ** =================================================================== */ #if defined(lua_c) || defined(luaall_c) /* @@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that @* is, whether we're running lua interactively). ** CHANGE it if you have a better definition for non-POSIX/non-Windows ** systems. */ #if defined(LUA_USE_ISATTY) #include #define lua_stdin_is_tty() isatty(0) #elif defined(LUA_WIN) #include #include #define lua_stdin_is_tty() _isatty(_fileno(stdin)) #else #define lua_stdin_is_tty() 1 /* assume stdin is a tty */ #endif /* @@ LUA_PROMPT is the default prompt used by stand-alone Lua. @@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. ** CHANGE them if you want different prompts. (You can also change the ** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) */ #define LUA_PROMPT "> " #define LUA_PROMPT2 ">> " /* @@ LUA_PROGNAME is the default name for the stand-alone Lua program. ** CHANGE it if your stand-alone interpreter has a different name and ** your system is not able to detect that name automatically. */ #define LUA_PROGNAME "lua" /* @@ LUA_MAXINPUT is the maximum length for an input line in the @* stand-alone interpreter. ** CHANGE it if you need longer lines. */ #define LUA_MAXINPUT 512 /* @@ lua_readline defines how to show a prompt and then read a line from @* the standard input. @@ lua_saveline defines how to "save" a read line in a "history". @@ lua_freeline defines how to free a line read by lua_readline. ** CHANGE them if you want to improve this functionality (e.g., by using ** GNU readline and history facilities). */ #if defined(LUA_USE_READLINE) #include #include #include #define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) #define lua_saveline(L,idx) \ if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ add_history(lua_tostring(L, idx)); /* add it to history */ #define lua_freeline(L,b) ((void)L, free(b)) #else #define lua_readline(L,b,p) \ ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ #define lua_saveline(L,idx) { (void)L; (void)idx; } #define lua_freeline(L,b) { (void)L; (void)b; } #endif #endif /* }================================================================== */ /* @@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles @* as a percentage. ** CHANGE it if you want the GC to run faster or slower (higher values ** mean larger pauses which mean slower collection.) You can also change ** this value dynamically. */ #define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ /* @@ LUAI_GCMUL defines the default speed of garbage collection relative to @* memory allocation as a percentage. ** CHANGE it if you want to change the granularity of the garbage ** collection. (Higher values mean coarser collections. 0 represents ** infinity, where each step performs a full collection.) You can also ** change this value dynamically. */ #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ /* @@ LUA_COMPAT_GETN controls compatibility with old getn behavior. ** CHANGE it (define it) if you want exact compatibility with the ** behavior of setn/getn in Lua 5.0. */ #undef LUA_COMPAT_GETN /* @@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. ** CHANGE it to undefined as soon as you do not need a global 'loadlib' ** function (the function is still available as 'package.loadlib'). */ #undef LUA_COMPAT_LOADLIB /* @@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. ** CHANGE it to undefined as soon as your programs use only '...' to ** access vararg parameters (instead of the old 'arg' table). */ #define LUA_COMPAT_VARARG /* @@ LUA_COMPAT_MOD controls compatibility with old math.mod function. ** CHANGE it to undefined as soon as your programs use 'math.fmod' or ** the new '%' operator instead of 'math.mod'. */ #define LUA_COMPAT_MOD /* @@ LUA_COMPAT_LSTR controls compatibility with old long string nesting @* facility. ** CHANGE it to 2 if you want the old behaviour, or undefine it to turn ** off the advisory error when nesting [[...]]. */ #define LUA_COMPAT_LSTR 1 /* @@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. ** CHANGE it to undefined as soon as you rename 'string.gfind' to ** 'string.gmatch'. */ #define LUA_COMPAT_GFIND /* @@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' @* behavior. ** CHANGE it to undefined as soon as you replace to 'luaL_register' ** your uses of 'luaL_openlib' */ #define LUA_COMPAT_OPENLIB /* @@ luai_apicheck is the assert macro used by the Lua-C API. ** CHANGE luai_apicheck if you want Lua to perform some checks in the ** parameters it gets from API calls. This may slow down the interpreter ** a bit, but may be quite useful when debugging C code that interfaces ** with Lua. A useful redefinition is to use assert.h. */ #if defined(LUA_USE_APICHECK) #include #define luai_apicheck(L,o) { (void)L; assert(o); } #else #define luai_apicheck(L,o) { (void)L; } #endif /* @@ LUAI_BITSINT defines the number of bits in an int. ** CHANGE here if Lua cannot automatically detect the number of bits of ** your machine. Probably you do not need to change this. */ /* avoid overflows in comparison */ #if INT_MAX-20 < 32760 #define LUAI_BITSINT 16 #elif INT_MAX > 2147483640L /* int has at least 32 bits */ #define LUAI_BITSINT 32 #else #error "you must define LUA_BITSINT with number of bits in an integer" #endif /* @@ LUAI_UINT32 is an unsigned integer with at least 32 bits. @@ LUAI_INT32 is an signed integer with at least 32 bits. @@ LUAI_UMEM is an unsigned integer big enough to count the total @* memory used by Lua. @@ LUAI_MEM is a signed integer big enough to count the total memory @* used by Lua. ** CHANGE here if for some weird reason the default definitions are not ** good enough for your machine. (The definitions in the 'else' ** part always works, but may waste space on machines with 64-bit ** longs.) Probably you do not need to change this. */ #if LUAI_BITSINT >= 32 #define LUAI_UINT32 unsigned int #define LUAI_INT32 int #define LUAI_MAXINT32 INT_MAX #define LUAI_UMEM size_t #define LUAI_MEM ptrdiff_t #else /* 16-bit ints */ #define LUAI_UINT32 unsigned long #define LUAI_INT32 long #define LUAI_MAXINT32 LONG_MAX #define LUAI_UMEM unsigned long #define LUAI_MEM long #endif /* @@ LUAI_MAXCALLS limits the number of nested calls. ** CHANGE it if you need really deep recursive calls. This limit is ** arbitrary; its only purpose is to stop infinite recursion before ** exhausting memory. */ #define LUAI_MAXCALLS 20000 /* @@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function @* can use. ** CHANGE it if you need lots of (Lua) stack space for your C ** functions. This limit is arbitrary; its only purpose is to stop C ** functions to consume unlimited stack space. (must be smaller than ** -LUA_REGISTRYINDEX) */ #define LUAI_MAXCSTACK 8000 /* ** {================================================================== ** CHANGE (to smaller values) the following definitions if your system ** has a small C stack. (Or you may want to change them to larger ** values if your system has a large C stack and these limits are ** too rigid for you.) Some of these constants control the size of ** stack-allocated arrays used by the compiler or the interpreter, while ** others limit the maximum number of recursive calls that the compiler ** or the interpreter can perform. Values too large may cause a C stack ** overflow for some forms of deep constructs. ** =================================================================== */ /* @@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and @* syntactical nested non-terminals in a program. */ #define LUAI_MAXCCALLS 200 /* @@ LUAI_MAXVARS is the maximum number of local variables per function @* (must be smaller than 250). */ #define LUAI_MAXVARS 200 /* @@ LUAI_MAXUPVALUES is the maximum number of upvalues per function @* (must be smaller than 250). */ #define LUAI_MAXUPVALUES 60 /* @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. */ #if 0 #define LUAL_BUFFERSIZE BUFSIZ #else #define LUAL_BUFFERSIZE 512 #endif /* }================================================================== */ /* ** {================================================================== @@ LUA_NUMBER is the type of numbers in Lua. ** CHANGE the following definitions only if you want to build Lua ** with a number type different from double. You may also need to ** change lua_number2int & lua_number2integer. ** =================================================================== */ #if 0 #define LUA_NUMBER_DOUBLE #define LUA_NUMBER double /* @@ LUAI_UACNUMBER is the result of an 'usual argument conversion' @* over a number. */ #define LUAI_UACNUMBER double #else #define LUA_NUMBER int #define LUAI_UACNUMBER int #endif /* @@ LUA_NUMBER_SCAN is the format for reading numbers. @@ LUA_NUMBER_FMT is the format for writing numbers. @@ lua_number2str converts a number to a string. @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. @@ lua_str2number converts a string to a number. */ #if 0 #define LUA_NUMBER_SCAN "%lf" #define LUA_NUMBER_FMT "%.14g" #else #define LUA_NUMBER_SCAN "%d" #define LUA_NUMBER_FMT "%d" #endif #define lua_number2str(s,n) snprintf((s), LUAI_MAXNUMBER2STR, LUA_NUMBER_FMT, (n)) #define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ #define lua_str2number(s,p) strtod((s), (p)) /* @@ The luai_num* macros define the primitive operations over numbers. */ #if defined(LUA_CORE) #if 0 #include #endif #define luai_numadd(a,b) ((a)+(b)) #define luai_numsub(a,b) ((a)-(b)) #define luai_nummul(a,b) ((a)*(b)) #if 0 #define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) #define luai_numpow(a,b) (pow(a,b)) #else static inline LUA_NUMBER luai_numdiv (LUA_NUMBER a, LUA_NUMBER b) { int neg = 0; unsigned res; if (a < 0) { a = -a; neg = !neg; } if (b < 0) { b = -b; neg = !neg; } res = (unsigned) a / (unsigned) b; return neg ? -res : res; } static inline LUA_NUMBER luai_nummod (LUA_NUMBER a, LUA_NUMBER b) { int neg = 0; unsigned res; if (a < 0) { a = -a; neg = !neg; } if (b < 0) { b = -b; neg = !neg; } res = (unsigned) a % (unsigned) b; return neg ? -res : res; } static inline LUA_NUMBER luai_numpow (LUA_NUMBER a, LUA_NUMBER b) { LUA_NUMBER c; c = 1; while (b > 0) { c *= a; b--; } return c; } #endif #define luai_numunm(a) (-(a)) #define luai_numeq(a,b) ((a)==(b)) #define luai_numlt(a,b) ((a)<(b)) #define luai_numle(a,b) ((a)<=(b)) #define luai_numisnan(a) (!luai_numeq((a), (a))) #endif /* @@ lua_number2int is a macro to convert lua_Number to int. @@ lua_number2integer is a macro to convert lua_Number to lua_Integer. ** CHANGE them if you know a faster way to convert a lua_Number to ** int (with any rounding method and without throwing errors) in your ** system. In Pentium machines, a naive typecast from double to int ** in C is extremely slow, so any alternative is worth trying. */ #if 0 /* On a Pentium, resort to a trick */ #if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ (defined(__i386) || defined (_M_IX86) || defined(__i386__)) /* On a Microsoft compiler, use assembler */ #if defined(_MSC_VER) #define lua_number2int(i,d) __asm fld d __asm fistp i #define lua_number2integer(i,n) lua_number2int(i, n) /* the next trick should work on any Pentium, but sometimes clashes with a DirectX idiosyncrasy */ #else union luai_Cast { double l_d; long l_l; }; #define lua_number2int(i,d) \ { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } #define lua_number2integer(i,n) lua_number2int(i, n) #endif /* this option always works, but may be slow */ #else #define lua_number2int(i,d) ((i)=(int)(d)) #define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) #endif #else #define lua_number2int(i,d) ((i)=(int)(d)) #define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) #endif /* }================================================================== */ /* @@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. ** CHANGE it if your system requires alignments larger than double. (For ** instance, if your system supports long doubles and they must be ** aligned in 16-byte boundaries, then you should add long double in the ** union.) Probably you do not need to change this. */ #define LUAI_USER_ALIGNMENT_T grub_properly_aligned_t /* @@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. ** CHANGE them if you prefer to use longjmp/setjmp even with C++ ** or if want/don't to use _longjmp/_setjmp instead of regular ** longjmp/setjmp. By default, Lua handles errors with exceptions when ** compiling as C++ code, with _longjmp/_setjmp when asked to use them, ** and with longjmp/setjmp otherwise. */ #if defined(__cplusplus) /* C++ exceptions */ #define LUAI_THROW(L,c) throw(c) #define LUAI_TRY(L,c,a) try { a } catch(...) \ { if ((c)->status == 0) (c)->status = -1; } #define luai_jmpbuf int /* dummy variable */ #elif defined(LUA_USE_ULONGJMP) /* in Unix, try _longjmp/_setjmp (more efficient) */ #define LUAI_THROW(L,c) _longjmp((c)->b, 1) #define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } #define luai_jmpbuf jmp_buf #else /* default handling with long jumps */ #define LUAI_THROW(L,c) longjmp((c)->b, 1) #define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } #define luai_jmpbuf jmp_buf #endif /* @@ LUA_MAXCAPTURES is the maximum number of captures that a pattern @* can do during pattern-matching. ** CHANGE it if you need more captures. This limit is arbitrary. */ #define LUA_MAXCAPTURES 32 /* @@ lua_tmpnam is the function that the OS library uses to create a @* temporary name. @@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. ** CHANGE them if you have an alternative to tmpnam (which is considered ** insecure) or if you want the original tmpnam anyway. By default, Lua ** uses tmpnam except when POSIX is available, where it uses mkstemp. */ #if defined(loslib_c) || defined(luaall_c) #if defined(LUA_USE_MKSTEMP) #include #define LUA_TMPNAMBUFSIZE 32 #define lua_tmpnam(b,e) { \ strcpy(b, "/tmp/lua_XXXXXX"); \ e = mkstemp(b); \ if (e != -1) close(e); \ e = (e == -1); } #else #define LUA_TMPNAMBUFSIZE L_tmpnam #define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } #endif #endif /* @@ lua_popen spawns a new process connected to the current one through @* the file streams. ** CHANGE it if you have a way to implement it in your system. */ #if defined(LUA_USE_POPEN) #define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) #define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) #elif defined(LUA_WIN) #define lua_popen(L,c,m) ((void)L, _popen(c,m)) #define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) #else #define lua_popen(L,c,m) ((void)((void)c, m), \ luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) #define lua_pclose(L,file) ((void)((void)L, file), 0) #endif /* @@ LUA_DL_* define which dynamic-library system Lua should use. ** CHANGE here if Lua has problems choosing the appropriate ** dynamic-library system for your platform (either Windows' DLL, Mac's ** dyld, or Unix's dlopen). If your system is some kind of Unix, there ** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for ** it. To use dlopen you also need to adapt the src/Makefile (probably ** adding -ldl to the linker options), so Lua does not select it ** automatically. (When you change the makefile to add -ldl, you must ** also add -DLUA_USE_DLOPEN.) ** If you do not want any kind of dynamic library, undefine all these ** options. ** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. */ #if 0 #if defined(LUA_USE_DLOPEN) #define LUA_DL_DLOPEN #endif #if defined(LUA_WIN) #define LUA_DL_DLL #endif #endif /* @@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State @* (the data goes just *before* the lua_State pointer). ** CHANGE (define) this if you really need that. This value must be ** a multiple of the maximum alignment required for your machine. */ #define LUAI_EXTRASPACE 0 /* @@ luai_userstate* allow user-specific actions on threads. ** CHANGE them if you defined LUAI_EXTRASPACE and need to do something ** extra when a thread is created/deleted/resumed/yielded. */ #define luai_userstateopen(L) ((void)L) #define luai_userstateclose(L) ((void)L) #define luai_userstatethread(L,L1) ((void)L) #define luai_userstatefree(L) ((void)L) #define luai_userstateresume(L,n) ((void)L) #define luai_userstateyield(L,n) ((void)L) /* @@ LUA_INTFRMLEN is the length modifier for integer conversions @* in 'string.format'. @@ LUA_INTFRM_T is the integer type correspoding to the previous length @* modifier. ** CHANGE them if your system supports long long or does not support long. */ #if defined(LUA_USELONGLONG) #define LUA_INTFRMLEN "ll" #define LUA_INTFRM_T long long #else #define LUA_INTFRMLEN "l" #define LUA_INTFRM_T long #endif /* =================================================================== */ /* ** Local configuration. You can use this space to add your redefinitions ** without modifying the main part of the file. */ #endif debian/grub-extras/lua/lstrlib.c0000664000000000000000000005605212524662415014052 0ustar /* ** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ #if 0 #include #include #include #include #include #endif #define lstrlib_c #define LUA_LIB #include "lua.h" #include "lauxlib.h" #include "lualib.h" /* macro to `unsign' a character */ #define uchar(c) ((unsigned char)(c)) static int str_len (lua_State *L) { size_t l; luaL_checklstring(L, 1, &l); lua_pushinteger(L, l); return 1; } static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { /* relative string position: negative means back from end */ if (pos < 0) pos += (ptrdiff_t)len + 1; return (pos >= 0) ? pos : 0; } static int str_sub (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); if (start < 1) start = 1; if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; if (start <= end) lua_pushlstring(L, s+start-1, end-start+1); else lua_pushliteral(L, ""); return 1; } static int str_reverse (lua_State *L) { size_t l; luaL_Buffer b; const char *s = luaL_checklstring(L, 1, &l); luaL_buffinit(L, &b); while (l--) luaL_addchar(&b, s[l]); luaL_pushresult(&b); return 1; } static int str_lower (lua_State *L) { size_t l; size_t i; luaL_Buffer b; const char *s = luaL_checklstring(L, 1, &l); luaL_buffinit(L, &b); for (i=0; i 0) luaL_addlstring(&b, s, l); luaL_pushresult(&b); return 1; } static int str_byte (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); int n, i; if (posi <= 0) posi = 1; if ((size_t)pose > l) pose = l; if (posi > pose) return 0; /* empty interval; return no values */ n = (int)(pose - posi + 1); if (posi + n <= pose) /* overflow? */ luaL_error(L, "string slice too long"); luaL_checkstack(L, n, "string slice too long"); for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED) return luaL_error(ms->L, "invalid capture index"); return l; } static int capture_to_close (MatchState *ms) { int level = ms->level; for (level--; level>=0; level--) if (ms->capture[level].len == CAP_UNFINISHED) return level; return luaL_error(ms->L, "invalid pattern capture"); } static const char *classend (MatchState *ms, const char *p) { switch (*p++) { case L_ESC: { if (*p == '\0') luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); return p+1; } case '[': { if (*p == '^') p++; do { /* look for a `]' */ if (*p == '\0') luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); if (*(p++) == L_ESC && *p != '\0') p++; /* skip escapes (e.g. `%]') */ } while (*p != ']'); return p+1; } default: { return p; } } } static int match_class (int c, int cl) { int res; switch (tolower(cl)) { case 'a' : res = isalpha(c); break; case 'c' : res = iscntrl(c); break; case 'd' : res = isdigit(c); break; case 'l' : res = islower(c); break; case 'p' : res = ispunct(c); break; case 's' : res = isspace(c); break; case 'u' : res = isupper(c); break; case 'w' : res = isalnum(c); break; case 'x' : res = isxdigit(c); break; case 'z' : res = (c == 0); break; default: return (cl == c); } return (islower(cl) ? res : !res); } static int matchbracketclass (int c, const char *p, const char *ec) { int sig = 1; if (*(p+1) == '^') { sig = 0; p++; /* skip the `^' */ } while (++p < ec) { if (*p == L_ESC) { p++; if (match_class(c, uchar(*p))) return sig; } else if ((*(p+1) == '-') && (p+2 < ec)) { p+=2; if (uchar(*(p-2)) <= c && c <= uchar(*p)) return sig; } else if (uchar(*p) == c) return sig; } return !sig; } static int singlematch (int c, const char *p, const char *ep) { switch (*p) { case '.': return 1; /* matches any char */ case L_ESC: return match_class(c, uchar(*(p+1))); case '[': return matchbracketclass(c, p, ep-1); default: return (uchar(*p) == c); } } static const char *match (MatchState *ms, const char *s, const char *p); static const char *matchbalance (MatchState *ms, const char *s, const char *p) { if (*p == 0 || *(p+1) == 0) luaL_error(ms->L, "unbalanced pattern"); if (*s != *p) return NULL; else { int b = *p; int e = *(p+1); int cont = 1; while (++s < ms->src_end) { if (*s == e) { if (--cont == 0) return s+1; } else if (*s == b) cont++; } } return NULL; /* string ends out of balance */ } static const char *max_expand (MatchState *ms, const char *s, const char *p, const char *ep) { ptrdiff_t i = 0; /* counts maximum expand for item */ while ((s+i)src_end && singlematch(uchar(*(s+i)), p, ep)) i++; /* keeps trying to match with the maximum repetitions */ while (i>=0) { const char *res = match(ms, (s+i), ep+1); if (res) return res; i--; /* else didn't match; reduce 1 repetition to try again */ } return NULL; } static const char *min_expand (MatchState *ms, const char *s, const char *p, const char *ep) { for (;;) { const char *res = match(ms, s, ep+1); if (res != NULL) return res; else if (ssrc_end && singlematch(uchar(*s), p, ep)) s++; /* try with one more repetition */ else return NULL; } } static const char *start_capture (MatchState *ms, const char *s, const char *p, int what) { const char *res; int level = ms->level; if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); ms->capture[level].init = s; ms->capture[level].len = what; ms->level = level+1; if ((res=match(ms, s, p)) == NULL) /* match failed? */ ms->level--; /* undo capture */ return res; } static const char *end_capture (MatchState *ms, const char *s, const char *p) { int l = capture_to_close(ms); const char *res; ms->capture[l].len = s - ms->capture[l].init; /* close capture */ if ((res = match(ms, s, p)) == NULL) /* match failed? */ ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ return res; } static const char *match_capture (MatchState *ms, const char *s, int l) { size_t len; l = check_capture(ms, l); len = ms->capture[l].len; if ((size_t)(ms->src_end-s) >= len && memcmp(ms->capture[l].init, s, len) == 0) return s+len; else return NULL; } static const char *match (MatchState *ms, const char *s, const char *p) { init: /* using goto's to optimize tail recursion */ switch (*p) { case '(': { /* start capture */ if (*(p+1) == ')') /* position capture? */ return start_capture(ms, s, p+2, CAP_POSITION); else return start_capture(ms, s, p+1, CAP_UNFINISHED); } case ')': { /* end capture */ return end_capture(ms, s, p+1); } case L_ESC: { switch (*(p+1)) { case 'b': { /* balanced string? */ s = matchbalance(ms, s, p+2); if (s == NULL) return NULL; p+=4; goto init; /* else return match(ms, s, p+4); */ } case 'f': { /* frontier? */ const char *ep; char previous; p += 2; if (*p != '[') luaL_error(ms->L, "missing " LUA_QL("[") " after " LUA_QL("%%f") " in pattern"); ep = classend(ms, p); /* points to what is next */ previous = (s == ms->src_init) ? '\0' : *(s-1); if (matchbracketclass(uchar(previous), p, ep-1) || !matchbracketclass(uchar(*s), p, ep-1)) return NULL; p=ep; goto init; /* else return match(ms, s, ep); */ } default: { if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ s = match_capture(ms, s, uchar(*(p+1))); if (s == NULL) return NULL; p+=2; goto init; /* else return match(ms, s, p+2) */ } goto dflt; /* case default */ } } } case '\0': { /* end of pattern */ return s; /* match succeeded */ } case '$': { if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ return (s == ms->src_end) ? s : NULL; /* check end of string */ else goto dflt; } default: dflt: { /* it is a pattern item */ const char *ep = classend(ms, p); /* points to what is next */ int m = ssrc_end && singlematch(uchar(*s), p, ep); switch (*ep) { case '?': { /* optional */ const char *res; if (m && ((res=match(ms, s+1, ep+1)) != NULL)) return res; p=ep+1; goto init; /* else return match(ms, s, ep+1); */ } case '*': { /* 0 or more repetitions */ return max_expand(ms, s, p, ep); } case '+': { /* 1 or more repetitions */ return (m ? max_expand(ms, s+1, p, ep) : NULL); } case '-': { /* 0 or more repetitions (minimum) */ return min_expand(ms, s, p, ep); } default: { if (!m) return NULL; s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ } } } } } static const char *lmemfind (const char *s1, size_t l1, const char *s2, size_t l2) { if (l2 == 0) return s1; /* empty strings are everywhere */ else if (l2 > l1) return NULL; /* avoids a negative `l1' */ else { const char *init; /* to search for a `*s2' inside `s1' */ l2--; /* 1st char will be checked by `memchr' */ l1 = l1-l2; /* `s2' cannot be found after that */ while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { init++; /* 1st char is already checked */ if (memcmp(init, s2+1, l2) == 0) return init-1; else { /* correct `l1' and `s1' to try again */ l1 -= init-s1; s1 = init; } } return NULL; /* not found */ } } static void push_onecapture (MatchState *ms, int i, const char *s, const char *e) { if (i >= ms->level) { if (i == 0) /* ms->level == 0, too */ lua_pushlstring(ms->L, s, e - s); /* add whole match */ else luaL_error(ms->L, "invalid capture index"); } else { ptrdiff_t l = ms->capture[i].len; if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); if (l == CAP_POSITION) lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); else lua_pushlstring(ms->L, ms->capture[i].init, l); } } static int push_captures (MatchState *ms, const char *s, const char *e) { int i; int nlevels = (ms->level == 0 && s) ? 1 : ms->level; luaL_checkstack(ms->L, nlevels, "too many captures"); for (i = 0; i < nlevels; i++) push_onecapture(ms, i, s, e); return nlevels; /* number of strings pushed */ } static int str_find_aux (lua_State *L, int find) { size_t l1, l2; const char *s = luaL_checklstring(L, 1, &l1); const char *p = luaL_checklstring(L, 2, &l2); ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; if (init < 0) init = 0; else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; if (find && (lua_toboolean(L, 4) || /* explicit request? */ strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ /* do a plain search */ const char *s2 = lmemfind(s+init, l1-init, p, l2); if (s2) { lua_pushinteger(L, s2-s+1); lua_pushinteger(L, s2-s+l2); return 2; } } else { MatchState ms; int anchor = (*p == '^') ? (p++, 1) : 0; const char *s1=s+init; ms.L = L; ms.src_init = s; ms.src_end = s+l1; do { const char *res; ms.level = 0; if ((res=match(&ms, s1, p)) != NULL) { if (find) { lua_pushinteger(L, s1-s+1); /* start */ lua_pushinteger(L, res-s); /* end */ return push_captures(&ms, NULL, 0) + 2; } else return push_captures(&ms, s1, res); } } while (s1++ < ms.src_end && !anchor); } lua_pushnil(L); /* not found */ return 1; } static int str_find (lua_State *L) { return str_find_aux(L, 1); } static int str_match (lua_State *L) { return str_find_aux(L, 0); } static int gmatch_aux (lua_State *L) { MatchState ms; size_t ls; const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); const char *p = lua_tostring(L, lua_upvalueindex(2)); const char *src; ms.L = L; ms.src_init = s; ms.src_end = s+ls; for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); src <= ms.src_end; src++) { const char *e; ms.level = 0; if ((e = match(&ms, src, p)) != NULL) { lua_Integer newstart = e-s; if (e == src) newstart++; /* empty match? go at least one position */ lua_pushinteger(L, newstart); lua_replace(L, lua_upvalueindex(3)); return push_captures(&ms, src, e); } } return 0; /* not found */ } static int gmatch (lua_State *L) { luaL_checkstring(L, 1); luaL_checkstring(L, 2); lua_settop(L, 2); lua_pushinteger(L, 0); lua_pushcclosure(L, gmatch_aux, 3); return 1; } static int gfind_nodef (lua_State *L) { return luaL_error(L, LUA_QL("string.gfind") " was renamed to " LUA_QL("string.gmatch")); } static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, const char *e) { size_t l, i; const char *news = lua_tolstring(ms->L, 3, &l); for (i = 0; i < l; i++) { if (news[i] != L_ESC) luaL_addchar(b, news[i]); else { i++; /* skip ESC */ if (!isdigit(uchar(news[i]))) luaL_addchar(b, news[i]); else if (news[i] == '0') luaL_addlstring(b, s, e - s); else { push_onecapture(ms, news[i] - '1', s, e); luaL_addvalue(b); /* add capture to accumulated result */ } } } } static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, const char *e) { lua_State *L = ms->L; switch (lua_type(L, 3)) { case LUA_TNUMBER: case LUA_TSTRING: { add_s(ms, b, s, e); return; } case LUA_TFUNCTION: { int n; lua_pushvalue(L, 3); n = push_captures(ms, s, e); lua_call(L, n, 1); break; } case LUA_TTABLE: { push_onecapture(ms, 0, s, e); lua_gettable(L, 3); break; } } if (!lua_toboolean(L, -1)) { /* nil or false? */ lua_pop(L, 1); lua_pushlstring(L, s, e - s); /* keep original text */ } else if (!lua_isstring(L, -1)) luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); luaL_addvalue(b); /* add result to accumulator */ } static int str_gsub (lua_State *L) { size_t srcl; const char *src = luaL_checklstring(L, 1, &srcl); const char *p = luaL_checkstring(L, 2); int tr = lua_type(L, 3); int max_s = luaL_optint(L, 4, srcl+1); int anchor = (*p == '^') ? (p++, 1) : 0; int n = 0; MatchState ms; luaL_Buffer b; luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, "string/function/table expected"); luaL_buffinit(L, &b); ms.L = L; ms.src_init = src; ms.src_end = src+srcl; while (n < max_s) { const char *e; ms.level = 0; e = match(&ms, src, p); if (e) { n++; add_value(&ms, &b, src, e); } if (e && e>src) /* non empty match? */ src = e; /* skip it */ else if (src < ms.src_end) luaL_addchar(&b, *src++); else break; if (anchor) break; } luaL_addlstring(&b, src, ms.src_end-src); luaL_pushresult(&b); lua_pushinteger(L, n); /* number of substitutions */ return 2; } /* }====================================================== */ /* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ #define MAX_ITEM 512 /* valid flags in a format specification */ #define FLAGS "-+ #0" /* ** maximum size of each format specification (such as '%-099.99d') ** (+10 accounts for %99.99x plus margin of error) */ #define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { size_t l; const char *s = luaL_checklstring(L, arg, &l); luaL_addchar(b, '"'); while (l--) { switch (*s) { case '"': case '\\': case '\n': { luaL_addchar(b, '\\'); luaL_addchar(b, *s); break; } case '\r': { luaL_addlstring(b, "\\r", 2); break; } case '\0': { luaL_addlstring(b, "\\000", 4); break; } default: { luaL_addchar(b, *s); break; } } s++; } luaL_addchar(b, '"'); } static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { const char *p = strfrmt; while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) luaL_error(L, "invalid format (repeated flags)"); if (isdigit(uchar(*p))) p++; /* skip width */ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ if (*p == '.') { p++; if (isdigit(uchar(*p))) p++; /* skip precision */ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ } if (isdigit(uchar(*p))) luaL_error(L, "invalid format (width or precision too long)"); *(form++) = '%'; strncpy(form, strfrmt, p - strfrmt + 1); form += p - strfrmt + 1; *form = '\0'; return p; } static void addintlen (char *form) { size_t l = strlen(form); char spec = form[l - 1]; strcpy(form + l - 1, LUA_INTFRMLEN); form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; } static int str_format (lua_State *L) { int arg = 1; size_t sfl; const char *strfrmt = luaL_checklstring(L, arg, &sfl); const char *strfrmt_end = strfrmt+sfl; luaL_Buffer b; luaL_buffinit(L, &b); while (strfrmt < strfrmt_end) { if (*strfrmt != L_ESC) luaL_addchar(&b, *strfrmt++); else if (*++strfrmt == L_ESC) luaL_addchar(&b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format (`%...') */ char buff[MAX_ITEM]; /* to store the formatted item */ arg++; strfrmt = scanformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { snprintf(buff, sizeof (buff), form, (int)luaL_checknumber(L, arg)); break; } case 'd': case 'i': { addintlen(form); snprintf(buff, sizeof (buff), form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); break; } case 'o': case 'u': case 'x': case 'X': { addintlen(form); snprintf(buff, sizeof (buff), form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); break; } #if 0 case 'e': case 'E': case 'f': case 'g': case 'G': { snprintf(buff, sizeof (buff), form, (double)luaL_checknumber(L, arg)); break; } #endif case 'q': { addquoted(L, &b, arg); continue; /* skip the 'addsize' at the end */ } case 's': { size_t l; const char *s = luaL_checklstring(L, arg, &l); if (!strchr(form, '.') && l >= 100) { /* no precision and string is too long to be formatted; keep original string */ lua_pushvalue(L, arg); luaL_addvalue(&b); continue; /* skip the `addsize' at the end */ } else { snprintf(buff, sizeof (buff), form, s); break; } } default: { /* also treat cases `pnLlh' */ return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " LUA_QL("format"), *(strfrmt - 1)); } } luaL_addlstring(&b, buff, strlen(buff)); } } luaL_pushresult(&b); return 1; } static const luaL_Reg strlib[] = { {"byte", str_byte}, {"char", str_char}, {"dump", str_dump}, {"find", str_find}, {"format", str_format}, {"gfind", gfind_nodef}, {"gmatch", gmatch}, {"gsub", str_gsub}, {"len", str_len}, {"lower", str_lower}, {"match", str_match}, {"rep", str_rep}, {"reverse", str_reverse}, {"sub", str_sub}, {"upper", str_upper}, {NULL, NULL} }; static void createmetatable (lua_State *L) { lua_createtable(L, 0, 1); /* create metatable for strings */ lua_pushliteral(L, ""); /* dummy string */ lua_pushvalue(L, -2); lua_setmetatable(L, -2); /* set string metatable */ lua_pop(L, 1); /* pop dummy string */ lua_pushvalue(L, -2); /* string library... */ lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ lua_pop(L, 1); /* pop metatable */ } /* ** Open string library */ LUALIB_API int luaopen_string (lua_State *L) { luaL_register(L, LUA_STRLIBNAME, strlib); #if defined(LUA_COMPAT_GFIND) lua_getfield(L, -1, "gmatch"); lua_setfield(L, -2, "gfind"); #endif createmetatable(L); return 1; } debian/grub-extras/lua/llex.h0000664000000000000000000000420112524662415013335 0ustar /* ** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ #ifndef llex_h #define llex_h #include "lobject.h" #include "lzio.h" #define FIRST_RESERVED 257 /* maximum length of a reserved word */ #define TOKEN_LEN (sizeof("function")/sizeof(char)) /* * WARNING: if you change the order of this enumeration, * grep "ORDER RESERVED" */ enum RESERVED { /* terminal symbols denoted by reserved words */ TK_AND = FIRST_RESERVED, TK_BREAK, TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, /* other terminal symbols */ TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, TK_NAME, TK_STRING, TK_EOS }; /* number of reserved words */ #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) /* array with token `names' */ LUAI_DATA const char *const luaX_tokens []; typedef union { lua_Number r; TString *ts; } SemInfo; /* semantics information */ typedef struct Token { int token; SemInfo seminfo; } Token; typedef struct LexState { int current; /* current character (charint) */ int linenumber; /* input line counter */ int lastline; /* line of last token `consumed' */ Token t; /* current token */ Token lookahead; /* look ahead token */ struct FuncState *fs; /* `FuncState' is private to the parser */ struct lua_State *L; ZIO *z; /* input stream */ Mbuffer *buff; /* buffer for tokens */ TString *source; /* current source name */ char decpoint; /* locale decimal point */ } LexState; LUAI_FUNC void luaX_init (lua_State *L); LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source); LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); LUAI_FUNC void luaX_next (LexState *ls); LUAI_FUNC void luaX_lookahead (LexState *ls); LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); #endif debian/grub-extras/lua/lstring.h0000664000000000000000000000145612524662415014064 0ustar /* ** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ #ifndef lstring_h #define lstring_h #include "lgc.h" #include "lobject.h" #include "lstate.h" #define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) #define sizeudata(u) (sizeof(union Udata)+(u)->len) #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ (sizeof(s)/sizeof(char))-1)) #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) LUAI_FUNC void luaS_resize (lua_State *L, int newsize); LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); #endif debian/grub-extras/lua/lstate.h0000664000000000000000000001162312524662415013673 0ustar /* ** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ #ifndef lstate_h #define lstate_h #include "lua.h" #include "lobject.h" #include "ltm.h" #include "lzio.h" struct lua_longjmp; /* defined in ldo.c */ /* table of globals */ #define gt(L) (&L->l_gt) /* registry */ #define registry(L) (&G(L)->l_registry) /* extra stack space to handle TM calls and some other extras */ #define EXTRA_STACK 5 #define BASIC_CI_SIZE 8 #define BASIC_STACK_SIZE (2*LUA_MINSTACK) typedef struct stringtable { GCObject **hash; lu_int32 nuse; /* number of elements */ int size; } stringtable; /* ** informations about a call */ typedef struct CallInfo { StkId base; /* base for this function */ StkId func; /* function index in the stack */ StkId top; /* top for this function */ const Instruction *savedpc; int nresults; /* expected number of results from this function */ int tailcalls; /* number of tail calls lost under this entry */ } CallInfo; #define curr_func(L) (clvalue(L->ci->func)) #define ci_func(ci) (clvalue((ci)->func)) #define f_isLua(ci) (!ci_func(ci)->c.isC) #define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) /* ** `global state', shared by all threads of this state */ typedef struct global_State { stringtable strt; /* hash table for strings */ lua_Alloc frealloc; /* function to reallocate memory */ void *ud; /* auxiliary data to `frealloc' */ lu_byte currentwhite; lu_byte gcstate; /* state of garbage collector */ int sweepstrgc; /* position of sweep in `strt' */ GCObject *rootgc; /* list of all collectable objects */ GCObject **sweepgc; /* position of sweep in `rootgc' */ GCObject *gray; /* list of gray objects */ GCObject *grayagain; /* list of objects to be traversed atomically */ GCObject *weak; /* list of weak tables (to be cleared) */ GCObject *tmudata; /* last element of list of userdata to be GC */ Mbuffer buff; /* temporary buffer for string concatentation */ lu_mem GCthreshold; lu_mem totalbytes; /* number of bytes currently allocated */ lu_mem estimate; /* an estimate of number of bytes actually in use */ lu_mem gcdept; /* how much GC is `behind schedule' */ int gcpause; /* size of pause between successive GCs */ int gcstepmul; /* GC `granularity' */ lua_CFunction panic; /* to be called in unprotected errors */ TValue l_registry; struct lua_State *mainthread; UpVal uvhead; /* head of double-linked list of all open upvalues */ struct Table *mt[NUM_TAGS]; /* metatables for basic types */ TString *tmname[TM_N]; /* array with tag-method names */ } global_State; /* ** `per thread' state */ struct lua_State { CommonHeader; lu_byte status; StkId top; /* first free slot in the stack */ StkId base; /* base of current function */ global_State *l_G; CallInfo *ci; /* call info for current function */ const Instruction *savedpc; /* `savedpc' of current function */ StkId stack_last; /* last free slot in the stack */ StkId stack; /* stack base */ CallInfo *end_ci; /* points after end of ci array*/ CallInfo *base_ci; /* array of CallInfo's */ int stacksize; int size_ci; /* size of array `base_ci' */ unsigned short nCcalls; /* number of nested C calls */ unsigned short baseCcalls; /* nested C calls when resuming coroutine */ lu_byte hookmask; lu_byte allowhook; int basehookcount; int hookcount; lua_Hook hook; TValue l_gt; /* table of globals */ TValue env; /* temporary place for environments */ GCObject *openupval; /* list of open upvalues in this stack */ GCObject *gclist; struct lua_longjmp *errorJmp; /* current error recover point */ ptrdiff_t errfunc; /* current error handling function (stack index) */ }; #define G(L) (L->l_G) /* ** Union of all collectable objects */ union GCObject { GCheader gch; union TString ts; union Udata u; union Closure cl; struct Table h; struct Proto p; struct UpVal uv; struct lua_State th; /* thread */ }; /* macros to convert a GCObject into a specific value */ #define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) #define gco2ts(o) (&rawgco2ts(o)->tsv) #define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) #define gco2u(o) (&rawgco2u(o)->uv) #define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) #define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) #define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) #define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) #define ngcotouv(o) \ check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) /* macro to convert any Lua object into a GCObject */ #define obj2gco(v) (cast(GCObject *, (v))) LUAI_FUNC lua_State *luaE_newthread (lua_State *L); LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); #endif debian/grub-extras/lua/linit.c0000664000000000000000000000140712524662415013510 0ustar /* ** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ ** Initialization of libraries for lua.c ** See Copyright Notice in lua.h */ #define linit_c #define LUA_LIB #include "lua.h" #include "lualib.h" #include "lauxlib.h" static const luaL_Reg lualibs[] = { {"", luaopen_base}, // {LUA_LOADLIBNAME, luaopen_package}, {LUA_TABLIBNAME, luaopen_table}, // {LUA_IOLIBNAME, luaopen_io}, // {LUA_OSLIBNAME, luaopen_os}, {LUA_STRLIBNAME, luaopen_string}, // {LUA_MATHLIBNAME, luaopen_math}, // {LUA_DBLIBNAME, luaopen_debug}, {NULL, NULL} }; LUALIB_API void luaL_openlibs (lua_State *L) { const luaL_Reg *lib = lualibs; for (; lib->func; lib++) { lua_pushcfunction(L, lib->func); lua_pushstring(L, lib->name); lua_call(L, 1, 0); } } debian/grub-extras/lua/lparser.c0000664000000000000000000010754412524662415014052 0ustar /* ** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ #if 0 #include #endif #define lparser_c #define LUA_CORE #include "lua.h" #include "lcode.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "llex.h" #include "lmem.h" #include "lobject.h" #include "lopcodes.h" #include "lparser.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #define hasmultret(k) ((k) == VCALL || (k) == VVARARG) #define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) #define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) /* ** nodes for block list (list of active blocks) */ typedef struct BlockCnt { struct BlockCnt *previous; /* chain */ int breaklist; /* list of jumps out of this loop */ lu_byte nactvar; /* # active locals outside the breakable structure */ lu_byte upval; /* true if some variable in the block is an upvalue */ lu_byte isbreakable; /* true if `block' is a loop */ } BlockCnt; /* ** prototypes for recursive non-terminal functions */ static void chunk (LexState *ls); static void expr (LexState *ls, expdesc *v); static void anchor_token (LexState *ls) { if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { TString *ts = ls->t.seminfo.ts; luaX_newstring(ls, getstr(ts), ts->tsv.len); } } static void error_expected (LexState *ls, int token) { luaX_syntaxerror(ls, luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); } static void errorlimit (FuncState *fs, int limit, const char *what) { const char *msg = (fs->f->linedefined == 0) ? luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : luaO_pushfstring(fs->L, "function at line %d has more than %d %s", fs->f->linedefined, limit, what); luaX_lexerror(fs->ls, msg, 0); } static int testnext (LexState *ls, int c) { if (ls->t.token == c) { luaX_next(ls); return 1; } else return 0; } static void check (LexState *ls, int c) { if (ls->t.token != c) error_expected(ls, c); } static void checknext (LexState *ls, int c) { check(ls, c); luaX_next(ls); } #define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } static void check_match (LexState *ls, int what, int who, int where) { if (!testnext(ls, what)) { if (where == ls->linenumber) error_expected(ls, what); else { luaX_syntaxerror(ls, luaO_pushfstring(ls->L, LUA_QS " expected (to close " LUA_QS " at line %d)", luaX_token2str(ls, what), luaX_token2str(ls, who), where)); } } } static TString *str_checkname (LexState *ls) { TString *ts; check(ls, TK_NAME); ts = ls->t.seminfo.ts; luaX_next(ls); return ts; } static void init_exp (expdesc *e, expkind k, int i) { e->f = e->t = NO_JUMP; e->k = k; e->u.s.info = i; } static void codestring (LexState *ls, expdesc *e, TString *s) { init_exp(e, VK, luaK_stringK(ls->fs, s)); } static void checkname(LexState *ls, expdesc *e) { codestring(ls, e, str_checkname(ls)); } static int registerlocalvar (LexState *ls, TString *varname) { FuncState *fs = ls->fs; Proto *f = fs->f; int oldsize = f->sizelocvars; luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, LocVar, SHRT_MAX, "too many local variables"); while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; f->locvars[fs->nlocvars].varname = varname; luaC_objbarrier(ls->L, f, varname); return fs->nlocvars++; } #define new_localvarliteral(ls,v,n) \ new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) static void new_localvar (LexState *ls, TString *name, int n) { FuncState *fs = ls->fs; luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); } static void adjustlocalvars (LexState *ls, int nvars) { FuncState *fs = ls->fs; fs->nactvar = cast_byte(fs->nactvar + nvars); for (; nvars; nvars--) { getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; } } static void removevars (LexState *ls, int tolevel) { FuncState *fs = ls->fs; while (fs->nactvar > tolevel) getlocvar(fs, --fs->nactvar).endpc = fs->pc; } static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { int i; Proto *f = fs->f; int oldsize = f->sizeupvalues; for (i=0; inups; i++) { if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { lua_assert(f->upvalues[i] == name); return i; } } /* new one */ luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, TString *, MAX_INT, ""); while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; f->upvalues[f->nups] = name; luaC_objbarrier(fs->L, f, name); lua_assert(v->k == VLOCAL || v->k == VUPVAL); fs->upvalues[f->nups].k = cast_byte(v->k); fs->upvalues[f->nups].info = cast_byte(v->u.s.info); return f->nups++; } static int searchvar (FuncState *fs, TString *n) { int i; for (i=fs->nactvar-1; i >= 0; i--) { if (n == getlocvar(fs, i).varname) return i; } return -1; /* not found */ } static void markupval (FuncState *fs, int level) { BlockCnt *bl = fs->bl; while (bl && bl->nactvar > level) bl = bl->previous; if (bl) bl->upval = 1; } static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { if (fs == NULL) { /* no more levels? */ init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ return VGLOBAL; } else { int v = searchvar(fs, n); /* look up at current level */ if (v >= 0) { init_exp(var, VLOCAL, v); if (!base) markupval(fs, v); /* local will be used as an upval */ return VLOCAL; } else { /* not found at current level; try upper one */ if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) return VGLOBAL; var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ var->k = VUPVAL; /* upvalue in this level */ return VUPVAL; } } } static void singlevar (LexState *ls, expdesc *var) { TString *varname = str_checkname(ls); FuncState *fs = ls->fs; if (singlevaraux(fs, varname, var, 1) == VGLOBAL) var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ } static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { FuncState *fs = ls->fs; int extra = nvars - nexps; if (hasmultret(e->k)) { extra++; /* includes call itself */ if (extra < 0) extra = 0; luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ if (extra > 1) luaK_reserveregs(fs, extra-1); } else { if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ if (extra > 0) { int reg = fs->freereg; luaK_reserveregs(fs, extra); luaK_nil(fs, reg, extra); } } } static void enterlevel (LexState *ls) { if (++ls->L->nCcalls > LUAI_MAXCCALLS) luaX_lexerror(ls, "chunk has too many syntax levels", 0); } #define leavelevel(ls) ((ls)->L->nCcalls--) static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { bl->breaklist = NO_JUMP; bl->isbreakable = isbreakable; bl->nactvar = fs->nactvar; bl->upval = 0; bl->previous = fs->bl; fs->bl = bl; lua_assert(fs->freereg == fs->nactvar); } static void leaveblock (FuncState *fs) { BlockCnt *bl = fs->bl; fs->bl = bl->previous; removevars(fs->ls, bl->nactvar); if (bl->upval) luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); /* a block either controls scope or breaks (never both) */ lua_assert(!bl->isbreakable || !bl->upval); lua_assert(bl->nactvar == fs->nactvar); fs->freereg = fs->nactvar; /* free registers */ luaK_patchtohere(fs, bl->breaklist); } static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { FuncState *fs = ls->fs; Proto *f = fs->f; int oldsize = f->sizep; int i; luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "constant table overflow"); while (oldsize < f->sizep) f->p[oldsize++] = NULL; f->p[fs->np++] = func->f; luaC_objbarrier(ls->L, f, func->f); init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); for (i=0; if->nups; i++) { OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); } } static void open_func (LexState *ls, FuncState *fs) { lua_State *L = ls->L; Proto *f = luaF_newproto(L); fs->f = f; fs->prev = ls->fs; /* linked list of funcstates */ fs->ls = ls; fs->L = L; ls->fs = fs; fs->pc = 0; fs->lasttarget = -1; fs->jpc = NO_JUMP; fs->freereg = 0; fs->nk = 0; fs->np = 0; fs->nlocvars = 0; fs->nactvar = 0; fs->bl = NULL; f->source = ls->source; f->maxstacksize = 2; /* registers 0/1 are always valid */ fs->h = luaH_new(L, 0, 0); /* anchor table of constants and prototype (to avoid being collected) */ sethvalue2s(L, L->top, fs->h); incr_top(L); setptvalue2s(L, L->top, f); incr_top(L); } static void close_func (LexState *ls) { lua_State *L = ls->L; FuncState *fs = ls->fs; Proto *f = fs->f; removevars(ls, 0); luaK_ret(fs, 0, 0); /* final return */ luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); f->sizecode = fs->pc; luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); f->sizelineinfo = fs->pc; luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); f->sizek = fs->nk; luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); f->sizep = fs->np; luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); f->sizelocvars = fs->nlocvars; luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); f->sizeupvalues = f->nups; lua_assert(luaG_checkcode(f)); lua_assert(fs->bl == NULL); ls->fs = fs->prev; L->top -= 2; /* remove table and prototype from the stack */ /* last token read was anchored in defunct function; must reanchor it */ if (fs) anchor_token(ls); } Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { struct LexState lexstate; struct FuncState funcstate; lexstate.buff = buff; luaX_setinput(L, &lexstate, z, luaS_new(L, name)); open_func(&lexstate, &funcstate); funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ luaX_next(&lexstate); /* read first token */ chunk(&lexstate); check(&lexstate, TK_EOS); close_func(&lexstate); lua_assert(funcstate.prev == NULL); lua_assert(funcstate.f->nups == 0); lua_assert(lexstate.fs == NULL); return funcstate.f; } /*============================================================*/ /* GRAMMAR RULES */ /*============================================================*/ static void field (LexState *ls, expdesc *v) { /* field -> ['.' | ':'] NAME */ FuncState *fs = ls->fs; expdesc key; luaK_exp2anyreg(fs, v); luaX_next(ls); /* skip the dot or colon */ checkname(ls, &key); luaK_indexed(fs, v, &key); } static void yindex (LexState *ls, expdesc *v) { /* index -> '[' expr ']' */ luaX_next(ls); /* skip the '[' */ expr(ls, v); luaK_exp2val(ls->fs, v); checknext(ls, ']'); } /* ** {====================================================================== ** Rules for Constructors ** ======================================================================= */ struct ConsControl { expdesc v; /* last list item read */ expdesc *t; /* table descriptor */ int nh; /* total number of `record' elements */ int na; /* total number of array elements */ int tostore; /* number of array elements pending to be stored */ }; static void recfield (LexState *ls, struct ConsControl *cc) { /* recfield -> (NAME | `['exp1`]') = exp1 */ FuncState *fs = ls->fs; int reg = ls->fs->freereg; expdesc key, val; int rkkey; if (ls->t.token == TK_NAME) { luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); checkname(ls, &key); } else /* ls->t.token == '[' */ yindex(ls, &key); cc->nh++; checknext(ls, '='); rkkey = luaK_exp2RK(fs, &key); expr(ls, &val); luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); fs->freereg = reg; /* free registers */ } static void closelistfield (FuncState *fs, struct ConsControl *cc) { if (cc->v.k == VVOID) return; /* there is no list item */ luaK_exp2nextreg(fs, &cc->v); cc->v.k = VVOID; if (cc->tostore == LFIELDS_PER_FLUSH) { luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ cc->tostore = 0; /* no more items pending */ } } static void lastlistfield (FuncState *fs, struct ConsControl *cc) { if (cc->tostore == 0) return; if (hasmultret(cc->v.k)) { luaK_setmultret(fs, &cc->v); luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); cc->na--; /* do not count last expression (unknown number of elements) */ } else { if (cc->v.k != VVOID) luaK_exp2nextreg(fs, &cc->v); luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); } } static void listfield (LexState *ls, struct ConsControl *cc) { expr(ls, &cc->v); luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); cc->na++; cc->tostore++; } static void constructor (LexState *ls, expdesc *t) { /* constructor -> ?? */ FuncState *fs = ls->fs; int line = ls->linenumber; int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); struct ConsControl cc; cc.na = cc.nh = cc.tostore = 0; cc.t = t; init_exp(t, VRELOCABLE, pc); init_exp(&cc.v, VVOID, 0); /* no value (yet) */ luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ checknext(ls, '{'); do { lua_assert(cc.v.k == VVOID || cc.tostore > 0); if (ls->t.token == '}') break; closelistfield(fs, &cc); switch(ls->t.token) { case TK_NAME: { /* may be listfields or recfields */ luaX_lookahead(ls); if (ls->lookahead.token != '=') /* expression? */ listfield(ls, &cc); else recfield(ls, &cc); break; } case '[': { /* constructor_item -> recfield */ recfield(ls, &cc); break; } default: { /* constructor_part -> listfield */ listfield(ls, &cc); break; } } } while (testnext(ls, ',') || testnext(ls, ';')); check_match(ls, '}', '{', line); lastlistfield(fs, &cc); SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ } /* }====================================================================== */ static void parlist (LexState *ls) { /* parlist -> [ param { `,' param } ] */ FuncState *fs = ls->fs; Proto *f = fs->f; int nparams = 0; f->is_vararg = 0; if (ls->t.token != ')') { /* is `parlist' not empty? */ do { switch (ls->t.token) { case TK_NAME: { /* param -> NAME */ new_localvar(ls, str_checkname(ls), nparams++); break; } case TK_DOTS: { /* param -> `...' */ luaX_next(ls); #if defined(LUA_COMPAT_VARARG) /* use `arg' as default name */ new_localvarliteral(ls, "arg", nparams++); f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; #endif f->is_vararg |= VARARG_ISVARARG; break; } default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); } } while (!f->is_vararg && testnext(ls, ',')); } adjustlocalvars(ls, nparams); f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ } static void body (LexState *ls, expdesc *e, int needself, int line) { /* body -> `(' parlist `)' chunk END */ FuncState new_fs; open_func(ls, &new_fs); new_fs.f->linedefined = line; checknext(ls, '('); if (needself) { new_localvarliteral(ls, "self", 0); adjustlocalvars(ls, 1); } parlist(ls); checknext(ls, ')'); chunk(ls); new_fs.f->lastlinedefined = ls->linenumber; check_match(ls, TK_END, TK_FUNCTION, line); close_func(ls); pushclosure(ls, &new_fs, e); } static int explist1 (LexState *ls, expdesc *v) { /* explist1 -> expr { `,' expr } */ int n = 1; /* at least one expression */ expr(ls, v); while (testnext(ls, ',')) { luaK_exp2nextreg(ls->fs, v); expr(ls, v); n++; } return n; } static void funcargs (LexState *ls, expdesc *f) { FuncState *fs = ls->fs; expdesc args; int base, nparams; int line = ls->linenumber; switch (ls->t.token) { case '(': { /* funcargs -> `(' [ explist1 ] `)' */ if (line != ls->lastline) luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); luaX_next(ls); if (ls->t.token == ')') /* arg list is empty? */ args.k = VVOID; else { explist1(ls, &args); luaK_setmultret(fs, &args); } check_match(ls, ')', '(', line); break; } case '{': { /* funcargs -> constructor */ constructor(ls, &args); break; } case TK_STRING: { /* funcargs -> STRING */ codestring(ls, &args, ls->t.seminfo.ts); luaX_next(ls); /* must use `seminfo' before `next' */ break; } default: { luaX_syntaxerror(ls, "function arguments expected"); return; } } lua_assert(f->k == VNONRELOC); base = f->u.s.info; /* base register for call */ if (hasmultret(args.k)) nparams = LUA_MULTRET; /* open call */ else { if (args.k != VVOID) luaK_exp2nextreg(fs, &args); /* close last argument */ nparams = fs->freereg - (base+1); } init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); luaK_fixline(fs, line); fs->freereg = base+1; /* call remove function and arguments and leaves (unless changed) one result */ } /* ** {====================================================================== ** Expression parsing ** ======================================================================= */ static void prefixexp (LexState *ls, expdesc *v) { /* prefixexp -> NAME | '(' expr ')' */ switch (ls->t.token) { case '(': { int line = ls->linenumber; luaX_next(ls); expr(ls, v); check_match(ls, ')', '(', line); luaK_dischargevars(ls->fs, v); return; } case TK_NAME: { singlevar(ls, v); return; } default: { luaX_syntaxerror(ls, "unexpected symbol"); return; } } } static void primaryexp (LexState *ls, expdesc *v) { /* primaryexp -> prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ FuncState *fs = ls->fs; prefixexp(ls, v); for (;;) { switch (ls->t.token) { case '.': { /* field */ field(ls, v); break; } case '[': { /* `[' exp1 `]' */ expdesc key; luaK_exp2anyreg(fs, v); yindex(ls, &key); luaK_indexed(fs, v, &key); break; } case ':': { /* `:' NAME funcargs */ expdesc key; luaX_next(ls); checkname(ls, &key); luaK_self(fs, v, &key); funcargs(ls, v); break; } case '(': case TK_STRING: case '{': { /* funcargs */ luaK_exp2nextreg(fs, v); funcargs(ls, v); break; } default: return; } } } static void simpleexp (LexState *ls, expdesc *v) { /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | constructor | FUNCTION body | primaryexp */ switch (ls->t.token) { case TK_NUMBER: { init_exp(v, VKNUM, 0); v->u.nval = ls->t.seminfo.r; break; } case TK_STRING: { codestring(ls, v, ls->t.seminfo.ts); break; } case TK_NIL: { init_exp(v, VNIL, 0); break; } case TK_TRUE: { init_exp(v, VTRUE, 0); break; } case TK_FALSE: { init_exp(v, VFALSE, 0); break; } case TK_DOTS: { /* vararg */ FuncState *fs = ls->fs; check_condition(ls, fs->f->is_vararg, "cannot use " LUA_QL("...") " outside a vararg function"); fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); break; } case '{': { /* constructor */ constructor(ls, v); return; } case TK_FUNCTION: { luaX_next(ls); body(ls, v, 0, ls->linenumber); return; } default: { primaryexp(ls, v); return; } } luaX_next(ls); } static UnOpr getunopr (int op) { switch (op) { case TK_NOT: return OPR_NOT; case '-': return OPR_MINUS; case '#': return OPR_LEN; default: return OPR_NOUNOPR; } } static BinOpr getbinopr (int op) { switch (op) { case '+': return OPR_ADD; case '-': return OPR_SUB; case '*': return OPR_MUL; case '/': return OPR_DIV; case '%': return OPR_MOD; case '^': return OPR_POW; case TK_CONCAT: return OPR_CONCAT; case TK_NE: return OPR_NE; case TK_EQ: return OPR_EQ; case '<': return OPR_LT; case TK_LE: return OPR_LE; case '>': return OPR_GT; case TK_GE: return OPR_GE; case TK_AND: return OPR_AND; case TK_OR: return OPR_OR; default: return OPR_NOBINOPR; } } static const struct { lu_byte left; /* left priority for each binary operator */ lu_byte right; /* right priority */ } priority[] = { /* ORDER OPR */ {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ {10, 9}, {5, 4}, /* power and concat (right associative) */ {3, 3}, {3, 3}, /* equality and inequality */ {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ {2, 2}, {1, 1} /* logical (and/or) */ }; #define UNARY_PRIORITY 8 /* priority for unary operators */ /* ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } ** where `binop' is any binary operator with a priority higher than `limit' */ static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { BinOpr op; UnOpr uop; enterlevel(ls); uop = getunopr(ls->t.token); if (uop != OPR_NOUNOPR) { luaX_next(ls); subexpr(ls, v, UNARY_PRIORITY); luaK_prefix(ls->fs, uop, v); } else simpleexp(ls, v); /* expand while operators have priorities higher than `limit' */ op = getbinopr(ls->t.token); while (op != OPR_NOBINOPR && priority[op].left > limit) { expdesc v2; BinOpr nextop; luaX_next(ls); luaK_infix(ls->fs, op, v); /* read sub-expression with higher priority */ nextop = subexpr(ls, &v2, priority[op].right); luaK_posfix(ls->fs, op, v, &v2); op = nextop; } leavelevel(ls); return op; /* return first untreated operator */ } static void expr (LexState *ls, expdesc *v) { subexpr(ls, v, 0); } /* }==================================================================== */ /* ** {====================================================================== ** Rules for Statements ** ======================================================================= */ static int block_follow (int token) { switch (token) { case TK_ELSE: case TK_ELSEIF: case TK_END: case TK_UNTIL: case TK_EOS: return 1; default: return 0; } } static void block (LexState *ls) { /* block -> chunk */ FuncState *fs = ls->fs; BlockCnt bl; enterblock(fs, &bl, 0); chunk(ls); lua_assert(bl.breaklist == NO_JUMP); leaveblock(fs); } /* ** structure to chain all variables in the left-hand side of an ** assignment */ struct LHS_assign { struct LHS_assign *prev; expdesc v; /* variable (global, local, upvalue, or indexed) */ }; /* ** check whether, in an assignment to a local variable, the local variable ** is needed in a previous assignment (to a table). If so, save original ** local value in a safe place and use this safe copy in the previous ** assignment. */ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { FuncState *fs = ls->fs; int extra = fs->freereg; /* eventual position to save local variable */ int conflict = 0; for (; lh; lh = lh->prev) { if (lh->v.k == VINDEXED) { if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ conflict = 1; lh->v.u.s.info = extra; /* previous assignment will use safe copy */ } if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ conflict = 1; lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ } } } if (conflict) { luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ luaK_reserveregs(fs, 1); } } static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { expdesc e; check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, "syntax error"); if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ struct LHS_assign nv; nv.prev = lh; primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, "variables in assignment"); assignment(ls, &nv, nvars+1); } else { /* assignment -> `=' explist1 */ int nexps; checknext(ls, '='); nexps = explist1(ls, &e); if (nexps != nvars) { adjust_assign(ls, nvars, nexps, &e); if (nexps > nvars) ls->fs->freereg -= nexps - nvars; /* remove extra values */ } else { luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_storevar(ls->fs, &lh->v, &e); return; /* avoid default */ } } init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ luaK_storevar(ls->fs, &lh->v, &e); } static int cond (LexState *ls) { /* cond -> exp */ expdesc v; expr(ls, &v); /* read condition */ if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ luaK_goiftrue(ls->fs, &v); return v.f; } static void breakstat (LexState *ls) { FuncState *fs = ls->fs; BlockCnt *bl = fs->bl; int upval = 0; while (bl && !bl->isbreakable) { upval |= bl->upval; bl = bl->previous; } if (!bl) luaX_syntaxerror(ls, "no loop to break"); if (upval) luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); } static void whilestat (LexState *ls, int line) { /* whilestat -> WHILE cond DO block END */ FuncState *fs = ls->fs; int whileinit; int condexit; BlockCnt bl; luaX_next(ls); /* skip WHILE */ whileinit = luaK_getlabel(fs); condexit = cond(ls); enterblock(fs, &bl, 1); checknext(ls, TK_DO); block(ls); luaK_patchlist(fs, luaK_jump(fs), whileinit); check_match(ls, TK_END, TK_WHILE, line); leaveblock(fs); luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ } static void repeatstat (LexState *ls, int line) { /* repeatstat -> REPEAT block UNTIL cond */ int condexit; FuncState *fs = ls->fs; int repeat_init = luaK_getlabel(fs); BlockCnt bl1, bl2; enterblock(fs, &bl1, 1); /* loop block */ enterblock(fs, &bl2, 0); /* scope block */ luaX_next(ls); /* skip REPEAT */ chunk(ls); check_match(ls, TK_UNTIL, TK_REPEAT, line); condexit = cond(ls); /* read condition (inside scope block) */ if (!bl2.upval) { /* no upvalues? */ leaveblock(fs); /* finish scope */ luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ } else { /* complete semantics when there are upvalues */ breakstat(ls); /* if condition then break */ luaK_patchtohere(ls->fs, condexit); /* else... */ leaveblock(fs); /* finish scope... */ luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */ } leaveblock(fs); /* finish loop */ } static int exp1 (LexState *ls) { expdesc e; int k; expr(ls, &e); k = e.k; luaK_exp2nextreg(ls->fs, &e); return k; } static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { /* forbody -> DO block */ BlockCnt bl; FuncState *fs = ls->fs; int prep, endfor; adjustlocalvars(ls, 3); /* control variables */ checknext(ls, TK_DO); prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); enterblock(fs, &bl, 0); /* scope for declared variables */ adjustlocalvars(ls, nvars); luaK_reserveregs(fs, nvars); block(ls); leaveblock(fs); /* end of scope for declared variables */ luaK_patchtohere(fs, prep); endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); } static void fornum (LexState *ls, TString *varname, int line) { /* fornum -> NAME = exp1,exp1[,exp1] forbody */ FuncState *fs = ls->fs; int base = fs->freereg; new_localvarliteral(ls, "(for index)", 0); new_localvarliteral(ls, "(for limit)", 1); new_localvarliteral(ls, "(for step)", 2); new_localvar(ls, varname, 3); checknext(ls, '='); exp1(ls); /* initial value */ checknext(ls, ','); exp1(ls); /* limit */ if (testnext(ls, ',')) exp1(ls); /* optional step */ else { /* default step = 1 */ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); luaK_reserveregs(fs, 1); } forbody(ls, base, line, 1, 1); } static void forlist (LexState *ls, TString *indexname) { /* forlist -> NAME {,NAME} IN explist1 forbody */ FuncState *fs = ls->fs; expdesc e; int nvars = 0; int line; int base = fs->freereg; /* create control variables */ new_localvarliteral(ls, "(for generator)", nvars++); new_localvarliteral(ls, "(for state)", nvars++); new_localvarliteral(ls, "(for control)", nvars++); /* create declared variables */ new_localvar(ls, indexname, nvars++); while (testnext(ls, ',')) new_localvar(ls, str_checkname(ls), nvars++); checknext(ls, TK_IN); line = ls->linenumber; adjust_assign(ls, 3, explist1(ls, &e), &e); luaK_checkstack(fs, 3); /* extra space to call generator */ forbody(ls, base, line, nvars - 3, 0); } static void forstat (LexState *ls, int line) { /* forstat -> FOR (fornum | forlist) END */ FuncState *fs = ls->fs; TString *varname; BlockCnt bl; enterblock(fs, &bl, 1); /* scope for loop and control variables */ luaX_next(ls); /* skip `for' */ varname = str_checkname(ls); /* first variable name */ switch (ls->t.token) { case '=': fornum(ls, varname, line); break; case ',': case TK_IN: forlist(ls, varname); break; default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); } check_match(ls, TK_END, TK_FOR, line); leaveblock(fs); /* loop scope (`break' jumps to this point) */ } static int test_then_block (LexState *ls) { /* test_then_block -> [IF | ELSEIF] cond THEN block */ int condexit; luaX_next(ls); /* skip IF or ELSEIF */ condexit = cond(ls); checknext(ls, TK_THEN); block(ls); /* `then' part */ return condexit; } static void ifstat (LexState *ls, int line) { /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ FuncState *fs = ls->fs; int flist; int escapelist = NO_JUMP; flist = test_then_block(ls); /* IF cond THEN block */ while (ls->t.token == TK_ELSEIF) { luaK_concat(fs, &escapelist, luaK_jump(fs)); luaK_patchtohere(fs, flist); flist = test_then_block(ls); /* ELSEIF cond THEN block */ } if (ls->t.token == TK_ELSE) { luaK_concat(fs, &escapelist, luaK_jump(fs)); luaK_patchtohere(fs, flist); luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ block(ls); /* `else' part */ } else luaK_concat(fs, &escapelist, flist); luaK_patchtohere(fs, escapelist); check_match(ls, TK_END, TK_IF, line); } static void localfunc (LexState *ls) { expdesc v, b; FuncState *fs = ls->fs; new_localvar(ls, str_checkname(ls), 0); init_exp(&v, VLOCAL, fs->freereg); luaK_reserveregs(fs, 1); adjustlocalvars(ls, 1); body(ls, &b, 0, ls->linenumber); luaK_storevar(fs, &v, &b); /* debug information will only see the variable after this point! */ getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; } static void localstat (LexState *ls) { /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ int nvars = 0; int nexps; expdesc e; do { new_localvar(ls, str_checkname(ls), nvars++); } while (testnext(ls, ',')); if (testnext(ls, '=')) nexps = explist1(ls, &e); else { e.k = VVOID; nexps = 0; } adjust_assign(ls, nvars, nexps, &e); adjustlocalvars(ls, nvars); } static int funcname (LexState *ls, expdesc *v) { /* funcname -> NAME {field} [`:' NAME] */ int needself = 0; singlevar(ls, v); while (ls->t.token == '.') field(ls, v); if (ls->t.token == ':') { needself = 1; field(ls, v); } return needself; } static void funcstat (LexState *ls, int line) { /* funcstat -> FUNCTION funcname body */ int needself; expdesc v, b; luaX_next(ls); /* skip FUNCTION */ needself = funcname(ls, &v); body(ls, &b, needself, line); luaK_storevar(ls->fs, &v, &b); luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ } static void exprstat (LexState *ls) { /* stat -> func | assignment */ FuncState *fs = ls->fs; struct LHS_assign v; primaryexp(ls, &v.v); if (v.v.k == VCALL) /* stat -> func */ SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ else { /* stat -> assignment */ v.prev = NULL; assignment(ls, &v, 1); } } static void retstat (LexState *ls) { /* stat -> RETURN explist */ FuncState *fs = ls->fs; expdesc e; int first, nret; /* registers with returned values */ luaX_next(ls); /* skip RETURN */ if (block_follow(ls->t.token) || ls->t.token == ';') first = nret = 0; /* return no values */ else { nret = explist1(ls, &e); /* optional return values */ if (hasmultret(e.k)) { luaK_setmultret(fs, &e); if (e.k == VCALL && nret == 1) { /* tail call? */ SET_OPCODE(getcode(fs,&e), OP_TAILCALL); lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); } first = fs->nactvar; nret = LUA_MULTRET; /* return all values */ } else { if (nret == 1) /* only one single value? */ first = luaK_exp2anyreg(fs, &e); else { luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ first = fs->nactvar; /* return all `active' values */ lua_assert(nret == fs->freereg - first); } } } luaK_ret(fs, first, nret); } static int statement (LexState *ls) { int line = ls->linenumber; /* may be needed for error messages */ switch (ls->t.token) { case TK_IF: { /* stat -> ifstat */ ifstat(ls, line); return 0; } case TK_WHILE: { /* stat -> whilestat */ whilestat(ls, line); return 0; } case TK_DO: { /* stat -> DO block END */ luaX_next(ls); /* skip DO */ block(ls); check_match(ls, TK_END, TK_DO, line); return 0; } case TK_FOR: { /* stat -> forstat */ forstat(ls, line); return 0; } case TK_REPEAT: { /* stat -> repeatstat */ repeatstat(ls, line); return 0; } case TK_FUNCTION: { funcstat(ls, line); /* stat -> funcstat */ return 0; } case TK_LOCAL: { /* stat -> localstat */ luaX_next(ls); /* skip LOCAL */ if (testnext(ls, TK_FUNCTION)) /* local function? */ localfunc(ls); else localstat(ls); return 0; } case TK_RETURN: { /* stat -> retstat */ retstat(ls); return 1; /* must be last statement */ } case TK_BREAK: { /* stat -> breakstat */ luaX_next(ls); /* skip BREAK */ breakstat(ls); return 1; /* must be last statement */ } default: { exprstat(ls); return 0; /* to avoid warnings */ } } } static void chunk (LexState *ls) { /* chunk -> { stat [`;'] } */ int islast = 0; enterlevel(ls); while (!islast && !block_follow(ls->t.token)) { islast = statement(ls); testnext(ls, ';'); lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && ls->fs->freereg >= ls->fs->nactvar); ls->fs->freereg = ls->fs->nactvar; /* free registers */ } leavelevel(ls); } /* }====================================================================== */ debian/grub-extras/lua/ldebug.c0000664000000000000000000004072212524662415013636 0ustar /* ** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ ** Debug Interface ** See Copyright Notice in lua.h */ #if 0 #include #include #include #endif #define ldebug_c #define LUA_CORE #include "lua.h" #include "lapi.h" #include "lcode.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lobject.h" #include "lopcodes.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" #include "lvm.h" static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); static int currentpc (lua_State *L, CallInfo *ci) { if (!isLua(ci)) return -1; /* function is not a Lua function? */ if (ci == L->ci) ci->savedpc = L->savedpc; return pcRel(ci->savedpc, ci_func(ci)->l.p); } static int currentline (lua_State *L, CallInfo *ci) { int pc = currentpc(L, ci); if (pc < 0) return -1; /* only active lua functions have current-line information */ else return getline(ci_func(ci)->l.p, pc); } /* ** this function can be called asynchronous (e.g. during a signal) */ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { if (func == NULL || mask == 0) { /* turn off hooks? */ mask = 0; func = NULL; } L->hook = func; L->basehookcount = count; resethookcount(L); L->hookmask = cast_byte(mask); return 1; } LUA_API lua_Hook lua_gethook (lua_State *L) { return L->hook; } LUA_API int lua_gethookmask (lua_State *L) { return L->hookmask; } LUA_API int lua_gethookcount (lua_State *L) { return L->basehookcount; } LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { int status; CallInfo *ci; lua_lock(L); for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { level--; if (f_isLua(ci)) /* Lua function? */ level -= ci->tailcalls; /* skip lost tail calls */ } if (level == 0 && ci > L->base_ci) { /* level found? */ status = 1; ar->i_ci = cast_int(ci - L->base_ci); } else if (level < 0) { /* level is of a lost tail call? */ status = 1; ar->i_ci = 0; } else status = 0; /* no such level */ lua_unlock(L); return status; } static Proto *getluaproto (CallInfo *ci) { return (isLua(ci) ? ci_func(ci)->l.p : NULL); } static const char *findlocal (lua_State *L, CallInfo *ci, int n) { const char *name; Proto *fp = getluaproto(ci); if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) return name; /* is a local variable in a Lua function */ else { StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ return "(*temporary)"; else return NULL; } } LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { CallInfo *ci = L->base_ci + ar->i_ci; const char *name = findlocal(L, ci, n); lua_lock(L); if (name) luaA_pushobject(L, ci->base + (n - 1)); lua_unlock(L); return name; } LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { CallInfo *ci = L->base_ci + ar->i_ci; const char *name = findlocal(L, ci, n); lua_lock(L); if (name) setobjs2s(L, ci->base + (n - 1), L->top - 1); L->top--; /* pop value */ lua_unlock(L); return name; } static void funcinfo (lua_Debug *ar, Closure *cl) { if (cl->c.isC) { ar->source = "=[C]"; ar->linedefined = -1; ar->lastlinedefined = -1; ar->what = "C"; } else { ar->source = getstr(cl->l.p->source); ar->linedefined = cl->l.p->linedefined; ar->lastlinedefined = cl->l.p->lastlinedefined; ar->what = (ar->linedefined == 0) ? "main" : "Lua"; } luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); } static void info_tailcall (lua_Debug *ar) { ar->name = ar->namewhat = ""; ar->what = "tail"; ar->lastlinedefined = ar->linedefined = ar->currentline = -1; ar->source = "=(tail call)"; luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); ar->nups = 0; } static void collectvalidlines (lua_State *L, Closure *f) { if (f == NULL || f->c.isC) { setnilvalue(L->top); } else { Table *t = luaH_new(L, 0, 0); int *lineinfo = f->l.p->lineinfo; int i; for (i=0; il.p->sizelineinfo; i++) setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); sethvalue(L, L->top, t); } incr_top(L); } static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, Closure *f, CallInfo *ci) { int status = 1; if (f == NULL) { info_tailcall(ar); return status; } for (; *what; what++) { switch (*what) { case 'S': { funcinfo(ar, f); break; } case 'l': { ar->currentline = (ci) ? currentline(L, ci) : -1; break; } case 'u': { ar->nups = f->c.nupvalues; break; } case 'n': { ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; if (ar->namewhat == NULL) { ar->namewhat = ""; /* not found */ ar->name = NULL; } break; } case 'L': case 'f': /* handled by lua_getinfo */ break; default: status = 0; /* invalid option */ } } return status; } LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { int status; Closure *f = NULL; CallInfo *ci = NULL; lua_lock(L); if (*what == '>') { StkId func = L->top - 1; luai_apicheck(L, ttisfunction(func)); what++; /* skip the '>' */ f = clvalue(func); L->top--; /* pop function */ } else if (ar->i_ci != 0) { /* no tail call? */ ci = L->base_ci + ar->i_ci; lua_assert(ttisfunction(ci->func)); f = clvalue(ci->func); } status = auxgetinfo(L, what, ar, f, ci); if (strchr(what, 'f')) { if (f == NULL) setnilvalue(L->top); else setclvalue(L, L->top, f); incr_top(L); } if (strchr(what, 'L')) collectvalidlines(L, f); lua_unlock(L); return status; } /* ** {====================================================== ** Symbolic Execution and code checker ** ======================================================= */ #define check(x) if (!(x)) return 0; #define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) #define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) static int precheck (const Proto *pt) { check(pt->maxstacksize <= MAXSTACK); check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); check(!(pt->is_vararg & VARARG_NEEDSARG) || (pt->is_vararg & VARARG_HASARG)); check(pt->sizeupvalues <= pt->nups); check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); return 1; } #define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) int luaG_checkopenop (Instruction i) { switch (GET_OPCODE(i)) { case OP_CALL: case OP_TAILCALL: case OP_RETURN: case OP_SETLIST: { check(GETARG_B(i) == 0); return 1; } default: return 0; /* invalid instruction after an open call */ } } static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { switch (mode) { case OpArgN: check(r == 0); break; case OpArgU: break; case OpArgR: checkreg(pt, r); break; case OpArgK: check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); break; } return 1; } static Instruction symbexec (const Proto *pt, int lastpc, int reg) { int pc; int last; /* stores position of last instruction that changed `reg' */ last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ check(precheck(pt)); for (pc = 0; pc < lastpc; pc++) { Instruction i = pt->code[pc]; OpCode op = GET_OPCODE(i); int a = GETARG_A(i); int b = 0; int c = 0; check(op < NUM_OPCODES); checkreg(pt, a); switch (getOpMode(op)) { case iABC: { b = GETARG_B(i); c = GETARG_C(i); check(checkArgMode(pt, b, getBMode(op))); check(checkArgMode(pt, c, getCMode(op))); break; } case iABx: { b = GETARG_Bx(i); if (getBMode(op) == OpArgK) check(b < pt->sizek); break; } case iAsBx: { b = GETARG_sBx(i); if (getBMode(op) == OpArgR) { int dest = pc+1+b; check(0 <= dest && dest < pt->sizecode); if (dest > 0) { int j; /* check that it does not jump to a setlist count; this is tricky, because the count from a previous setlist may have the same value of an invalid setlist; so, we must go all the way back to the first of them (if any) */ for (j = 0; j < dest; j++) { Instruction d = pt->code[dest-1-j]; if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; } /* if 'j' is even, previous value is not a setlist (even if it looks like one) */ check((j&1) == 0); } } break; } } if (testAMode(op)) { if (a == reg) last = pc; /* change register `a' */ } if (testTMode(op)) { check(pc+2 < pt->sizecode); /* check skip */ check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); } switch (op) { case OP_LOADBOOL: { if (c == 1) { /* does it jump? */ check(pc+2 < pt->sizecode); /* check its jump */ check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST || GETARG_C(pt->code[pc+1]) != 0); } break; } case OP_LOADNIL: { if (a <= reg && reg <= b) last = pc; /* set registers from `a' to `b' */ break; } case OP_GETUPVAL: case OP_SETUPVAL: { check(b < pt->nups); break; } case OP_GETGLOBAL: case OP_SETGLOBAL: { check(ttisstring(&pt->k[b])); break; } case OP_SELF: { checkreg(pt, a+1); if (reg == a+1) last = pc; break; } case OP_CONCAT: { check(b < c); /* at least two operands */ break; } case OP_TFORLOOP: { check(c >= 1); /* at least one result (control variable) */ checkreg(pt, a+2+c); /* space for results */ if (reg >= a+2) last = pc; /* affect all regs above its base */ break; } case OP_FORLOOP: case OP_FORPREP: checkreg(pt, a+3); /* go through */ case OP_JMP: { int dest = pc+1+b; /* not full check and jump is forward and do not skip `lastpc'? */ if (reg != NO_REG && pc < dest && dest <= lastpc) pc += b; /* do the jump */ break; } case OP_CALL: case OP_TAILCALL: { if (b != 0) { checkreg(pt, a+b-1); } c--; /* c = num. returns */ if (c == LUA_MULTRET) { check(checkopenop(pt, pc)); } else if (c != 0) checkreg(pt, a+c-1); if (reg >= a) last = pc; /* affect all registers above base */ break; } case OP_RETURN: { b--; /* b = num. returns */ if (b > 0) checkreg(pt, a+b-1); break; } case OP_SETLIST: { if (b > 0) checkreg(pt, a + b); if (c == 0) { pc++; check(pc < pt->sizecode - 1); } break; } case OP_CLOSURE: { int nup, j; check(b < pt->sizep); nup = pt->p[b]->nups; check(pc + nup < pt->sizecode); for (j = 1; j <= nup; j++) { OpCode op1 = GET_OPCODE(pt->code[pc + j]); check(op1 == OP_GETUPVAL || op1 == OP_MOVE); } if (reg != NO_REG) /* tracing? */ pc += nup; /* do not 'execute' these pseudo-instructions */ break; } case OP_VARARG: { check((pt->is_vararg & VARARG_ISVARARG) && !(pt->is_vararg & VARARG_NEEDSARG)); b--; if (b == LUA_MULTRET) check(checkopenop(pt, pc)); checkreg(pt, a+b-1); break; } default: break; } } return pt->code[last]; } #undef check #undef checkjump #undef checkreg /* }====================================================== */ int luaG_checkcode (const Proto *pt) { return (symbexec(pt, pt->sizecode, NO_REG) != 0); } static const char *kname (Proto *p, int c) { if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) return svalue(&p->k[INDEXK(c)]); else return "?"; } static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, const char **name) { if (isLua(ci)) { /* a Lua function? */ Proto *p = ci_func(ci)->l.p; int pc = currentpc(L, ci); Instruction i; *name = luaF_getlocalname(p, stackpos+1, pc); if (*name) /* is a local? */ return "local"; i = symbexec(p, pc, stackpos); /* try symbolic execution */ lua_assert(pc != -1); switch (GET_OPCODE(i)) { case OP_GETGLOBAL: { int g = GETARG_Bx(i); /* global index */ lua_assert(ttisstring(&p->k[g])); *name = svalue(&p->k[g]); return "global"; } case OP_MOVE: { int a = GETARG_A(i); int b = GETARG_B(i); /* move from `b' to `a' */ if (b < a) return getobjname(L, ci, b, name); /* get name for `b' */ break; } case OP_GETTABLE: { int k = GETARG_C(i); /* key index */ *name = kname(p, k); return "field"; } case OP_GETUPVAL: { int u = GETARG_B(i); /* upvalue index */ *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; return "upvalue"; } case OP_SELF: { int k = GETARG_C(i); /* key index */ *name = kname(p, k); return "method"; } default: break; } } return NULL; /* no useful name found */ } static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { Instruction i; if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) return NULL; /* calling function is not Lua (or is unknown) */ ci--; /* calling function */ i = ci_func(ci)->l.p->code[currentpc(L, ci)]; if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || GET_OPCODE(i) == OP_TFORLOOP) return getobjname(L, ci, GETARG_A(i), name); else return NULL; /* no useful name can be found */ } /* only ANSI way to check whether a pointer points to an array */ static int isinstack (CallInfo *ci, const TValue *o) { StkId p; for (p = ci->base; p < ci->top; p++) if (o == p) return 1; return 0; } void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { const char *name = NULL; const char *t = luaT_typenames[ttype(o)]; const char *kind = (isinstack(L->ci, o)) ? getobjname(L, L->ci, cast_int(o - L->base), &name) : NULL; if (kind) luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", op, kind, name, t); else luaG_runerror(L, "attempt to %s a %s value", op, t); } void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; lua_assert(!ttisstring(p1) && !ttisnumber(p1)); luaG_typeerror(L, p1, "concatenate"); } void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { TValue temp; if (luaV_tonumber(p1, &temp) == NULL) p2 = p1; /* first operand is wrong */ luaG_typeerror(L, p2, "perform arithmetic on"); } int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { const char *t1 = luaT_typenames[ttype(p1)]; const char *t2 = luaT_typenames[ttype(p2)]; if (t1[2] == t2[2]) luaG_runerror(L, "attempt to compare two %s values", t1); else luaG_runerror(L, "attempt to compare %s with %s", t1, t2); return 0; } static void addinfo (lua_State *L, const char *msg) { CallInfo *ci = L->ci; if (isLua(ci)) { /* is Lua code? */ char buff[LUA_IDSIZE]; /* add file:line information */ int line = currentline(L, ci); luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); } } void luaG_errormsg (lua_State *L) { if (L->errfunc != 0) { /* is there an error handling function? */ StkId errfunc = restorestack(L, L->errfunc); if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); setobjs2s(L, L->top, L->top - 1); /* move argument */ setobjs2s(L, L->top - 1, errfunc); /* push function */ incr_top(L); luaD_call(L, L->top - 2, 1); /* call it */ } luaD_throw(L, LUA_ERRRUN); } void luaG_runerror (lua_State *L, const char *fmt, ...) { va_list argp; va_start(argp, fmt); addinfo(L, luaO_pushvfstring(L, fmt, argp)); va_end(argp); luaG_errormsg(L); } debian/grub-extras/lua/lobject.h0000664000000000000000000002044412524662415014022 0ustar /* ** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ #ifndef lobject_h #define lobject_h #include #include "llimits.h" #include "lua.h" /* tags for values visible from Lua */ #define LAST_TAG LUA_TTHREAD #define NUM_TAGS (LAST_TAG+1) /* ** Extra tags for non-values */ #define LUA_TPROTO (LAST_TAG+1) #define LUA_TUPVAL (LAST_TAG+2) #define LUA_TDEADKEY (LAST_TAG+3) /* ** Union of all collectable objects */ typedef union GCObject GCObject; /* ** Common Header for all collectable objects (in macro form, to be ** included in other objects) */ #define CommonHeader GCObject __attribute__ ((aligned)) *next; lu_byte tt; lu_byte marked /* ** Common header in struct form */ typedef struct GCheader { CommonHeader; } GCheader; /* ** Union of all Lua values */ typedef union { GCObject *gc; void *p; lua_Number n; int b; } Value; /* ** Tagged Values */ #define TValuefields Value value; int tt typedef struct lua_TValue { TValuefields; } TValue; /* Macros to test type */ #define ttisnil(o) (ttype(o) == LUA_TNIL) #define ttisnumber(o) (ttype(o) == LUA_TNUMBER) #define ttisstring(o) (ttype(o) == LUA_TSTRING) #define ttistable(o) (ttype(o) == LUA_TTABLE) #define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) #define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) #define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) #define ttisthread(o) (ttype(o) == LUA_TTHREAD) #define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) /* Macros to access values */ #define ttype(o) ((o)->tt) #define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) #define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) #define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) #define tsvalue(o) (&rawtsvalue(o)->tsv) #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) #define uvalue(o) (&rawuvalue(o)->uv) #define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) #define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) #define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) #define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) /* ** for internal debug only */ #define checkconsistency(obj) \ lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) #define checkliveness(g,obj) \ lua_assert(!iscollectable(obj) || \ ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) /* Macros to set values */ #define setnilvalue(obj) ((obj)->tt=LUA_TNIL) #define setnvalue(obj,x) \ { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } #define setpvalue(obj,x) \ { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } #define setbvalue(obj,x) \ { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } #define setsvalue(L,obj,x) \ { TValue *i_o=(obj); \ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ checkliveness(G(L),i_o); } #define setuvalue(L,obj,x) \ { TValue *i_o=(obj); \ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ checkliveness(G(L),i_o); } #define setthvalue(L,obj,x) \ { TValue *i_o=(obj); \ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ checkliveness(G(L),i_o); } #define setclvalue(L,obj,x) \ { TValue *i_o=(obj); \ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ checkliveness(G(L),i_o); } #define sethvalue(L,obj,x) \ { TValue *i_o=(obj); \ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ checkliveness(G(L),i_o); } #define setptvalue(L,obj,x) \ { TValue *i_o=(obj); \ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ checkliveness(G(L),i_o); } #define setobj(L,obj1,obj2) \ { const TValue *o2=(obj2); TValue *o1=(obj1); \ o1->value = o2->value; o1->tt=o2->tt; \ checkliveness(G(L),o1); } /* ** different types of sets, according to destination */ /* from stack to (same) stack */ #define setobjs2s setobj /* to stack (not from same stack) */ #define setobj2s setobj #define setsvalue2s setsvalue #define sethvalue2s sethvalue #define setptvalue2s setptvalue /* from table to same table */ #define setobjt2t setobj /* to table */ #define setobj2t setobj /* to new object */ #define setobj2n setobj #define setsvalue2n setsvalue #define setttype(obj, tt) (ttype(obj) = (tt)) #define iscollectable(o) (ttype(o) >= LUA_TSTRING) typedef TValue *StkId; /* index to stack elements */ /* ** String headers for string table */ typedef union TString { L_Umaxalign dummy; /* ensures maximum alignment for strings */ struct { CommonHeader; lu_byte reserved; unsigned int hash; size_t len; } tsv; } TString; #define getstr(ts) cast(const char *, (ts) + 1) #define svalue(o) getstr(rawtsvalue(o)) typedef union Udata { L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ struct { CommonHeader; struct Table *metatable; struct Table *env; size_t len; } uv; } Udata; /* ** Function Prototypes */ typedef struct Proto { CommonHeader; TValue *k; /* constants used by the function */ Instruction *code; struct Proto **p; /* functions defined inside the function */ int *lineinfo; /* map from opcodes to source lines */ struct LocVar *locvars; /* information about local variables */ TString **upvalues; /* upvalue names */ TString *source; int sizeupvalues; int sizek; /* size of `k' */ int sizecode; int sizelineinfo; int sizep; /* size of `p' */ int sizelocvars; int linedefined; int lastlinedefined; GCObject *gclist; lu_byte nups; /* number of upvalues */ lu_byte numparams; lu_byte is_vararg; lu_byte maxstacksize; } Proto; /* masks for new-style vararg */ #define VARARG_HASARG 1 #define VARARG_ISVARARG 2 #define VARARG_NEEDSARG 4 typedef struct LocVar { TString *varname; int startpc; /* first point where variable is active */ int endpc; /* first point where variable is dead */ } LocVar; /* ** Upvalues */ typedef struct UpVal { CommonHeader; TValue *v; /* points to stack or to its own value */ union { TValue value; /* the value (when closed) */ struct { /* double linked list (when open) */ struct UpVal *prev; struct UpVal *next; } l; } u; } UpVal; /* ** Closures */ #define ClosureHeader \ CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ struct Table *env typedef struct CClosure { ClosureHeader; lua_CFunction f; TValue upvalue[1]; } CClosure; typedef struct LClosure { ClosureHeader; struct Proto *p; UpVal *upvals[1]; } LClosure; typedef union Closure { CClosure c; LClosure l; } Closure; #define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) #define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) /* ** Tables */ typedef union TKey { struct { TValuefields; struct Node *next; /* for chaining */ } nk; TValue tvk; } TKey; typedef struct Node { TValue i_val; TKey i_key; } Node; typedef struct Table { CommonHeader; lu_byte flags; /* 1<

lsizenode)) #define luaO_nilobject (&luaO_nilobject_) LUAI_DATA const TValue luaO_nilobject_; #define ceillog2(x) (luaO_log2((x)-1) + 1) LUAI_FUNC int luaO_log2 (unsigned int x); LUAI_FUNC int luaO_int2fb (unsigned int x); LUAI_FUNC int luaO_fb2int (int x); LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp); LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); #endif debian/grub-extras/lua/llex.c0000664000000000000000000003041212524662415013333 0ustar /* ** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ #if 0 #include #include #include #endif #define llex_c #define LUA_CORE #include "lua.h" #include "ldo.h" #include "llex.h" #include "lobject.h" #include "lparser.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "lzio.h" #define next(ls) (ls->current = zgetc(ls->z)) #define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') /* ORDER RESERVED */ const char *const luaX_tokens [] = { "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while", "..", "...", "==", ">=", "<=", "~=", "", "", "", "", NULL }; #define save_and_next(ls) (save(ls, ls->current), next(ls)) static void save (LexState *ls, int c) { Mbuffer *b = ls->buff; if (b->n + 1 > b->buffsize) { size_t newsize; if (b->buffsize >= MAX_SIZET/2) luaX_lexerror(ls, "lexical element too long", 0); newsize = b->buffsize * 2; luaZ_resizebuffer(ls->L, b, newsize); } b->buffer[b->n++] = cast(char, c); } void luaX_init (lua_State *L) { int i; for (i=0; itsv.reserved = cast_byte(i+1); /* reserved word */ } } #define MAXSRC 80 const char *luaX_token2str (LexState *ls, int token) { if (token < FIRST_RESERVED) { lua_assert(token == cast(unsigned char, token)); return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : luaO_pushfstring(ls->L, "%c", token); } else return luaX_tokens[token-FIRST_RESERVED]; } static const char *txtToken (LexState *ls, int token) { switch (token) { case TK_NAME: case TK_STRING: case TK_NUMBER: save(ls, '\0'); return luaZ_buffer(ls->buff); default: return luaX_token2str(ls, token); } } void luaX_lexerror (LexState *ls, const char *msg, int token) { char buff[MAXSRC]; luaO_chunkid(buff, getstr(ls->source), MAXSRC); msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); if (token) luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); luaD_throw(ls->L, LUA_ERRSYNTAX); } void luaX_syntaxerror (LexState *ls, const char *msg) { luaX_lexerror(ls, msg, ls->t.token); } TString *luaX_newstring (LexState *ls, const char *str, size_t l) { lua_State *L = ls->L; TString *ts = luaS_newlstr(L, str, l); TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ if (ttisnil(o)) setbvalue(o, 1); /* make sure `str' will not be collected */ return ts; } static void inclinenumber (LexState *ls) { int old = ls->current; lua_assert(currIsNewline(ls)); next(ls); /* skip `\n' or `\r' */ if (currIsNewline(ls) && ls->current != old) next(ls); /* skip `\n\r' or `\r\n' */ if (++ls->linenumber >= MAX_INT) luaX_syntaxerror(ls, "chunk has too many lines"); } void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { ls->decpoint = '.'; ls->L = L; ls->lookahead.token = TK_EOS; /* no look-ahead token */ ls->z = z; ls->fs = NULL; ls->linenumber = 1; ls->lastline = 1; ls->source = source; luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ next(ls); /* read first char */ } /* ** ======================================================= ** LEXICAL ANALYZER ** ======================================================= */ static int check_next (LexState *ls, const char *set) { if (!strchr(set, ls->current)) return 0; save_and_next(ls); return 1; } static void buffreplace (LexState *ls, char from, char to) { size_t n = luaZ_bufflen(ls->buff); char *p = luaZ_buffer(ls->buff); while (n--) if (p[n] == from) p[n] = to; } static void trydecpoint (LexState *ls, SemInfo *seminfo) { /* format error: try to update decimal point separator */ #if 0 struct lconv *cv = localeconv(); char old = ls->decpoint; ls->decpoint = (cv ? cv->decimal_point[0] : '.'); #else char old = ls->decpoint; ls->decpoint = '.'; #endif buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { /* format error with correct decimal point: no more options */ buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ luaX_lexerror(ls, "malformed number", TK_NUMBER); } } /* LUA_NUMBER */ static void read_numeral (LexState *ls, SemInfo *seminfo) { lua_assert(isdigit(ls->current)); do { save_and_next(ls); } while (isdigit(ls->current) || ls->current == '.'); if (check_next(ls, "Ee")) /* `E'? */ check_next(ls, "+-"); /* optional exponent sign */ while (isalnum(ls->current) || ls->current == '_') save_and_next(ls); save(ls, '\0'); buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ trydecpoint(ls, seminfo); /* try to update decimal point separator */ } static int skip_sep (LexState *ls) { int count = 0; int s = ls->current; lua_assert(s == '[' || s == ']'); save_and_next(ls); while (ls->current == '=') { save_and_next(ls); count++; } return (ls->current == s) ? count : (-count) - 1; } static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { int cont = 0; (void)(cont); /* avoid warnings when `cont' is not used */ save_and_next(ls); /* skip 2nd `[' */ if (currIsNewline(ls)) /* string starts with a newline? */ inclinenumber(ls); /* skip it */ for (;;) { switch (ls->current) { case EOZ: luaX_lexerror(ls, (seminfo) ? "unfinished long string" : "unfinished long comment", TK_EOS); break; /* to avoid warnings */ #if defined(LUA_COMPAT_LSTR) case '[': { if (skip_sep(ls) == sep) { save_and_next(ls); /* skip 2nd `[' */ cont++; #if LUA_COMPAT_LSTR == 1 if (sep == 0) luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); #endif } break; } #endif case ']': { if (skip_sep(ls) == sep) { save_and_next(ls); /* skip 2nd `]' */ #if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2 cont--; if (sep == 0 && cont >= 0) break; #endif goto endloop; } break; } case '\n': case '\r': { save(ls, '\n'); inclinenumber(ls); if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ break; } default: { if (seminfo) save_and_next(ls); else next(ls); } } } endloop: if (seminfo) seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), luaZ_bufflen(ls->buff) - 2*(2 + sep)); } static void read_string (LexState *ls, int del, SemInfo *seminfo) { save_and_next(ls); while (ls->current != del) { switch (ls->current) { case EOZ: luaX_lexerror(ls, "unfinished string", TK_EOS); continue; /* to avoid warnings */ case '\n': case '\r': luaX_lexerror(ls, "unfinished string", TK_STRING); continue; /* to avoid warnings */ case '\\': { int c; next(ls); /* do not save the `\' */ switch (ls->current) { case 'a': c = '\a'; break; case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case '\n': /* go through */ case '\r': save(ls, '\n'); inclinenumber(ls); continue; case EOZ: continue; /* will raise an error next loop */ default: { if (!isdigit(ls->current)) save_and_next(ls); /* handles \\, \", \', and \? */ else { /* \xxx */ int i = 0; c = 0; do { c = 10*c + (ls->current-'0'); next(ls); } while (++i<3 && isdigit(ls->current)); if (c > UCHAR_MAX) luaX_lexerror(ls, "escape sequence too large", TK_STRING); save(ls, c); } continue; } } save(ls, c); next(ls); continue; } default: save_and_next(ls); } } save_and_next(ls); /* skip delimiter */ seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, luaZ_bufflen(ls->buff) - 2); } static int llex (LexState *ls, SemInfo *seminfo) { luaZ_resetbuffer(ls->buff); for (;;) { switch (ls->current) { case '\n': case '\r': { inclinenumber(ls); continue; } case '-': { next(ls); if (ls->current != '-') return '-'; /* else is a comment */ next(ls); if (ls->current == '[') { int sep = skip_sep(ls); luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ if (sep >= 0) { read_long_string(ls, NULL, sep); /* long comment */ luaZ_resetbuffer(ls->buff); continue; } } /* else short comment */ while (!currIsNewline(ls) && ls->current != EOZ) next(ls); continue; } case '[': { int sep = skip_sep(ls); if (sep >= 0) { read_long_string(ls, seminfo, sep); return TK_STRING; } else if (sep == -1) return '['; else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); } case '=': { next(ls); if (ls->current != '=') return '='; else { next(ls); return TK_EQ; } } case '<': { next(ls); if (ls->current != '=') return '<'; else { next(ls); return TK_LE; } } case '>': { next(ls); if (ls->current != '=') return '>'; else { next(ls); return TK_GE; } } case '~': { next(ls); if (ls->current != '=') return '~'; else { next(ls); return TK_NE; } } case '"': case '\'': { read_string(ls, ls->current, seminfo); return TK_STRING; } case '.': { save_and_next(ls); if (check_next(ls, ".")) { if (check_next(ls, ".")) return TK_DOTS; /* ... */ else return TK_CONCAT; /* .. */ } else if (!isdigit(ls->current)) return '.'; else { read_numeral(ls, seminfo); return TK_NUMBER; } } case EOZ: { return TK_EOS; } default: { if (isspace(ls->current)) { lua_assert(!currIsNewline(ls)); next(ls); continue; } else if (isdigit(ls->current)) { read_numeral(ls, seminfo); return TK_NUMBER; } else if (isalpha(ls->current) || ls->current == '_') { /* identifier or reserved word */ TString *ts; do { save_and_next(ls); } while (isalnum(ls->current) || ls->current == '_'); ts = luaX_newstring(ls, luaZ_buffer(ls->buff), luaZ_bufflen(ls->buff)); if (ts->tsv.reserved > 0) /* reserved word? */ return ts->tsv.reserved - 1 + FIRST_RESERVED; else { seminfo->ts = ts; return TK_NAME; } } else { int c = ls->current; next(ls); return c; /* single-char tokens (+ - / ...) */ } } } } } void luaX_next (LexState *ls) { ls->lastline = ls->linenumber; if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ ls->t = ls->lookahead; /* use this one */ ls->lookahead.token = TK_EOS; /* and discharge it */ } else ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ } void luaX_lookahead (LexState *ls) { lua_assert(ls->lookahead.token == TK_EOS); ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); } debian/grub-extras/lua/ldo.c0000664000000000000000000003501612524662415013152 0ustar /* ** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ #if 0 #include #include #include #endif #define ldo_c #define LUA_CORE #include "lua.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lgc.h" #include "lmem.h" #include "lobject.h" #include "lopcodes.h" #include "lparser.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" #include "lundump.h" #include "lvm.h" #include "lzio.h" /* ** {====================================================== ** Error-recovery functions ** ======================================================= */ /* chain list of long jump buffers */ struct lua_longjmp { struct lua_longjmp *previous; luai_jmpbuf b; volatile int status; /* error code */ }; void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { switch (errcode) { case LUA_ERRMEM: { setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); break; } case LUA_ERRERR: { setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); break; } case LUA_ERRSYNTAX: case LUA_ERRRUN: { setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ break; } } L->top = oldtop + 1; } static void restore_stack_limit (lua_State *L) { lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ int inuse = cast_int(L->ci - L->base_ci); if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ luaD_reallocCI(L, LUAI_MAXCALLS); } } static void resetstack (lua_State *L, int status) { L->ci = L->base_ci; L->base = L->ci->base; luaF_close(L, L->base); /* close eventual pending closures */ luaD_seterrorobj(L, status, L->base); L->nCcalls = L->baseCcalls; L->allowhook = 1; restore_stack_limit(L); L->errfunc = 0; L->errorJmp = NULL; } void luaD_throw (lua_State *L, int errcode) { if (L->errorJmp) { L->errorJmp->status = errcode; LUAI_THROW(L, L->errorJmp); } else { L->status = cast_byte(errcode); if (G(L)->panic) { resetstack(L, errcode); lua_unlock(L); G(L)->panic(L); } exit(EXIT_FAILURE); } } int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { struct lua_longjmp lj; lj.status = 0; lj.previous = L->errorJmp; /* chain new error handler */ L->errorJmp = &lj; LUAI_TRY(L, &lj, (*f)(L, ud); ); L->errorJmp = lj.previous; /* restore old error handler */ return lj.status; } /* }====================================================== */ static void correctstack (lua_State *L, TValue *oldstack) { CallInfo *ci; GCObject *up; L->top = (L->top - oldstack) + L->stack; for (up = L->openupval; up != NULL; up = up->gch.next) gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; for (ci = L->base_ci; ci <= L->ci; ci++) { ci->top = (ci->top - oldstack) + L->stack; ci->base = (ci->base - oldstack) + L->stack; ci->func = (ci->func - oldstack) + L->stack; } L->base = (L->base - oldstack) + L->stack; } void luaD_reallocstack (lua_State *L, int newsize) { TValue *oldstack = L->stack; int realsize = newsize + 1 + EXTRA_STACK; lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); L->stacksize = realsize; L->stack_last = L->stack+newsize; correctstack(L, oldstack); } void luaD_reallocCI (lua_State *L, int newsize) { CallInfo *oldci = L->base_ci; luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); L->size_ci = newsize; L->ci = (L->ci - oldci) + L->base_ci; L->end_ci = L->base_ci + L->size_ci - 1; } void luaD_growstack (lua_State *L, int n) { if (n <= L->stacksize) /* double size is enough? */ luaD_reallocstack(L, 2*L->stacksize); else luaD_reallocstack(L, L->stacksize + n); } static CallInfo *growCI (lua_State *L) { if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ luaD_throw(L, LUA_ERRERR); else { luaD_reallocCI(L, 2*L->size_ci); if (L->size_ci > LUAI_MAXCALLS) luaG_runerror(L, "stack overflow"); } return ++L->ci; } void luaD_callhook (lua_State *L, int event, int line) { lua_Hook hook = L->hook; if (hook && L->allowhook) { ptrdiff_t top = savestack(L, L->top); ptrdiff_t ci_top = savestack(L, L->ci->top); lua_Debug ar; ar.event = event; ar.currentline = line; if (event == LUA_HOOKTAILRET) ar.i_ci = 0; /* tail call; no debug information about it */ else ar.i_ci = cast_int(L->ci - L->base_ci); luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ L->ci->top = L->top + LUA_MINSTACK; lua_assert(L->ci->top <= L->stack_last); L->allowhook = 0; /* cannot call hooks inside a hook */ lua_unlock(L); (*hook)(L, &ar); lua_lock(L); lua_assert(!L->allowhook); L->allowhook = 1; L->ci->top = restorestack(L, ci_top); L->top = restorestack(L, top); } } static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { int i; int nfixargs = p->numparams; Table *htab = NULL; StkId base, fixed; for (; actual < nfixargs; ++actual) setnilvalue(L->top++); #if defined(LUA_COMPAT_VARARG) if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ int nvar = actual - nfixargs; /* number of extra arguments */ lua_assert(p->is_vararg & VARARG_HASARG); luaC_checkGC(L); htab = luaH_new(L, nvar, 1); /* create `arg' table */ for (i=0; itop - nvar + i); /* store counter in field `n' */ setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); } #endif /* move fixed parameters to final position */ fixed = L->top - actual; /* first fixed argument */ base = L->top; /* final position of first argument */ for (i=0; itop++, fixed+i); setnilvalue(fixed+i); } /* add `arg' parameter */ if (htab) { sethvalue(L, L->top++, htab); lua_assert(iswhite(obj2gco(htab))); } return base; } static StkId tryfuncTM (lua_State *L, StkId func) { const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); StkId p; ptrdiff_t funcr = savestack(L, func); if (!ttisfunction(tm)) luaG_typeerror(L, func, "call"); /* Open a hole inside the stack at `func' */ for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); incr_top(L); func = restorestack(L, funcr); /* previous call may change stack */ setobj2s(L, func, tm); /* tag method is the new function to be called */ return func; } #define inc_ci(L) \ ((L->ci == L->end_ci) ? growCI(L) : \ (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) int luaD_precall (lua_State *L, StkId func, int nresults) { LClosure *cl; ptrdiff_t funcr; if (!ttisfunction(func)) /* `func' is not a function? */ func = tryfuncTM(L, func); /* check the `function' tag method */ funcr = savestack(L, func); cl = &clvalue(func)->l; L->ci->savedpc = L->savedpc; if (!cl->isC) { /* Lua function? prepare its call */ CallInfo *ci; StkId st, base; Proto *p = cl->p; luaD_checkstack(L, p->maxstacksize); func = restorestack(L, funcr); if (!p->is_vararg) { /* no varargs? */ base = func + 1; if (L->top > base + p->numparams) L->top = base + p->numparams; } else { /* vararg function */ int nargs = cast_int(L->top - func) - 1; base = adjust_varargs(L, p, nargs); func = restorestack(L, funcr); /* previous call may change the stack */ } ci = inc_ci(L); /* now `enter' new function */ ci->func = func; L->base = ci->base = base; ci->top = L->base + p->maxstacksize; lua_assert(ci->top <= L->stack_last); L->savedpc = p->code; /* starting point */ ci->tailcalls = 0; ci->nresults = nresults; for (st = L->top; st < ci->top; st++) setnilvalue(st); L->top = ci->top; if (L->hookmask & LUA_MASKCALL) { L->savedpc++; /* hooks assume 'pc' is already incremented */ luaD_callhook(L, LUA_HOOKCALL, -1); L->savedpc--; /* correct 'pc' */ } return PCRLUA; } else { /* if is a C function, call it */ CallInfo *ci; int n; luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ ci = inc_ci(L); /* now `enter' new function */ ci->func = restorestack(L, funcr); L->base = ci->base = ci->func + 1; ci->top = L->top + LUA_MINSTACK; lua_assert(ci->top <= L->stack_last); ci->nresults = nresults; if (L->hookmask & LUA_MASKCALL) luaD_callhook(L, LUA_HOOKCALL, -1); lua_unlock(L); n = (*curr_func(L)->c.f)(L); /* do the actual call */ lua_lock(L); if (n < 0) /* yielding? */ return PCRYIELD; else { luaD_poscall(L, L->top - n); return PCRC; } } } static StkId callrethooks (lua_State *L, StkId firstResult) { ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ luaD_callhook(L, LUA_HOOKRET, -1); if (f_isLua(L->ci)) { /* Lua function? */ while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ luaD_callhook(L, LUA_HOOKTAILRET, -1); } return restorestack(L, fr); } int luaD_poscall (lua_State *L, StkId firstResult) { StkId res; int wanted, i; CallInfo *ci; if (L->hookmask & LUA_MASKRET) firstResult = callrethooks(L, firstResult); ci = L->ci--; res = ci->func; /* res == final position of 1st result */ wanted = ci->nresults; L->base = (ci - 1)->base; /* restore base */ L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ /* move results to correct place */ for (i = wanted; i != 0 && firstResult < L->top; i--) setobjs2s(L, res++, firstResult++); while (i-- > 0) setnilvalue(res++); L->top = res; return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ } /* ** Call a function (C or Lua). The function to be called is at *func. ** The arguments are on the stack, right after the function. ** When returns, all the results are on the stack, starting at the original ** function position. */ void luaD_call (lua_State *L, StkId func, int nResults) { if (++L->nCcalls >= LUAI_MAXCCALLS) { if (L->nCcalls == LUAI_MAXCCALLS) luaG_runerror(L, "C stack overflow"); else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ } if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ luaV_execute(L, 1); /* call it */ L->nCcalls--; luaC_checkGC(L); } static void resume (lua_State *L, void *ud) { StkId firstArg = cast(StkId, ud); CallInfo *ci = L->ci; if (L->status == 0) { /* start coroutine? */ lua_assert(ci == L->base_ci && firstArg > L->base); if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) return; } else { /* resuming from previous yield */ lua_assert(L->status == LUA_YIELD); L->status = 0; if (!f_isLua(ci)) { /* `common' yield? */ /* finish interrupted execution of `OP_CALL' */ lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); if (luaD_poscall(L, firstArg)) /* complete it... */ L->top = L->ci->top; /* and correct top if not multiple results */ } else /* yielded inside a hook: just continue its execution */ L->base = L->ci->base; } luaV_execute(L, cast_int(L->ci - L->base_ci)); } static int resume_error (lua_State *L, const char *msg) { L->top = L->ci->base; setsvalue2s(L, L->top, luaS_new(L, msg)); incr_top(L); lua_unlock(L); return LUA_ERRRUN; } LUA_API int lua_resume (lua_State *L, int nargs) { int status; lua_lock(L); if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) return resume_error(L, "cannot resume non-suspended coroutine"); if (L->nCcalls >= LUAI_MAXCCALLS) return resume_error(L, "C stack overflow"); luai_userstateresume(L, nargs); lua_assert(L->errfunc == 0); L->baseCcalls = ++L->nCcalls; status = luaD_rawrunprotected(L, resume, L->top - nargs); if (status != 0) { /* error? */ L->status = cast_byte(status); /* mark thread as `dead' */ luaD_seterrorobj(L, status, L->top); L->ci->top = L->top; } else { lua_assert(L->nCcalls == L->baseCcalls); status = L->status; } --L->nCcalls; lua_unlock(L); return status; } LUA_API int lua_yield (lua_State *L, int nresults) { luai_userstateyield(L, nresults); lua_lock(L); if (L->nCcalls > L->baseCcalls) luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); L->base = L->top - nresults; /* protect stack slots below */ L->status = LUA_YIELD; lua_unlock(L); return -1; } int luaD_pcall (lua_State *L, Pfunc func, void *u, ptrdiff_t old_top, ptrdiff_t ef) { int status; unsigned short oldnCcalls = L->nCcalls; ptrdiff_t old_ci = saveci(L, L->ci); lu_byte old_allowhooks = L->allowhook; ptrdiff_t old_errfunc = L->errfunc; L->errfunc = ef; status = luaD_rawrunprotected(L, func, u); if (status != 0) { /* an error occurred? */ StkId oldtop = restorestack(L, old_top); luaF_close(L, oldtop); /* close eventual pending closures */ luaD_seterrorobj(L, status, oldtop); L->nCcalls = oldnCcalls; L->ci = restoreci(L, old_ci); L->base = L->ci->base; L->savedpc = L->ci->savedpc; L->allowhook = old_allowhooks; restore_stack_limit(L); } L->errfunc = old_errfunc; return status; } /* ** Execute a protected parser. */ struct SParser { /* data to `f_parser' */ ZIO *z; Mbuffer buff; /* buffer to be used by the scanner */ const char *name; }; static void f_parser (lua_State *L, void *ud) { int i; Proto *tf; Closure *cl; struct SParser *p = cast(struct SParser *, ud); int c = luaZ_lookahead(p->z); luaC_checkGC(L); tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, &p->buff, p->name); cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); cl->l.p = tf; for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ cl->l.upvals[i] = luaF_newupval(L); setclvalue(L, L->top, cl); incr_top(L); } int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { struct SParser p; int status; p.z = z; p.name = name; luaZ_initbuffer(L, &p.buff); status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); luaZ_freebuffer(L, &p.buff); return status; } debian/grub-extras/lua/lvm.c0000664000000000000000000005514012524662415013172 0ustar /* ** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ #if 0 #include #include #include #endif #define lvm_c #define LUA_CORE #include "lua.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lgc.h" #include "lobject.h" #include "lopcodes.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" #include "lvm.h" /* limit for table tag-method chains (to avoid loops) */ #define MAXTAGLOOP 100 const TValue *luaV_tonumber (const TValue *obj, TValue *n) { lua_Number num; if (ttisnumber(obj)) return obj; if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { setnvalue(n, num); return n; } else return NULL; } int luaV_tostring (lua_State *L, StkId obj) { if (!ttisnumber(obj)) return 0; else { char s[LUAI_MAXNUMBER2STR]; lua_Number n = nvalue(obj); lua_number2str(s, n); setsvalue2s(L, obj, luaS_new(L, s)); return 1; } } static void traceexec (lua_State *L, const Instruction *pc) { lu_byte mask = L->hookmask; const Instruction *oldpc = L->savedpc; L->savedpc = pc; if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { resethookcount(L); luaD_callhook(L, LUA_HOOKCOUNT, -1); } if (mask & LUA_MASKLINE) { Proto *p = ci_func(L->ci)->l.p; int npc = pcRel(pc, p); int newline = getline(p, npc); /* call linehook when enter a new function, when jump back (loop), or when enter a new line */ if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) luaD_callhook(L, LUA_HOOKLINE, newline); } } static void callTMres (lua_State *L, StkId res, const TValue *f, const TValue *p1, const TValue *p2) { ptrdiff_t result = savestack(L, res); setobj2s(L, L->top, f); /* push function */ setobj2s(L, L->top+1, p1); /* 1st argument */ setobj2s(L, L->top+2, p2); /* 2nd argument */ luaD_checkstack(L, 3); L->top += 3; luaD_call(L, L->top - 3, 1); res = restorestack(L, result); L->top--; setobjs2s(L, res, L->top); } static void callTM (lua_State *L, const TValue *f, const TValue *p1, const TValue *p2, const TValue *p3) { setobj2s(L, L->top, f); /* push function */ setobj2s(L, L->top+1, p1); /* 1st argument */ setobj2s(L, L->top+2, p2); /* 2nd argument */ setobj2s(L, L->top+3, p3); /* 3th argument */ luaD_checkstack(L, 4); L->top += 4; luaD_call(L, L->top - 4, 0); } void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { int loop; for (loop = 0; loop < MAXTAGLOOP; loop++) { const TValue *tm; if (ttistable(t)) { /* `t' is a table? */ Table *h = hvalue(t); const TValue *res = luaH_get(h, key); /* do a primitive get */ if (!ttisnil(res) || /* result is no nil? */ (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ setobj2s(L, val, res); return; } /* else will try the tag method */ } else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) luaG_typeerror(L, t, "index"); if (ttisfunction(tm)) { callTMres(L, val, tm, t, key); return; } t = tm; /* else repeat with `tm' */ } luaG_runerror(L, "loop in gettable"); } void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { int loop; for (loop = 0; loop < MAXTAGLOOP; loop++) { const TValue *tm; if (ttistable(t)) { /* `t' is a table? */ Table *h = hvalue(t); TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ if (!ttisnil(oldval) || /* result is no nil? */ (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ setobj2t(L, oldval, val); luaC_barriert(L, h, val); return; } /* else will try the tag method */ } else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) luaG_typeerror(L, t, "index"); if (ttisfunction(tm)) { callTM(L, tm, t, key, val); return; } t = tm; /* else repeat with `tm' */ } luaG_runerror(L, "loop in settable"); } static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, StkId res, TMS event) { const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ if (ttisnil(tm)) tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ if (ttisnil(tm)) return 0; callTMres(L, res, tm, p1, p2); return 1; } static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, TMS event) { const TValue *tm1 = fasttm(L, mt1, event); const TValue *tm2; if (tm1 == NULL) return NULL; /* no metamethod */ if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ tm2 = fasttm(L, mt2, event); if (tm2 == NULL) return NULL; /* no metamethod */ if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ return tm1; return NULL; } static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, TMS event) { const TValue *tm1 = luaT_gettmbyobj(L, p1, event); const TValue *tm2; if (ttisnil(tm1)) return -1; /* no metamethod? */ tm2 = luaT_gettmbyobj(L, p2, event); if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ return -1; callTMres(L, L->top, tm1, p1, p2); return !l_isfalse(L->top); } static int l_strcmp (const TString *ls, const TString *rs) { const char *l = getstr(ls); size_t ll = ls->tsv.len; const char *r = getstr(rs); size_t lr = rs->tsv.len; for (;;) { int temp = strcoll(l, r); if (temp != 0) return temp; else { /* strings are equal up to a `\0' */ size_t len = strlen(l); /* index of first `\0' in both strings */ if (len == lr) /* r is finished? */ return (len == ll) ? 0 : 1; else if (len == ll) /* l is finished? */ return -1; /* l is smaller than r (because r is not finished) */ /* both strings longer than `len'; go on comparing (after the `\0') */ len++; l += len; ll -= len; r += len; lr -= len; } } } int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { int res; if (ttype(l) != ttype(r)) return luaG_ordererror(L, l, r); else if (ttisnumber(l)) return luai_numlt(nvalue(l), nvalue(r)); else if (ttisstring(l)) return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) return res; return luaG_ordererror(L, l, r); } static int lessequal (lua_State *L, const TValue *l, const TValue *r) { int res; if (ttype(l) != ttype(r)) return luaG_ordererror(L, l, r); else if (ttisnumber(l)) return luai_numle(nvalue(l), nvalue(r)); else if (ttisstring(l)) return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ return res; else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ return !res; return luaG_ordererror(L, l, r); } int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { const TValue *tm; lua_assert(ttype(t1) == ttype(t2)); switch (ttype(t1)) { case LUA_TNIL: return 1; case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); case LUA_TUSERDATA: { if (uvalue(t1) == uvalue(t2)) return 1; tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); break; /* will try TM */ } case LUA_TTABLE: { if (hvalue(t1) == hvalue(t2)) return 1; tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); break; /* will try TM */ } default: return gcvalue(t1) == gcvalue(t2); } if (tm == NULL) return 0; /* no TM? */ callTMres(L, L->top, tm, t1, t2); /* call TM */ return !l_isfalse(L->top); } void luaV_concat (lua_State *L, int total, int last) { do { StkId top = L->base + last + 1; int n = 2; /* number of elements handled in this pass (at least 2) */ if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) luaG_concaterror(L, top-2, top-1); } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ (void)tostring(L, top - 2); /* result is first op (as string) */ else { /* at least two string values; get as many as possible */ size_t tl = tsvalue(top-1)->len; char *buffer; int i; /* collect total length */ for (n = 1; n < total && tostring(L, top-n-1); n++) { size_t l = tsvalue(top-n-1)->len; if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); tl += l; } buffer = luaZ_openspace(L, &G(L)->buff, tl); tl = 0; for (i=n; i>0; i--) { /* concat all strings */ size_t l = tsvalue(top-i)->len; memcpy(buffer+tl, svalue(top-i), l); tl += l; } setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); } total -= n-1; /* got `n' strings to create 1 new */ last -= n-1; } while (total > 1); /* repeat until only 1 result left */ } static void Arith (lua_State *L, StkId ra, const TValue *rb, const TValue *rc, TMS op) { TValue tempb, tempc; const TValue *b, *c; if ((b = luaV_tonumber(rb, &tempb)) != NULL && (c = luaV_tonumber(rc, &tempc)) != NULL) { lua_Number nb = nvalue(b), nc = nvalue(c); switch (op) { case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break; case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break; case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; default: lua_assert(0); break; } } else if (!call_binTM(L, rb, rc, ra, op)) luaG_aritherror(L, rb, rc); } /* ** some macros for common tasks in `luaV_execute' */ #define runtime_check(L, c) { if (!(c)) break; } #define RA(i) (base+GETARG_A(i)) /* to be used after possible stack reallocation */ #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) #define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) #define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) #define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} #define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } #define arith_op(op,tm) { \ TValue *rb = RKB(i); \ TValue *rc = RKC(i); \ if (ttisnumber(rb) && ttisnumber(rc)) { \ lua_Number nb = nvalue(rb), nc = nvalue(rc); \ setnvalue(ra, op(nb, nc)); \ } \ else \ Protect(Arith(L, ra, rb, rc, tm)); \ } void luaV_execute (lua_State *L, int nexeccalls) { LClosure *cl; StkId base; TValue *k; const Instruction *pc; reentry: /* entry point */ lua_assert(isLua(L->ci)); pc = L->savedpc; cl = &clvalue(L->ci->func)->l; base = L->base; k = cl->p->k; /* main loop of interpreter */ for (;;) { const Instruction i = *pc++; StkId ra; if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { traceexec(L, pc); if (L->status == LUA_YIELD) { /* did hook yield? */ L->savedpc = pc - 1; return; } base = L->base; } /* warning!! several calls may realloc the stack and invalidate `ra' */ ra = RA(i); lua_assert(base == L->base && L->base == L->ci->base); lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); switch (GET_OPCODE(i)) { case OP_MOVE: { setobjs2s(L, ra, RB(i)); continue; } case OP_LOADK: { setobj2s(L, ra, KBx(i)); continue; } case OP_LOADBOOL: { setbvalue(ra, GETARG_B(i)); if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ continue; } case OP_LOADNIL: { TValue *rb = RB(i); do { setnilvalue(rb--); } while (rb >= ra); continue; } case OP_GETUPVAL: { int b = GETARG_B(i); setobj2s(L, ra, cl->upvals[b]->v); continue; } case OP_GETGLOBAL: { TValue g; TValue *rb = KBx(i); sethvalue(L, &g, cl->env); lua_assert(ttisstring(rb)); Protect(luaV_gettable(L, &g, rb, ra)); continue; } case OP_GETTABLE: { Protect(luaV_gettable(L, RB(i), RKC(i), ra)); continue; } case OP_SETGLOBAL: { TValue g; sethvalue(L, &g, cl->env); lua_assert(ttisstring(KBx(i))); Protect(luaV_settable(L, &g, KBx(i), ra)); continue; } case OP_SETUPVAL: { UpVal *uv = cl->upvals[GETARG_B(i)]; setobj(L, uv->v, ra); luaC_barrier(L, uv, ra); continue; } case OP_SETTABLE: { Protect(luaV_settable(L, ra, RKB(i), RKC(i))); continue; } case OP_NEWTABLE: { int b = GETARG_B(i); int c = GETARG_C(i); sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); Protect(luaC_checkGC(L)); continue; } case OP_SELF: { StkId rb = RB(i); setobjs2s(L, ra+1, rb); Protect(luaV_gettable(L, rb, RKC(i), ra)); continue; } case OP_ADD: { arith_op(luai_numadd, TM_ADD); continue; } case OP_SUB: { arith_op(luai_numsub, TM_SUB); continue; } case OP_MUL: { arith_op(luai_nummul, TM_MUL); continue; } case OP_DIV: { arith_op(luai_numdiv, TM_DIV); continue; } case OP_MOD: { arith_op(luai_nummod, TM_MOD); continue; } case OP_POW: { arith_op(luai_numpow, TM_POW); continue; } case OP_UNM: { TValue *rb = RB(i); if (ttisnumber(rb)) { lua_Number nb = nvalue(rb); setnvalue(ra, luai_numunm(nb)); } else { Protect(Arith(L, ra, rb, rb, TM_UNM)); } continue; } case OP_NOT: { int res = l_isfalse(RB(i)); /* next assignment may change this value */ setbvalue(ra, res); continue; } case OP_LEN: { const TValue *rb = RB(i); switch (ttype(rb)) { case LUA_TTABLE: { setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); break; } case LUA_TSTRING: { setnvalue(ra, cast_num(tsvalue(rb)->len)); break; } default: { /* try metamethod */ Protect( if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) luaG_typeerror(L, rb, "get length of"); ) } } continue; } case OP_CONCAT: { int b = GETARG_B(i); int c = GETARG_C(i); Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); setobjs2s(L, RA(i), base+b); continue; } case OP_JMP: { dojump(L, pc, GETARG_sBx(i)); continue; } case OP_EQ: { TValue *rb = RKB(i); TValue *rc = RKC(i); Protect( if (equalobj(L, rb, rc) == GETARG_A(i)) dojump(L, pc, GETARG_sBx(*pc)); ) pc++; continue; } case OP_LT: { Protect( if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) dojump(L, pc, GETARG_sBx(*pc)); ) pc++; continue; } case OP_LE: { Protect( if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) dojump(L, pc, GETARG_sBx(*pc)); ) pc++; continue; } case OP_TEST: { if (l_isfalse(ra) != GETARG_C(i)) dojump(L, pc, GETARG_sBx(*pc)); pc++; continue; } case OP_TESTSET: { TValue *rb = RB(i); if (l_isfalse(rb) != GETARG_C(i)) { setobjs2s(L, ra, rb); dojump(L, pc, GETARG_sBx(*pc)); } pc++; continue; } case OP_CALL: { int b = GETARG_B(i); int nresults = GETARG_C(i) - 1; if (b != 0) L->top = ra+b; /* else previous instruction set top */ L->savedpc = pc; switch (luaD_precall(L, ra, nresults)) { case PCRLUA: { nexeccalls++; goto reentry; /* restart luaV_execute over new Lua function */ } case PCRC: { /* it was a C function (`precall' called it); adjust results */ if (nresults >= 0) L->top = L->ci->top; base = L->base; continue; } default: { return; /* yield */ } } } case OP_TAILCALL: { int b = GETARG_B(i); if (b != 0) L->top = ra+b; /* else previous instruction set top */ L->savedpc = pc; lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); switch (luaD_precall(L, ra, LUA_MULTRET)) { case PCRLUA: { /* tail call: put new frame in place of previous one */ CallInfo *ci = L->ci - 1; /* previous frame */ int aux; StkId func = ci->func; StkId pfunc = (ci+1)->func; /* previous function index */ if (L->openupval) luaF_close(L, ci->base); L->base = ci->base = ci->func + ((ci+1)->base - pfunc); for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ setobjs2s(L, func+aux, pfunc+aux); ci->top = L->top = func+aux; /* correct top */ lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); ci->savedpc = L->savedpc; ci->tailcalls++; /* one more call lost */ L->ci--; /* remove new frame */ goto reentry; } case PCRC: { /* it was a C function (`precall' called it) */ base = L->base; continue; } default: { return; /* yield */ } } } case OP_RETURN: { int b = GETARG_B(i); if (b != 0) L->top = ra+b-1; if (L->openupval) luaF_close(L, base); L->savedpc = pc; b = luaD_poscall(L, ra); if (--nexeccalls == 0) /* was previous function running `here'? */ return; /* no: return */ else { /* yes: continue its execution */ if (b) L->top = L->ci->top; lua_assert(isLua(L->ci)); lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); goto reentry; } } case OP_FORLOOP: { lua_Number step = nvalue(ra+2); lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ lua_Number limit = nvalue(ra+1); if (luai_numlt(0, step) ? luai_numle(idx, limit) : luai_numle(limit, idx)) { dojump(L, pc, GETARG_sBx(i)); /* jump back */ setnvalue(ra, idx); /* update internal index... */ setnvalue(ra+3, idx); /* ...and external index */ } continue; } case OP_FORPREP: { const TValue *init = ra; const TValue *plimit = ra+1; const TValue *pstep = ra+2; L->savedpc = pc; /* next steps may throw errors */ if (!tonumber(init, ra)) luaG_runerror(L, LUA_QL("for") " initial value must be a number"); else if (!tonumber(plimit, ra+1)) luaG_runerror(L, LUA_QL("for") " limit must be a number"); else if (!tonumber(pstep, ra+2)) luaG_runerror(L, LUA_QL("for") " step must be a number"); setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); dojump(L, pc, GETARG_sBx(i)); continue; } case OP_TFORLOOP: { StkId cb = ra + 3; /* call base */ setobjs2s(L, cb+2, ra+2); setobjs2s(L, cb+1, ra+1); setobjs2s(L, cb, ra); L->top = cb+3; /* func. + 2 args (state and index) */ Protect(luaD_call(L, cb, GETARG_C(i))); L->top = L->ci->top; cb = RA(i) + 3; /* previous call may change the stack */ if (!ttisnil(cb)) { /* continue loop? */ setobjs2s(L, cb-1, cb); /* save control variable */ dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ } pc++; continue; } case OP_SETLIST: { int n = GETARG_B(i); int c = GETARG_C(i); int last; Table *h; if (n == 0) { n = cast_int(L->top - ra) - 1; L->top = L->ci->top; } if (c == 0) c = cast_int(*pc++); runtime_check(L, ttistable(ra)); h = hvalue(ra); last = ((c-1)*LFIELDS_PER_FLUSH) + n; if (last > h->sizearray) /* needs more space? */ luaH_resizearray(L, h, last); /* pre-alloc it at once */ for (; n > 0; n--) { TValue *val = ra+n; setobj2t(L, luaH_setnum(L, h, last--), val); luaC_barriert(L, h, val); } continue; } case OP_CLOSE: { luaF_close(L, ra); continue; } case OP_CLOSURE: { Proto *p; Closure *ncl; int nup, j; p = cl->p->p[GETARG_Bx(i)]; nup = p->nups; ncl = luaF_newLclosure(L, nup, cl->env); ncl->l.p = p; for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)]; else { lua_assert(GET_OPCODE(*pc) == OP_MOVE); ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); } } setclvalue(L, ra, ncl); Protect(luaC_checkGC(L)); continue; } case OP_VARARG: { int b = GETARG_B(i) - 1; int j; CallInfo *ci = L->ci; int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; if (b == LUA_MULTRET) { Protect(luaD_checkstack(L, n)); ra = RA(i); /* previous call may change the stack */ b = n; L->top = ra + n; } for (j = 0; j < b; j++) { if (j < n) { setobjs2s(L, ra + j, ci->base - n + j); } else { setnilvalue(ra + j); } } continue; } } } } debian/grub-extras/lua/lapi.c0000664000000000000000000005427612524662415013332 0ustar /* ** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $ ** Lua API ** See Copyright Notice in lua.h */ #if 0 #include #include #include #include #endif #define lapi_c #define LUA_CORE #include "lua.h" #include "lapi.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lgc.h" #include "lmem.h" #include "lobject.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" #include "lundump.h" #include "lvm.h" const char lua_ident[] = "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n" "$Authors: " LUA_AUTHORS " $\n" "$URL: www.lua.org $\n"; #define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) #define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) #define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} static TValue *index2adr (lua_State *L, int idx) { if (idx > 0) { TValue *o = L->base + (idx - 1); api_check(L, idx <= L->ci->top - L->base); if (o >= L->top) return cast(TValue *, luaO_nilobject); else return o; } else if (idx > LUA_REGISTRYINDEX) { api_check(L, idx != 0 && -idx <= L->top - L->base); return L->top + idx; } else switch (idx) { /* pseudo-indices */ case LUA_REGISTRYINDEX: return registry(L); case LUA_ENVIRONINDEX: { Closure *func = curr_func(L); sethvalue(L, &L->env, func->c.env); return &L->env; } case LUA_GLOBALSINDEX: return gt(L); default: { Closure *func = curr_func(L); idx = LUA_GLOBALSINDEX - idx; return (idx <= func->c.nupvalues) ? &func->c.upvalue[idx-1] : cast(TValue *, luaO_nilobject); } } } static Table *getcurrenv (lua_State *L) { if (L->ci == L->base_ci) /* no enclosing function? */ return hvalue(gt(L)); /* use global table as environment */ else { Closure *func = curr_func(L); return func->c.env; } } void luaA_pushobject (lua_State *L, const TValue *o) { setobj2s(L, L->top, o); api_incr_top(L); } LUA_API int lua_checkstack (lua_State *L, int size) { int res = 1; lua_lock(L); if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) res = 0; /* stack overflow */ else if (size > 0) { luaD_checkstack(L, size); if (L->ci->top < L->top + size) L->ci->top = L->top + size; } lua_unlock(L); return res; } LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { int i; if (from == to) return; lua_lock(to); api_checknelems(from, n); api_check(from, G(from) == G(to)); api_check(from, to->ci->top - to->top >= n); from->top -= n; for (i = 0; i < n; i++) { setobj2s(to, to->top++, from->top + i); } lua_unlock(to); } LUA_API void lua_setlevel (lua_State *from, lua_State *to) { to->nCcalls = from->nCcalls; } LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { lua_CFunction old; lua_lock(L); old = G(L)->panic; G(L)->panic = panicf; lua_unlock(L); return old; } LUA_API lua_State *lua_newthread (lua_State *L) { lua_State *L1; lua_lock(L); luaC_checkGC(L); L1 = luaE_newthread(L); setthvalue(L, L->top, L1); api_incr_top(L); lua_unlock(L); luai_userstatethread(L, L1); return L1; } /* ** basic stack manipulation */ LUA_API int lua_gettop (lua_State *L) { return cast_int(L->top - L->base); } LUA_API void lua_settop (lua_State *L, int idx) { lua_lock(L); if (idx >= 0) { api_check(L, idx <= L->stack_last - L->base); while (L->top < L->base + idx) setnilvalue(L->top++); L->top = L->base + idx; } else { api_check(L, -(idx+1) <= (L->top - L->base)); L->top += idx+1; /* `subtract' index (index is negative) */ } lua_unlock(L); } LUA_API void lua_remove (lua_State *L, int idx) { StkId p; lua_lock(L); p = index2adr(L, idx); api_checkvalidindex(L, p); while (++p < L->top) setobjs2s(L, p-1, p); L->top--; lua_unlock(L); } LUA_API void lua_insert (lua_State *L, int idx) { StkId p; StkId q; lua_lock(L); p = index2adr(L, idx); api_checkvalidindex(L, p); for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); setobjs2s(L, p, L->top); lua_unlock(L); } LUA_API void lua_replace (lua_State *L, int idx) { StkId o; lua_lock(L); /* explicit test for incompatible code */ if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) luaG_runerror(L, "no calling environment"); api_checknelems(L, 1); o = index2adr(L, idx); api_checkvalidindex(L, o); if (idx == LUA_ENVIRONINDEX) { Closure *func = curr_func(L); api_check(L, ttistable(L->top - 1)); func->c.env = hvalue(L->top - 1); luaC_barrier(L, func, L->top - 1); } else { setobj(L, o, L->top - 1); if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ luaC_barrier(L, curr_func(L), L->top - 1); } L->top--; lua_unlock(L); } LUA_API void lua_pushvalue (lua_State *L, int idx) { lua_lock(L); setobj2s(L, L->top, index2adr(L, idx)); api_incr_top(L); lua_unlock(L); } /* ** access functions (stack -> C) */ LUA_API int lua_type (lua_State *L, int idx) { StkId o = index2adr(L, idx); return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); } LUA_API const char *lua_typename (lua_State *L, int t) { UNUSED(L); return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; } LUA_API int lua_iscfunction (lua_State *L, int idx) { StkId o = index2adr(L, idx); return iscfunction(o); } LUA_API int lua_isnumber (lua_State *L, int idx) { TValue n; const TValue *o = index2adr(L, idx); return tonumber(o, &n); } LUA_API int lua_isstring (lua_State *L, int idx) { int t = lua_type(L, idx); return (t == LUA_TSTRING || t == LUA_TNUMBER); } LUA_API int lua_isuserdata (lua_State *L, int idx) { const TValue *o = index2adr(L, idx); return (ttisuserdata(o) || ttislightuserdata(o)); } LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { StkId o1 = index2adr(L, index1); StkId o2 = index2adr(L, index2); return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : luaO_rawequalObj(o1, o2); } LUA_API int lua_equal (lua_State *L, int index1, int index2) { StkId o1, o2; int i; lua_lock(L); /* may call tag method */ o1 = index2adr(L, index1); o2 = index2adr(L, index2); i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); lua_unlock(L); return i; } LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { StkId o1, o2; int i; lua_lock(L); /* may call tag method */ o1 = index2adr(L, index1); o2 = index2adr(L, index2); i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : luaV_lessthan(L, o1, o2); lua_unlock(L); return i; } LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { TValue n; const TValue *o = index2adr(L, idx); if (tonumber(o, &n)) return nvalue(o); else return 0; } LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { TValue n; const TValue *o = index2adr(L, idx); if (tonumber(o, &n)) { lua_Integer res; lua_Number num = nvalue(o); lua_number2integer(res, num); return res; } else return 0; } LUA_API int lua_toboolean (lua_State *L, int idx) { const TValue *o = index2adr(L, idx); return !l_isfalse(o); } LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { StkId o = index2adr(L, idx); if (!ttisstring(o)) { lua_lock(L); /* `luaV_tostring' may create a new string */ if (!luaV_tostring(L, o)) { /* conversion failed? */ if (len != NULL) *len = 0; lua_unlock(L); return NULL; } luaC_checkGC(L); o = index2adr(L, idx); /* previous call may reallocate the stack */ lua_unlock(L); } if (len != NULL) *len = tsvalue(o)->len; return svalue(o); } LUA_API size_t lua_objlen (lua_State *L, int idx) { StkId o = index2adr(L, idx); switch (ttype(o)) { case LUA_TSTRING: return tsvalue(o)->len; case LUA_TUSERDATA: return uvalue(o)->len; case LUA_TTABLE: return luaH_getn(hvalue(o)); case LUA_TNUMBER: { size_t l; lua_lock(L); /* `luaV_tostring' may create a new string */ l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); lua_unlock(L); return l; } default: return 0; } } LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { StkId o = index2adr(L, idx); return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; } LUA_API void *lua_touserdata (lua_State *L, int idx) { StkId o = index2adr(L, idx); switch (ttype(o)) { case LUA_TUSERDATA: return (rawuvalue(o) + 1); case LUA_TLIGHTUSERDATA: return pvalue(o); default: return NULL; } } LUA_API lua_State *lua_tothread (lua_State *L, int idx) { StkId o = index2adr(L, idx); return (!ttisthread(o)) ? NULL : thvalue(o); } LUA_API const void *lua_topointer (lua_State *L, int idx) { StkId o = index2adr(L, idx); switch (ttype(o)) { case LUA_TTABLE: return hvalue(o); case LUA_TFUNCTION: return clvalue(o); case LUA_TTHREAD: return thvalue(o); case LUA_TUSERDATA: case LUA_TLIGHTUSERDATA: return lua_touserdata(L, idx); default: return NULL; } } /* ** push functions (C -> stack) */ LUA_API void lua_pushnil (lua_State *L) { lua_lock(L); setnilvalue(L->top); api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { lua_lock(L); setnvalue(L->top, n); api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { lua_lock(L); setnvalue(L->top, cast_num(n)); api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { lua_lock(L); luaC_checkGC(L); setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushstring (lua_State *L, const char *s) { if (s == NULL) lua_pushnil(L); else lua_pushlstring(L, s, strlen(s)); } LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp) { const char *ret; lua_lock(L); luaC_checkGC(L); ret = luaO_pushvfstring(L, fmt, argp); lua_unlock(L); return ret; } LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { const char *ret; va_list argp; lua_lock(L); luaC_checkGC(L); va_start(argp, fmt); ret = luaO_pushvfstring(L, fmt, argp); va_end(argp); lua_unlock(L); return ret; } LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { Closure *cl; lua_lock(L); luaC_checkGC(L); api_checknelems(L, n); cl = luaF_newCclosure(L, n, getcurrenv(L)); cl->c.f = fn; L->top -= n; while (n--) setobj2n(L, &cl->c.upvalue[n], L->top+n); setclvalue(L, L->top, cl); lua_assert(iswhite(obj2gco(cl))); api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushboolean (lua_State *L, int b) { lua_lock(L); setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { lua_lock(L); setpvalue(L->top, p); api_incr_top(L); lua_unlock(L); } LUA_API int lua_pushthread (lua_State *L) { lua_lock(L); setthvalue(L, L->top, L); api_incr_top(L); lua_unlock(L); return (G(L)->mainthread == L); } /* ** get functions (Lua -> stack) */ LUA_API void lua_gettable (lua_State *L, int idx) { StkId t; lua_lock(L); t = index2adr(L, idx); api_checkvalidindex(L, t); luaV_gettable(L, t, L->top - 1, L->top - 1); lua_unlock(L); } LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { StkId t; TValue key; lua_lock(L); t = index2adr(L, idx); api_checkvalidindex(L, t); setsvalue(L, &key, luaS_new(L, k)); luaV_gettable(L, t, &key, L->top); api_incr_top(L); lua_unlock(L); } LUA_API void lua_rawget (lua_State *L, int idx) { StkId t; lua_lock(L); t = index2adr(L, idx); api_check(L, ttistable(t)); setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); lua_unlock(L); } LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { StkId o; lua_lock(L); o = index2adr(L, idx); api_check(L, ttistable(o)); setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); api_incr_top(L); lua_unlock(L); } LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { lua_lock(L); luaC_checkGC(L); sethvalue(L, L->top, luaH_new(L, narray, nrec)); api_incr_top(L); lua_unlock(L); } LUA_API int lua_getmetatable (lua_State *L, int objindex) { const TValue *obj; Table *mt = NULL; int res; lua_lock(L); obj = index2adr(L, objindex); switch (ttype(obj)) { case LUA_TTABLE: mt = hvalue(obj)->metatable; break; case LUA_TUSERDATA: mt = uvalue(obj)->metatable; break; default: mt = G(L)->mt[ttype(obj)]; break; } if (mt == NULL) res = 0; else { sethvalue(L, L->top, mt); api_incr_top(L); res = 1; } lua_unlock(L); return res; } LUA_API void lua_getfenv (lua_State *L, int idx) { StkId o; lua_lock(L); o = index2adr(L, idx); api_checkvalidindex(L, o); switch (ttype(o)) { case LUA_TFUNCTION: sethvalue(L, L->top, clvalue(o)->c.env); break; case LUA_TUSERDATA: sethvalue(L, L->top, uvalue(o)->env); break; case LUA_TTHREAD: setobj2s(L, L->top, gt(thvalue(o))); break; default: setnilvalue(L->top); break; } api_incr_top(L); lua_unlock(L); } /* ** set functions (stack -> Lua) */ LUA_API void lua_settable (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); t = index2adr(L, idx); api_checkvalidindex(L, t); luaV_settable(L, t, L->top - 2, L->top - 1); L->top -= 2; /* pop index and value */ lua_unlock(L); } LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { StkId t; TValue key; lua_lock(L); api_checknelems(L, 1); t = index2adr(L, idx); api_checkvalidindex(L, t); setsvalue(L, &key, luaS_new(L, k)); luaV_settable(L, t, &key, L->top - 1); L->top--; /* pop value */ lua_unlock(L); } LUA_API void lua_rawset (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); t = index2adr(L, idx); api_check(L, ttistable(t)); setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); luaC_barriert(L, hvalue(t), L->top-1); L->top -= 2; lua_unlock(L); } LUA_API void lua_rawseti (lua_State *L, int idx, int n) { StkId o; lua_lock(L); api_checknelems(L, 1); o = index2adr(L, idx); api_check(L, ttistable(o)); setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); luaC_barriert(L, hvalue(o), L->top-1); L->top--; lua_unlock(L); } LUA_API int lua_setmetatable (lua_State *L, int objindex) { TValue *obj; Table *mt; lua_lock(L); api_checknelems(L, 1); obj = index2adr(L, objindex); api_checkvalidindex(L, obj); if (ttisnil(L->top - 1)) mt = NULL; else { api_check(L, ttistable(L->top - 1)); mt = hvalue(L->top - 1); } switch (ttype(obj)) { case LUA_TTABLE: { hvalue(obj)->metatable = mt; if (mt) luaC_objbarriert(L, hvalue(obj), mt); break; } case LUA_TUSERDATA: { uvalue(obj)->metatable = mt; if (mt) luaC_objbarrier(L, rawuvalue(obj), mt); break; } default: { G(L)->mt[ttype(obj)] = mt; break; } } L->top--; lua_unlock(L); return 1; } LUA_API int lua_setfenv (lua_State *L, int idx) { StkId o; int res = 1; lua_lock(L); api_checknelems(L, 1); o = index2adr(L, idx); api_checkvalidindex(L, o); api_check(L, ttistable(L->top - 1)); switch (ttype(o)) { case LUA_TFUNCTION: clvalue(o)->c.env = hvalue(L->top - 1); break; case LUA_TUSERDATA: uvalue(o)->env = hvalue(L->top - 1); break; case LUA_TTHREAD: sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); break; default: res = 0; break; } if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); L->top--; lua_unlock(L); return res; } /* ** `load' and `call' functions (run Lua code) */ #define adjustresults(L,nres) \ { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } #define checkresults(L,na,nr) \ api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) LUA_API void lua_call (lua_State *L, int nargs, int nresults) { StkId func; lua_lock(L); api_checknelems(L, nargs+1); checkresults(L, nargs, nresults); func = L->top - (nargs+1); luaD_call(L, func, nresults); adjustresults(L, nresults); lua_unlock(L); } /* ** Execute a protected call. */ struct CallS { /* data to `f_call' */ StkId func; int nresults; }; static void f_call (lua_State *L, void *ud) { struct CallS *c = cast(struct CallS *, ud); luaD_call(L, c->func, c->nresults); } LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { struct CallS c; int status; ptrdiff_t func; lua_lock(L); api_checknelems(L, nargs+1); checkresults(L, nargs, nresults); if (errfunc == 0) func = 0; else { StkId o = index2adr(L, errfunc); api_checkvalidindex(L, o); func = savestack(L, o); } c.func = L->top - (nargs+1); /* function to be called */ c.nresults = nresults; status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); adjustresults(L, nresults); lua_unlock(L); return status; } /* ** Execute a protected C call. */ struct CCallS { /* data to `f_Ccall' */ lua_CFunction func; void *ud; }; static void f_Ccall (lua_State *L, void *ud) { struct CCallS *c = cast(struct CCallS *, ud); Closure *cl; cl = luaF_newCclosure(L, 0, getcurrenv(L)); cl->c.f = c->func; setclvalue(L, L->top, cl); /* push function */ api_incr_top(L); setpvalue(L->top, c->ud); /* push only argument */ api_incr_top(L); luaD_call(L, L->top - 2, 0); } LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { struct CCallS c; int status; lua_lock(L); c.func = func; c.ud = ud; status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); lua_unlock(L); return status; } LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char *chunkname) { ZIO z; int status; lua_lock(L); if (!chunkname) chunkname = "?"; luaZ_init(L, &z, reader, data); status = luaD_protectedparser(L, &z, chunkname); lua_unlock(L); return status; } LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { int status; TValue *o; lua_lock(L); api_checknelems(L, 1); o = L->top - 1; if (isLfunction(o)) status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); else status = 1; lua_unlock(L); return status; } LUA_API int lua_status (lua_State *L) { return L->status; } /* ** Garbage-collection function */ LUA_API int lua_gc (lua_State *L, int what, int data) { int res = 0; global_State *g; lua_lock(L); g = G(L); switch (what) { case LUA_GCSTOP: { g->GCthreshold = MAX_LUMEM; break; } case LUA_GCRESTART: { g->GCthreshold = g->totalbytes; break; } case LUA_GCCOLLECT: { luaC_fullgc(L); break; } case LUA_GCCOUNT: { /* GC values are expressed in Kbytes: #bytes/2^10 */ res = cast_int(g->totalbytes >> 10); break; } case LUA_GCCOUNTB: { res = cast_int(g->totalbytes & 0x3ff); break; } case LUA_GCSTEP: { lu_mem a = (cast(lu_mem, data) << 10); if (a <= g->totalbytes) g->GCthreshold = g->totalbytes - a; else g->GCthreshold = 0; while (g->GCthreshold <= g->totalbytes) { luaC_step(L); if (g->gcstate == GCSpause) { /* end of cycle? */ res = 1; /* signal it */ break; } } break; } case LUA_GCSETPAUSE: { res = g->gcpause; g->gcpause = data; break; } case LUA_GCSETSTEPMUL: { res = g->gcstepmul; g->gcstepmul = data; break; } default: res = -1; /* invalid option */ } lua_unlock(L); return res; } /* ** miscellaneous functions */ LUA_API int lua_error (lua_State *L) { lua_lock(L); api_checknelems(L, 1); luaG_errormsg(L); lua_unlock(L); return 0; /* to avoid warnings */ } LUA_API int lua_next (lua_State *L, int idx) { StkId t; int more; lua_lock(L); t = index2adr(L, idx); api_check(L, ttistable(t)); more = luaH_next(L, hvalue(t), L->top - 1); if (more) { api_incr_top(L); } else /* no more elements */ L->top -= 1; /* remove key */ lua_unlock(L); return more; } LUA_API void lua_concat (lua_State *L, int n) { lua_lock(L); api_checknelems(L, n); if (n >= 2) { luaC_checkGC(L); luaV_concat(L, n, cast_int(L->top - L->base) - 1); L->top -= (n-1); } else if (n == 0) { /* push empty string */ setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); api_incr_top(L); } /* else n == 1; nothing to do */ lua_unlock(L); } LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { lua_Alloc f; lua_lock(L); if (ud) *ud = G(L)->ud; f = G(L)->frealloc; lua_unlock(L); return f; } LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { lua_lock(L); G(L)->ud = ud; G(L)->frealloc = f; lua_unlock(L); } LUA_API void *lua_newuserdata (lua_State *L, size_t size) { Udata *u; lua_lock(L); luaC_checkGC(L); u = luaS_newudata(L, size, getcurrenv(L)); setuvalue(L, L->top, u); api_incr_top(L); lua_unlock(L); return u + 1; } static const char *aux_upvalue (StkId fi, int n, TValue **val) { Closure *f; if (!ttisfunction(fi)) return NULL; f = clvalue(fi); if (f->c.isC) { if (!(1 <= n && n <= f->c.nupvalues)) return NULL; *val = &f->c.upvalue[n-1]; return ""; } else { Proto *p = f->l.p; if (!(1 <= n && n <= p->sizeupvalues)) return NULL; *val = f->l.upvals[n-1]->v; return getstr(p->upvalues[n-1]); } } LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { const char *name; TValue *val; lua_lock(L); name = aux_upvalue(index2adr(L, funcindex), n, &val); if (name) { setobj2s(L, L->top, val); api_incr_top(L); } lua_unlock(L); return name; } LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { const char *name; TValue *val; StkId fi; lua_lock(L); fi = index2adr(L, funcindex); api_checknelems(L, 1); name = aux_upvalue(fi, n, &val); if (name) { L->top--; setobj(L, val, L->top); luaC_barrier(L, clvalue(fi), L->top); } lua_unlock(L); return name; } debian/grub-extras/lua/lgc.c0000664000000000000000000004721612524662415013146 0ustar /* ** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ #if 0 #include #endif #define lgc_c #define LUA_CORE #include "lua.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lgc.h" #include "lmem.h" #include "lobject.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" #define GCSTEPSIZE 1024u #define GCSWEEPMAX 40 #define GCSWEEPCOST 10 #define GCFINALIZECOST 100 #define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) #define makewhite(g,x) \ ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) #define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) #define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) #define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) #define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) #define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) #define KEYWEAK bitmask(KEYWEAKBIT) #define VALUEWEAK bitmask(VALUEWEAKBIT) #define markvalue(g,o) { checkconsistency(o); \ if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } #define markobject(g,t) { if (iswhite(obj2gco(t))) \ reallymarkobject(g, obj2gco(t)); } #define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) static void removeentry (Node *n) { lua_assert(ttisnil(gval(n))); if (iscollectable(gkey(n))) setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ } static void reallymarkobject (global_State *g, GCObject *o) { lua_assert(iswhite(o) && !isdead(g, o)); white2gray(o); switch (o->gch.tt) { case LUA_TSTRING: { return; } case LUA_TUSERDATA: { Table *mt = gco2u(o)->metatable; gray2black(o); /* udata are never gray */ if (mt) markobject(g, mt); markobject(g, gco2u(o)->env); return; } case LUA_TUPVAL: { UpVal *uv = gco2uv(o); markvalue(g, uv->v); if (uv->v == &uv->u.value) /* closed? */ gray2black(o); /* open upvalues are never black */ return; } case LUA_TFUNCTION: { gco2cl(o)->c.gclist = g->gray; g->gray = o; break; } case LUA_TTABLE: { gco2h(o)->gclist = g->gray; g->gray = o; break; } case LUA_TTHREAD: { gco2th(o)->gclist = g->gray; g->gray = o; break; } case LUA_TPROTO: { gco2p(o)->gclist = g->gray; g->gray = o; break; } default: lua_assert(0); } } static void marktmu (global_State *g) { GCObject *u = g->tmudata; if (u) { do { u = u->gch.next; makewhite(g, u); /* may be marked, if left from previous GC */ reallymarkobject(g, u); } while (u != g->tmudata); } } /* move `dead' udata that need finalization to list `tmudata' */ size_t luaC_separateudata (lua_State *L, int all) { global_State *g = G(L); size_t deadmem = 0; GCObject **p = &g->mainthread->next; GCObject *curr; while ((curr = *p) != NULL) { if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) p = &curr->gch.next; /* don't bother with them */ else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { markfinalized(gco2u(curr)); /* don't need finalization */ p = &curr->gch.next; } else { /* must call its gc method */ deadmem += sizeudata(gco2u(curr)); markfinalized(gco2u(curr)); *p = curr->gch.next; /* link `curr' at the end of `tmudata' list */ if (g->tmudata == NULL) /* list is empty? */ g->tmudata = curr->gch.next = curr; /* creates a circular list */ else { curr->gch.next = g->tmudata->gch.next; g->tmudata->gch.next = curr; g->tmudata = curr; } } } return deadmem; } static int traversetable (global_State *g, Table *h) { int i; int weakkey = 0; int weakvalue = 0; const TValue *mode; if (h->metatable) markobject(g, h->metatable); mode = gfasttm(g, h->metatable, TM_MODE); if (mode && ttisstring(mode)) { /* is there a weak mode? */ weakkey = (strchr(svalue(mode), 'k') != NULL); weakvalue = (strchr(svalue(mode), 'v') != NULL); if (weakkey || weakvalue) { /* is really weak? */ h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ h->marked |= cast_byte((weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT)); h->gclist = g->weak; /* must be cleared after GC, ... */ g->weak = obj2gco(h); /* ... so put in the appropriate list */ } } if (weakkey && weakvalue) return 1; if (!weakvalue) { i = h->sizearray; while (i--) markvalue(g, &h->array[i]); } i = sizenode(h); while (i--) { Node *n = gnode(h, i); lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); if (ttisnil(gval(n))) removeentry(n); /* remove empty entries */ else { lua_assert(!ttisnil(gkey(n))); if (!weakkey) markvalue(g, gkey(n)); if (!weakvalue) markvalue(g, gval(n)); } } return weakkey || weakvalue; } /* ** All marks are conditional because a GC may happen while the ** prototype is still being created */ static void traverseproto (global_State *g, Proto *f) { int i; if (f->source) stringmark(f->source); for (i=0; isizek; i++) /* mark literals */ markvalue(g, &f->k[i]); for (i=0; isizeupvalues; i++) { /* mark upvalue names */ if (f->upvalues[i]) stringmark(f->upvalues[i]); } for (i=0; isizep; i++) { /* mark nested protos */ if (f->p[i]) markobject(g, f->p[i]); } for (i=0; isizelocvars; i++) { /* mark local-variable names */ if (f->locvars[i].varname) stringmark(f->locvars[i].varname); } } static void traverseclosure (global_State *g, Closure *cl) { markobject(g, cl->c.env); if (cl->c.isC) { int i; for (i=0; ic.nupvalues; i++) /* mark its upvalues */ markvalue(g, &cl->c.upvalue[i]); } else { int i; lua_assert(cl->l.nupvalues == cl->l.p->nups); markobject(g, cl->l.p); for (i=0; il.nupvalues; i++) /* mark its upvalues */ markobject(g, cl->l.upvals[i]); } } static void checkstacksizes (lua_State *L, StkId max) { int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ int s_used = cast_int(max - L->stack); /* part of stack in use */ if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ return; /* do not touch the stacks */ if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ condhardstacktests(luaD_reallocCI(L, ci_used + 1)); if (4*s_used < L->stacksize && 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ condhardstacktests(luaD_reallocstack(L, s_used)); } static void traversestack (global_State *g, lua_State *l) { StkId o, lim; CallInfo *ci; markvalue(g, gt(l)); lim = l->top; for (ci = l->base_ci; ci <= l->ci; ci++) { lua_assert(ci->top <= l->stack_last); if (lim < ci->top) lim = ci->top; } for (o = l->stack; o < l->top; o++) markvalue(g, o); for (; o <= lim; o++) setnilvalue(o); checkstacksizes(l, lim); } /* ** traverse one gray object, turning it to black. ** Returns `quantity' traversed. */ static l_mem propagatemark (global_State *g) { GCObject *o = g->gray; lua_assert(isgray(o)); gray2black(o); switch (o->gch.tt) { case LUA_TTABLE: { Table *h = gco2h(o); g->gray = h->gclist; if (traversetable(g, h)) /* table is weak? */ black2gray(o); /* keep it gray */ return sizeof(Table) + sizeof(TValue) * h->sizearray + sizeof(Node) * sizenode(h); } case LUA_TFUNCTION: { Closure *cl = gco2cl(o); g->gray = cl->c.gclist; traverseclosure(g, cl); return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : sizeLclosure(cl->l.nupvalues); } case LUA_TTHREAD: { lua_State *th = gco2th(o); g->gray = th->gclist; th->gclist = g->grayagain; g->grayagain = o; black2gray(o); traversestack(g, th); return sizeof(lua_State) + sizeof(TValue) * th->stacksize + sizeof(CallInfo) * th->size_ci; } case LUA_TPROTO: { Proto *p = gco2p(o); g->gray = p->gclist; traverseproto(g, p); return sizeof(Proto) + sizeof(Instruction) * p->sizecode + sizeof(Proto *) * p->sizep + sizeof(TValue) * p->sizek + sizeof(int) * p->sizelineinfo + sizeof(LocVar) * p->sizelocvars + sizeof(TString *) * p->sizeupvalues; } default: lua_assert(0); return 0; } } static size_t propagateall (global_State *g) { size_t m = 0; while (g->gray) m += propagatemark(g); return m; } /* ** The next function tells whether a key or value can be cleared from ** a weak table. Non-collectable objects are never removed from weak ** tables. Strings behave as `values', so are never removed too. for ** other objects: if really collected, cannot keep them; for userdata ** being finalized, keep them in keys, but not in values */ static int iscleared (const TValue *o, int iskey) { if (!iscollectable(o)) return 0; if (ttisstring(o)) { stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ return 0; } return iswhite(gcvalue(o)) || (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); } /* ** clear collected entries from weaktables */ static void cleartable (GCObject *l) { while (l) { Table *h = gco2h(l); int i = h->sizearray; lua_assert(testbit(h->marked, VALUEWEAKBIT) || testbit(h->marked, KEYWEAKBIT)); if (testbit(h->marked, VALUEWEAKBIT)) { while (i--) { TValue *o = &h->array[i]; if (iscleared(o, 0)) /* value was collected? */ setnilvalue(o); /* remove value */ } } i = sizenode(h); while (i--) { Node *n = gnode(h, i); if (!ttisnil(gval(n)) && /* non-empty entry? */ (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { setnilvalue(gval(n)); /* remove value ... */ removeentry(n); /* remove entry from table */ } } l = h->gclist; } } static void freeobj (lua_State *L, GCObject *o) { switch (o->gch.tt) { case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; case LUA_TTABLE: luaH_free(L, gco2h(o)); break; case LUA_TTHREAD: { lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); luaE_freethread(L, gco2th(o)); break; } case LUA_TSTRING: { G(L)->strt.nuse--; luaM_freemem(L, o, sizestring(gco2ts(o))); break; } case LUA_TUSERDATA: { luaM_freemem(L, o, sizeudata(gco2u(o))); break; } default: lua_assert(0); } } #define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { GCObject *curr; global_State *g = G(L); int deadmask = otherwhite(g); while ((curr = *p) != NULL && count-- > 0) { if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ sweepwholelist(L, &gco2th(curr)->openupval); if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); makewhite(g, curr); /* make it white (for next cycle) */ p = &curr->gch.next; } else { /* must erase `curr' */ lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); *p = curr->gch.next; if (curr == g->rootgc) /* is the first element of the list? */ g->rootgc = curr->gch.next; /* adjust first */ freeobj(L, curr); } } return p; } static void checkSizes (lua_State *L) { global_State *g = G(L); /* check size of string hash */ if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && g->strt.size > MINSTRTABSIZE*2) luaS_resize(L, g->strt.size/2); /* table is too big */ /* check size of buffer */ if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ size_t newsize = luaZ_sizebuffer(&g->buff) / 2; luaZ_resizebuffer(L, &g->buff, newsize); } } static void GCTM (lua_State *L) { global_State *g = G(L); GCObject *o = g->tmudata->gch.next; /* get first element */ Udata *udata = rawgco2u(o); const TValue *tm; /* remove udata from `tmudata' */ if (o == g->tmudata) /* last element? */ g->tmudata = NULL; else g->tmudata->gch.next = udata->uv.next; udata->uv.next = g->mainthread->next; /* return it to `root' list */ g->mainthread->next = o; makewhite(g, o); tm = fasttm(L, udata->uv.metatable, TM_GC); if (tm != NULL) { lu_byte oldah = L->allowhook; lu_mem oldt = g->GCthreshold; L->allowhook = 0; /* stop debug hooks during GC tag method */ g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ setobj2s(L, L->top, tm); setuvalue(L, L->top+1, udata); L->top += 2; luaD_call(L, L->top - 2, 0); L->allowhook = oldah; /* restore hooks */ g->GCthreshold = oldt; /* restore threshold */ } } /* ** Call all GC tag methods */ void luaC_callGCTM (lua_State *L) { while (G(L)->tmudata) GCTM(L); } void luaC_freeall (lua_State *L) { global_State *g = G(L); int i; g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ sweepwholelist(L, &g->rootgc); for (i = 0; i < g->strt.size; i++) /* free all string lists */ sweepwholelist(L, &g->strt.hash[i]); } static void markmt (global_State *g) { int i; for (i=0; imt[i]) markobject(g, g->mt[i]); } /* mark root set */ static void markroot (lua_State *L) { global_State *g = G(L); g->gray = NULL; g->grayagain = NULL; g->weak = NULL; markobject(g, g->mainthread); /* make global table be traversed before main stack */ markvalue(g, gt(g->mainthread)); markvalue(g, registry(L)); markmt(g); g->gcstate = GCSpropagate; } static void remarkupvals (global_State *g) { UpVal *uv; for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); if (isgray(obj2gco(uv))) markvalue(g, uv->v); } } static void atomic (lua_State *L) { global_State *g = G(L); size_t udsize; /* total size of userdata to be finalized */ /* remark occasional upvalues of (maybe) dead threads */ remarkupvals(g); /* traverse objects cautch by write barrier and by 'remarkupvals' */ propagateall(g); /* remark weak tables */ g->gray = g->weak; g->weak = NULL; lua_assert(!iswhite(obj2gco(g->mainthread))); markobject(g, L); /* mark running thread */ markmt(g); /* mark basic metatables (again) */ propagateall(g); /* remark gray again */ g->gray = g->grayagain; g->grayagain = NULL; propagateall(g); udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ marktmu(g); /* mark `preserved' userdata */ udsize += propagateall(g); /* remark, to propagate `preserveness' */ cleartable(g->weak); /* remove collected objects from weak tables */ /* flip current white */ g->currentwhite = cast_byte(otherwhite(g)); g->sweepstrgc = 0; g->sweepgc = &g->rootgc; g->gcstate = GCSsweepstring; g->estimate = g->totalbytes - udsize; /* first estimate */ } static l_mem singlestep (lua_State *L) { global_State *g = G(L); /*lua_checkmemory(L);*/ switch (g->gcstate) { case GCSpause: { markroot(L); /* start a new collection */ return 0; } case GCSpropagate: { if (g->gray) return propagatemark(g); else { /* no more `gray' objects */ atomic(L); /* finish mark phase */ return 0; } } case GCSsweepstring: { lu_mem old = g->totalbytes; sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ g->gcstate = GCSsweep; /* end sweep-string phase */ lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes; return GCSWEEPCOST; } case GCSsweep: { lu_mem old = g->totalbytes; g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); if (*g->sweepgc == NULL) { /* nothing more to sweep? */ checkSizes(L); g->gcstate = GCSfinalize; /* end sweep phase */ } lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes; return GCSWEEPMAX*GCSWEEPCOST; } case GCSfinalize: { if (g->tmudata) { GCTM(L); if (g->estimate > GCFINALIZECOST) g->estimate -= GCFINALIZECOST; return GCFINALIZECOST; } else { g->gcstate = GCSpause; /* end collection */ g->gcdept = 0; return 0; } } default: lua_assert(0); return 0; } } void luaC_step (lua_State *L) { global_State *g = G(L); l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; if (lim == 0) lim = (MAX_LUMEM-1)/2; /* no limit */ g->gcdept += g->totalbytes - g->GCthreshold; do { lim -= singlestep(L); if (g->gcstate == GCSpause) break; } while (lim > 0); if (g->gcstate != GCSpause) { if (g->gcdept < GCSTEPSIZE) g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ else { g->gcdept -= GCSTEPSIZE; g->GCthreshold = g->totalbytes; } } else { lua_assert(g->totalbytes >= g->estimate); setthreshold(g); } } void luaC_fullgc (lua_State *L) { global_State *g = G(L); if (g->gcstate <= GCSpropagate) { /* reset sweep marks to sweep all elements (returning them to white) */ g->sweepstrgc = 0; g->sweepgc = &g->rootgc; /* reset other collector lists */ g->gray = NULL; g->grayagain = NULL; g->weak = NULL; g->gcstate = GCSsweepstring; } lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); /* finish any pending sweep phase */ while (g->gcstate != GCSfinalize) { lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); singlestep(L); } markroot(L); while (g->gcstate != GCSpause) { singlestep(L); } setthreshold(g); } void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { global_State *g = G(L); lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); lua_assert(ttype(&o->gch) != LUA_TTABLE); /* must keep invariant? */ if (g->gcstate == GCSpropagate) reallymarkobject(g, v); /* restore invariant */ else /* don't mind */ makewhite(g, o); /* mark as white just to avoid other barriers */ } void luaC_barrierback (lua_State *L, Table *t) { global_State *g = G(L); GCObject *o = obj2gco(t); lua_assert(isblack(o) && !isdead(g, o)); lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); black2gray(o); /* make table gray (again) */ t->gclist = g->grayagain; g->grayagain = o; } void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { global_State *g = G(L); o->gch.next = g->rootgc; g->rootgc = o; o->gch.marked = luaC_white(g); o->gch.tt = tt; } void luaC_linkupval (lua_State *L, UpVal *uv) { global_State *g = G(L); GCObject *o = obj2gco(uv); o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ g->rootgc = o; if (isgray(o)) { if (g->gcstate == GCSpropagate) { gray2black(o); /* closed upvalues need barrier */ luaC_barrier(L, uv, uv->v); } else { /* sweep phase: sweep it (turning it into white) */ makewhite(g, o); lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); } } } debian/grub-extras/lua/lmem.h0000664000000000000000000000274212524662415013333 0ustar /* ** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ #ifndef lmem_h #define lmem_h #if 0 #include #endif #include "llimits.h" #include "lua.h" #define MEMERRMSG "not enough memory" #define luaM_reallocv(L,b,on,n,e) \ ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ luaM_toobig(L)) #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) #define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) #define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) #define luaM_newvector(L,n,t) \ cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) #define luaM_growvector(L,v,nelems,size,t,limit,e) \ if ((nelems)+1 > (size)) \ ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) #define luaM_reallocvector(L, v,oldn,n,t) \ ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, size_t size); LUAI_FUNC void *luaM_toobig (lua_State *L); LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elem, int limit, const char *errormsg); #endif debian/grub-extras/lua/osdetect.lua0000664000000000000000000001655512524662415014554 0ustar #!lua -- -- Copyright (C) 2009 Free Software Foundation, Inc. -- -- GRUB is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- GRUB is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with GRUB. If not, see . -- function enum_device (device, fs, uuid) local root local title local source local kernels = {} local kernelnames = {} local kernel_num = 0 local function enum_file (name) local version version = string.match (name, "vmlinuz%-(.*)") if (version == nil) then version = string.match (name, "linux%-(.*)") end if (version ~= nil) then table.insert (kernels, version) table.insert (kernelnames, name) kernel_num = kernel_num + 1 end end local function sort_kernel (first, second) local a1, a2, a3, a4, b1, b2, b3, b4 a1, a2, a3, a4 = string.match (first, "(%d+)%.?(%d*).?(%d*)%-?(%d*)") b1, b2, b3, b4 = string.match (second, "(%d+)%.?(%d*).?(%d*)%-?(%d*)") return (a1 > b1) or (a2 > b2) or (a3 > b3) or (a4 < b4); end local function freebsd_variants (title, header, footer) normal = "\nset FreeBSD.acpi_load=YES" .. "\nset FreeBSD.hint.acpi.0.disabled=0" noacpi = "\nunset FreeBSD.acpi_load" .. "\nset FreeBSD.hint.acpi.0.disabled=1" .. "\nset FreeBSD.loader.acpi_disabled_by_user=1" safe = "\nset FreeBSD.hint.apic.0.disabled=1" .. "\nset FreeBSD.hw.ata.ata_dma=0" .. "\nset FreeBSD.hw.ata.atapi_dma=0" .. "\nset FreeBSD.hw.ata.wc=0" .. "\nset FreeBSD.hw.eisa_slots=0" .. "\nset FreeBSD.hint.kbdmux.0.disabled=1" grub.add_menu (header .. normal .. footer, title) grub.add_menu (header .. " --single" .. normal .. footer, title .. " (single)") grub.add_menu (header .. " --verbose" .. normal .. footer, title .. " (verbose)") grub.add_menu (header .. " --verbose" .. noacpi .. footer, title .. " (without ACPI)") grub.add_menu (header .. " --verbose" .. noacpi .. safe .. footer, title .. " (safe mode)") end root = "(" .. device .. ")/" source = "set root=" .. device .. "\nchainloader +1" local drive_num = string.match (device, "hd(%d+)") if (drive_num ~= nil) and (drive_num ~= "0") then source = source .. "\ndrivemap -s hd0 hd" .. drive_num end title = nil if (grub.file_exist (root .. "bootmgr") and grub.file_exist (root .. "boot/bcd")) then title = "Windows Vista bootmgr" source = "set root=" .. device .. "\nchainloader +1" elseif (grub.file_exist (root .. "ntldr") and grub.file_exist (root .. "ntdetect.com") and grub.file_exist (root .. "boot.ini")) then title = "Windows NT/2000/XP loader" elseif (grub.file_exist (root .. "windows/win.com")) then title = "Windows 98/ME" elseif (grub.file_exist (root .. "io.sys") and grub.file_exist (root .. "command.com")) then title = "MS-DOS" elseif (grub.file_exist (root .. "kernel.sys")) then title = "FreeDOS" elseif ((fs == "ufs1" or fs == "ufs2") and grub.file_exist (root .. "boot/kernel/kernel") and grub.file_exist (root .. "boot/device.hints")) then header = "set root=" .. device .. "\nfreebsd /boot/kernel/kernel" footer = "\nset FreeBSD.vfs.root.mountfrom=ufs:ufsid/" .. uuid .. "\nfreebsd_loadenv /boot/device.hints" title = "FreeBSD (on " .. fs .. " ".. device .. ")" freebsd_variants (title, header, footer) return 0 elseif (fs == "zfs" and grub.file_exist (root .. "/@/boot/kernel/kernel") and grub.file_exist (root .. "/@/boot/device.hints")) then header = "set root=" .. device .. "\nfreebsd /@/boot/kernel/kernel" footer = "\nfreebsd_module_elf /@/boot/kernel/opensolaris.ko" .. "\nfreebsd_module_elf /@/boot/kernel/zfs.ko" .. "\nfreebsd_module /@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache" .. "\nprobe -l -s name $root" .. "\nset FreeBSD.vfs.root.mountfrom=zfs:$name" .. "\nfreebsd_loadenv /@/boot/device.hints" title = "FreeBSD (on " .. fs .. " ".. device .. ")" freebsd_variants (title, header, footer) return 0 elseif (fs == "hfsplus" and grub.file_exist (root .. "mach_kernel")) then source = "set root=" .. device .. "\ninsmod vbe" .. "\ndo_resume=0" .. "\nif [ /var/vm/sleepimage -nt10 / ]; then" .. "\n if xnu_resume /var/vm/sleepimage; then" .. "\n do_resume=1" .. "\n fi" .. "\nfi" .. "\nif [ $do_resume == 0 ]; then" .. "\n xnu_uuid " .. uuid .. " uuid" .. "\n if [ -f /Extra/DSDT.aml ]; then" .. "\n acpi -e /Extra/DSDT.aml" .. "\n fi" .. "\n xnu_kernel /mach_kernel boot-uuid=${uuid} rd=*uuid" .. "\n if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then" .. "\n xnu_mkext /System/Library/Extensions.mkext" .. "\n else" .. "\n xnu_kextdir /System/Library/Extensions" .. "\n fi" .. "\n if [ -f /Extra/Extensions.mkext ]; then" .. "\n xnu_mkext /Extra/Extensions.mkext" .. "\n fi" .. "\n if [ -d /Extra/Extensions ]; then" .. "\n xnu_kextdir /Extra/Extensions" .. "\n fi" .. "\n if [ -f /Extra/devtree.txt ]; then" .. "\n xnu_devtree /Extra/devtree.txt" .. "\n fi" .. "\n if [ -f /Extra/splash.jpg ]; then" .. "\n insmod jpeg" .. "\n xnu_splash /Extra/splash.jpg" .. "\n fi" .. "\n if [ -f /Extra/splash.png ]; then" .. "\n insmod png" .. "\n xnu_splash /Extra/splash.png" .. "\n fi" .. "\n if [ -f /Extra/splash.tga ]; then" .. "\n insmod tga" .. "\n xnu_splash /Extra/splash.tga" .. "\n fi" .. "\nfi" title = "Mac OS X/Darwin" else grub.enum_file (enum_file, root .. "boot") if kernel_num ~= 0 then table.sort (kernels, sort_kernel) table.sort (kernelnames, sort_kernel) for i = 1, kernel_num do local initrd title = "Linux " .. kernels[i] source = "set root=" .. device .. "\nlinux /boot/" .. kernelnames[i] .. " root=UUID=" .. uuid .. " ro" if grub.file_exist (root .. "boot/initrd-" .. kernels[i] .. ".img") then initrd = "\ninitrd /boot/initrd-" .. kernels[i] .. ".img" elseif grub.file_exist (root .. "boot/initrd.img-" .. kernels[i]) then initrd = "\ninitrd /boot/initrd.img-" .. kernels[i] elseif grub.file_exist (root .. "boot/initrd-" .. kernels[i]) then initrd = "\ninitrd /boot/initrd-" .. kernels[i] else initrd = "" end grub.add_menu (source .. initrd, title) grub.add_menu (source .. " single" .. initrd, title .. " (single-user mode)") end return 0 end end if title == nil then local partition = string.match (device, ".*,(%d+)") if (partition ~= nil) and (tonumber (partition) > 4) then return 0 end title = "Other OS" end grub.add_menu (source, title) return 0 end grub.enum_device (enum_device) debian/grub-extras/lua/ltable.c0000664000000000000000000003770112524662415013642 0ustar /* ** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ /* ** Implementation of tables (aka arrays, objects, or hash tables). ** Tables keep its elements in two parts: an array part and a hash part. ** Non-negative integer keys are all candidates to be kept in the array ** part. The actual size of the array is the largest `n' such that at ** least half the slots between 0 and n are in use. ** Hash uses a mix of chained scatter table with Brent's variation. ** A main invariant of these tables is that, if an element is not ** in its main position (i.e. the `original' position that its hash gives ** to it), then the colliding element is in its own main position. ** Hence even when the load factor reaches 100%, performance remains good. */ #if 0 #include #include #endif #define ltable_c #define LUA_CORE #include "lua.h" #include "ldebug.h" #include "ldo.h" #include "lgc.h" #include "lmem.h" #include "lobject.h" #include "lstate.h" #include "ltable.h" /* ** max size of array part is 2^MAXBITS */ #if LUAI_BITSINT > 26 #define MAXBITS 26 #else #define MAXBITS (LUAI_BITSINT-2) #endif #define MAXASIZE (1 << MAXBITS) #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) #define hashstr(t,str) hashpow2(t, (str)->tsv.hash) #define hashboolean(t,p) hashpow2(t, p) /* ** for some types, it is better to avoid modulus by power of 2, as ** they tend to have many 2 factors. */ #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) #define hashpointer(t,p) hashmod(t, IntPoint(p)) /* ** number of ints inside a lua_Number */ #define numints cast_int(sizeof(lua_Number)/sizeof(int)) #define dummynode (&dummynode_) static const Node dummynode_ = { {{NULL}, LUA_TNIL}, /* value */ {{{NULL}, LUA_TNIL, NULL}} /* key */ }; /* ** hash for lua_Numbers */ static Node *hashnum (const Table *t, lua_Number n) { unsigned int a[numints]; int i; if (luai_numeq(n, 0)) /* avoid problems with -0 */ return gnode(t, 0); memcpy(a, &n, sizeof(a)); for (i = 1; i < numints; i++) a[0] += a[i]; return hashmod(t, a[0]); } /* ** returns the `main' position of an element in a table (that is, the index ** of its hash value) */ static Node *mainposition (const Table *t, const TValue *key) { switch (ttype(key)) { case LUA_TNUMBER: return hashnum(t, nvalue(key)); case LUA_TSTRING: return hashstr(t, rawtsvalue(key)); case LUA_TBOOLEAN: return hashboolean(t, bvalue(key)); case LUA_TLIGHTUSERDATA: return hashpointer(t, pvalue(key)); default: return hashpointer(t, gcvalue(key)); } } /* ** returns the index for `key' if `key' is an appropriate key to live in ** the array part of the table, -1 otherwise. */ static int arrayindex (const TValue *key) { if (ttisnumber(key)) { lua_Number n = nvalue(key); int k; lua_number2int(k, n); if (luai_numeq(cast_num(k), n)) return k; } return -1; /* `key' did not match some condition */ } /* ** returns the index of a `key' for table traversals. First goes all ** elements in the array part, then elements in the hash part. The ** beginning of a traversal is signalled by -1. */ static int findindex (lua_State *L, Table *t, StkId key) { int i; if (ttisnil(key)) return -1; /* first iteration */ i = arrayindex(key); if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ return i-1; /* yes; that's the index (corrected to C) */ else { Node *n = mainposition(t, key); do { /* check whether `key' is somewhere in the chain */ /* key may be dead already, but it is ok to use it in `next' */ if (luaO_rawequalObj(key2tval(n), key) || (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && gcvalue(gkey(n)) == gcvalue(key))) { i = cast_int(n - gnode(t, 0)); /* key index in hash table */ /* hash elements are numbered after array ones */ return i + t->sizearray; } else n = gnext(n); } while (n); luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ return 0; /* to avoid warnings */ } } int luaH_next (lua_State *L, Table *t, StkId key) { int i = findindex(L, t, key); /* find original element */ for (i++; i < t->sizearray; i++) { /* try first array part */ if (!ttisnil(&t->array[i])) { /* a non-nil value? */ setnvalue(key, cast_num(i+1)); setobj2s(L, key+1, &t->array[i]); return 1; } } for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ setobj2s(L, key, key2tval(gnode(t, i))); setobj2s(L, key+1, gval(gnode(t, i))); return 1; } } return 0; /* no more elements */ } /* ** {============================================================= ** Rehash ** ============================================================== */ static int computesizes (int nums[], int *narray) { int i; int twotoi; /* 2^i */ int a = 0; /* number of elements smaller than 2^i */ int na = 0; /* number of elements to go to array part */ int n = 0; /* optimal size for array part */ for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { if (nums[i] > 0) { a += nums[i]; if (a > twotoi/2) { /* more than half elements present? */ n = twotoi; /* optimal size (till now) */ na = a; /* all elements smaller than n will go to array part */ } } if (a == *narray) break; /* all elements already counted */ } *narray = n; lua_assert(*narray/2 <= na && na <= *narray); return na; } static int countint (const TValue *key, int *nums) { int k = arrayindex(key); if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ nums[ceillog2(k)]++; /* count as such */ return 1; } else return 0; } static int numusearray (const Table *t, int *nums) { int lg; int ttlg; /* 2^lg */ int ause = 0; /* summation of `nums' */ int i = 1; /* count to traverse all array keys */ for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ int lc = 0; /* counter */ int lim = ttlg; if (lim > t->sizearray) { lim = t->sizearray; /* adjust upper limit */ if (i > lim) break; /* no more elements to count */ } /* count elements in range (2^(lg-1), 2^lg] */ for (; i <= lim; i++) { if (!ttisnil(&t->array[i-1])) lc++; } nums[lg] += lc; ause += lc; } return ause; } static int numusehash (const Table *t, int *nums, int *pnasize) { int totaluse = 0; /* total number of elements */ int ause = 0; /* summation of `nums' */ int i = sizenode(t); while (i--) { Node *n = &t->node[i]; if (!ttisnil(gval(n))) { ause += countint(key2tval(n), nums); totaluse++; } } *pnasize += ause; return totaluse; } static void setarrayvector (lua_State *L, Table *t, int size) { int i; luaM_reallocvector(L, t->array, t->sizearray, size, TValue); for (i=t->sizearray; iarray[i]); t->sizearray = size; } static void setnodevector (lua_State *L, Table *t, int size) { int lsize; if (size == 0) { /* no elements to hash part? */ t->node = cast(Node *, dummynode); /* use common `dummynode' */ lsize = 0; } else { int i; lsize = ceillog2(size); if (lsize > MAXBITS) luaG_runerror(L, "table overflow"); size = twoto(lsize); t->node = luaM_newvector(L, size, Node); for (i=0; ilsizenode = cast_byte(lsize); t->lastfree = gnode(t, size); /* all positions are free */ } static void resize (lua_State *L, Table *t, int nasize, int nhsize) { int i; int oldasize = t->sizearray; int oldhsize = t->lsizenode; Node *nold = t->node; /* save old hash ... */ if (nasize > oldasize) /* array part must grow? */ setarrayvector(L, t, nasize); /* create new hash part with appropriate size */ setnodevector(L, t, nhsize); if (nasize < oldasize) { /* array part must shrink? */ t->sizearray = nasize; /* re-insert elements from vanishing slice */ for (i=nasize; iarray[i])) setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); } /* shrink array */ luaM_reallocvector(L, t->array, oldasize, nasize, TValue); } /* re-insert elements from hash part */ for (i = twoto(oldhsize) - 1; i >= 0; i--) { Node *old = nold+i; if (!ttisnil(gval(old))) setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old)); } if (nold != dummynode) luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ } void luaH_resizearray (lua_State *L, Table *t, int nasize) { int nsize = (t->node == dummynode) ? 0 : sizenode(t); resize(L, t, nasize, nsize); } static void rehash (lua_State *L, Table *t, const TValue *ek) { int nasize, na; int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ int i; int totaluse; for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ nasize = numusearray(t, nums); /* count keys in array part */ totaluse = nasize; /* all those keys are integer keys */ totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ /* count extra key */ nasize += countint(ek, nums); totaluse++; /* compute new size for array part */ na = computesizes(nums, &nasize); /* resize the table to new computed sizes */ resize(L, t, nasize, totaluse - na); } /* ** }============================================================= */ Table *luaH_new (lua_State *L, int narray, int nhash) { Table *t = luaM_new(L, Table); luaC_link(L, obj2gco(t), LUA_TTABLE); t->metatable = NULL; t->flags = cast_byte(~0); /* temporary values (kept only if some malloc fails) */ t->array = NULL; t->sizearray = 0; t->lsizenode = 0; t->node = cast(Node *, dummynode); setarrayvector(L, t, narray); setnodevector(L, t, nhash); return t; } void luaH_free (lua_State *L, Table *t) { if (t->node != dummynode) luaM_freearray(L, t->node, sizenode(t), Node); luaM_freearray(L, t->array, t->sizearray, TValue); luaM_free(L, t); } static Node *getfreepos (Table *t) { while (t->lastfree-- > t->node) { if (ttisnil(gkey(t->lastfree))) return t->lastfree; } return NULL; /* could not find a free place */ } /* ** inserts a new key into a hash table; first, check whether key's main ** position is free. If not, check whether colliding node is in its main ** position or not: if it is not, move colliding node to an empty place and ** put new key in its main position; otherwise (colliding node is in its main ** position), new key goes to an empty position. */ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { Node *mp = mainposition(t, key); if (!ttisnil(gval(mp)) || mp == dummynode) { Node *othern; Node *n = getfreepos(t); /* get a free place */ if (n == NULL) { /* cannot find a free place? */ rehash(L, t, key); /* grow table */ return luaH_set(L, t, key); /* re-insert key into grown table */ } lua_assert(n != dummynode); othern = mainposition(t, key2tval(mp)); if (othern != mp) { /* is colliding node out of its main position? */ /* yes; move colliding node into free position */ while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ #if 0 *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ #else memcpy (n, mp, sizeof (*n)); #endif gnext(mp) = NULL; /* now `mp' is free */ setnilvalue(gval(mp)); } else { /* colliding node is in its own main position */ /* new node will go into free position */ gnext(n) = gnext(mp); /* chain new position */ gnext(mp) = n; mp = n; } } gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; luaC_barriert(L, t, key); lua_assert(ttisnil(gval(mp))); return gval(mp); } /* ** search function for integers */ const TValue *luaH_getnum (Table *t, int key) { /* (1 <= key && key <= t->sizearray) */ if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) return &t->array[key-1]; else { lua_Number nk = cast_num(key); Node *n = hashnum(t, nk); do { /* check whether `key' is somewhere in the chain */ if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) return gval(n); /* that's it */ else n = gnext(n); } while (n); return luaO_nilobject; } } /* ** search function for strings */ const TValue *luaH_getstr (Table *t, TString *key) { Node *n = hashstr(t, key); do { /* check whether `key' is somewhere in the chain */ if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) return gval(n); /* that's it */ else n = gnext(n); } while (n); return luaO_nilobject; } /* ** main search function */ const TValue *luaH_get (Table *t, const TValue *key) { switch (ttype(key)) { case LUA_TNIL: return luaO_nilobject; case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); case LUA_TNUMBER: { int k; lua_Number n = nvalue(key); lua_number2int(k, n); if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ return luaH_getnum(t, k); /* use specialized version */ /* else go through */ } default: { Node *n = mainposition(t, key); do { /* check whether `key' is somewhere in the chain */ if (luaO_rawequalObj(key2tval(n), key)) return gval(n); /* that's it */ else n = gnext(n); } while (n); return luaO_nilobject; } } } TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { const TValue *p = luaH_get(t, key); t->flags = 0; if (p != luaO_nilobject) return cast(TValue *, p); else { if (ttisnil(key)) luaG_runerror(L, "table index is nil"); else if (ttisnumber(key) && luai_numisnan(nvalue(key))) luaG_runerror(L, "table index is NaN"); return newkey(L, t, key); } } TValue *luaH_setnum (lua_State *L, Table *t, int key) { const TValue *p = luaH_getnum(t, key); if (p != luaO_nilobject) return cast(TValue *, p); else { TValue k; setnvalue(&k, cast_num(key)); return newkey(L, t, &k); } } TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { const TValue *p = luaH_getstr(t, key); if (p != luaO_nilobject) return cast(TValue *, p); else { TValue k; setsvalue(L, &k, key); return newkey(L, t, &k); } } static int unbound_search (Table *t, unsigned int j) { unsigned int i = j; /* i is zero or a present index */ j++; /* find `i' and `j' such that i is present and j is not */ while (!ttisnil(luaH_getnum(t, j))) { i = j; j *= 2; if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ /* table was built with bad purposes: resort to linear search */ i = 1; while (!ttisnil(luaH_getnum(t, i))) i++; return i - 1; } } /* now do a binary search between them */ while (j - i > 1) { unsigned int m = (i+j)/2; if (ttisnil(luaH_getnum(t, m))) j = m; else i = m; } return i; } /* ** Try to find a boundary in table `t'. A `boundary' is an integer index ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). */ int luaH_getn (Table *t) { unsigned int j = t->sizearray; if (j > 0 && ttisnil(&t->array[j - 1])) { /* there is a boundary in the array part: (binary) search for it */ unsigned int i = 0; while (j - i > 1) { unsigned int m = (i+j)/2; if (ttisnil(&t->array[m - 1])) j = m; else i = m; } return i; } /* else must find a boundary in hash part */ else if (t->node == dummynode) /* hash part is empty? */ return j; /* that is easy... */ else return unbound_search(t, j); } #if defined(LUA_DEBUG) Node *luaH_mainposition (const Table *t, const TValue *key) { return mainposition(t, key); } int luaH_isdummy (Node *n) { return n == dummynode; } #endif debian/grub-extras/lua/liolib.c0000664000000000000000000003213612524662415013646 0ustar /* ** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ #include #include #include #include #define liolib_c #define LUA_LIB #include "lua.h" #include "lauxlib.h" #include "lualib.h" #define IO_INPUT 1 #define IO_OUTPUT 2 static const char *const fnames[] = {"input", "output"}; static int pushresult (lua_State *L, int i, const char *filename) { int en = errno; /* calls to Lua API may change this value */ if (i) { lua_pushboolean(L, 1); return 1; } else { lua_pushnil(L); if (filename) lua_pushfstring(L, "%s: %s", filename, strerror(en)); else lua_pushfstring(L, "%s", strerror(en)); lua_pushinteger(L, en); return 3; } } static void fileerror (lua_State *L, int arg, const char *filename) { lua_pushfstring(L, "%s: %s", filename, strerror(errno)); luaL_argerror(L, arg, lua_tostring(L, -1)); } #define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) static int io_type (lua_State *L) { void *ud; luaL_checkany(L, 1); ud = lua_touserdata(L, 1); lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) lua_pushnil(L); /* not a file */ else if (*((FILE **)ud) == NULL) lua_pushliteral(L, "closed file"); else lua_pushliteral(L, "file"); return 1; } static FILE *tofile (lua_State *L) { FILE **f = tofilep(L); if (*f == NULL) luaL_error(L, "attempt to use a closed file"); return *f; } /* ** When creating file handles, always creates a `closed' file handle ** before opening the actual file; so, if there is a memory error, the ** file is not left opened. */ static FILE **newfile (lua_State *L) { FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); *pf = NULL; /* file handle is currently `closed' */ luaL_getmetatable(L, LUA_FILEHANDLE); lua_setmetatable(L, -2); return pf; } /* ** function to (not) close the standard files stdin, stdout, and stderr */ static int io_noclose (lua_State *L) { lua_pushnil(L); lua_pushliteral(L, "cannot close standard file"); return 2; } /* ** function to close 'popen' files */ static int io_pclose (lua_State *L) { FILE **p = tofilep(L); int ok = lua_pclose(L, *p); *p = NULL; return pushresult(L, ok, NULL); } /* ** function to close regular files */ static int io_fclose (lua_State *L) { FILE **p = tofilep(L); int ok = (fclose(*p) == 0); *p = NULL; return pushresult(L, ok, NULL); } static int aux_close (lua_State *L) { lua_getfenv(L, 1); lua_getfield(L, -1, "__close"); return (lua_tocfunction(L, -1))(L); } static int io_close (lua_State *L) { if (lua_isnone(L, 1)) lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); tofile(L); /* make sure argument is a file */ return aux_close(L); } static int io_gc (lua_State *L) { FILE *f = *tofilep(L); /* ignore closed files */ if (f != NULL) aux_close(L); return 0; } static int io_tostring (lua_State *L) { FILE *f = *tofilep(L); if (f == NULL) lua_pushliteral(L, "file (closed)"); else lua_pushfstring(L, "file (%p)", f); return 1; } static int io_open (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); FILE **pf = newfile(L); *pf = fopen(filename, mode); return (*pf == NULL) ? pushresult(L, 0, filename) : 1; } /* ** this function has a separated environment, which defines the ** correct __close for 'popen' files */ static int io_popen (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); FILE **pf = newfile(L); *pf = lua_popen(L, filename, mode); return (*pf == NULL) ? pushresult(L, 0, filename) : 1; } static int io_tmpfile (lua_State *L) { FILE **pf = newfile(L); *pf = tmpfile(); return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; } static FILE *getiofile (lua_State *L, int findex) { FILE *f; lua_rawgeti(L, LUA_ENVIRONINDEX, findex); f = *(FILE **)lua_touserdata(L, -1); if (f == NULL) luaL_error(L, "standard %s file is closed", fnames[findex - 1]); return f; } static int g_iofile (lua_State *L, int f, const char *mode) { if (!lua_isnoneornil(L, 1)) { const char *filename = lua_tostring(L, 1); if (filename) { FILE **pf = newfile(L); *pf = fopen(filename, mode); if (*pf == NULL) fileerror(L, 1, filename); } else { tofile(L); /* check that it's a valid file handle */ lua_pushvalue(L, 1); } lua_rawseti(L, LUA_ENVIRONINDEX, f); } /* return current value */ lua_rawgeti(L, LUA_ENVIRONINDEX, f); return 1; } static int io_input (lua_State *L) { return g_iofile(L, IO_INPUT, "r"); } static int io_output (lua_State *L) { return g_iofile(L, IO_OUTPUT, "w"); } static int io_readline (lua_State *L); static void aux_lines (lua_State *L, int idx, int toclose) { lua_pushvalue(L, idx); lua_pushboolean(L, toclose); /* close/not close file when finished */ lua_pushcclosure(L, io_readline, 2); } static int f_lines (lua_State *L) { tofile(L); /* check that it's a valid file handle */ aux_lines(L, 1, 0); return 1; } static int io_lines (lua_State *L) { if (lua_isnoneornil(L, 1)) { /* no arguments? */ /* will iterate over default input */ lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); return f_lines(L); } else { const char *filename = luaL_checkstring(L, 1); FILE **pf = newfile(L); *pf = fopen(filename, "r"); if (*pf == NULL) fileerror(L, 1, filename); aux_lines(L, lua_gettop(L), 1); return 1; } } /* ** {====================================================== ** READ ** ======================================================= */ static int read_number (lua_State *L, FILE *f) { lua_Number d; if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { lua_pushnumber(L, d); return 1; } else return 0; /* read fails */ } static int test_eof (lua_State *L, FILE *f) { int c = getc(f); ungetc(c, f); lua_pushlstring(L, NULL, 0); return (c != EOF); } static int read_line (lua_State *L, FILE *f) { luaL_Buffer b; luaL_buffinit(L, &b); for (;;) { size_t l; char *p = luaL_prepbuffer(&b); if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ luaL_pushresult(&b); /* close buffer */ return (lua_objlen(L, -1) > 0); /* check whether read something */ } l = strlen(p); if (l == 0 || p[l-1] != '\n') luaL_addsize(&b, l); else { luaL_addsize(&b, l - 1); /* do not include `eol' */ luaL_pushresult(&b); /* close buffer */ return 1; /* read at least an `eol' */ } } } static int read_chars (lua_State *L, FILE *f, size_t n) { size_t rlen; /* how much to read */ size_t nr; /* number of chars actually read */ luaL_Buffer b; luaL_buffinit(L, &b); rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ do { char *p = luaL_prepbuffer(&b); if (rlen > n) rlen = n; /* cannot read more than asked */ nr = fread(p, sizeof(char), rlen, f); luaL_addsize(&b, nr); n -= nr; /* still have to read `n' chars */ } while (n > 0 && nr == rlen); /* until end of count or eof */ luaL_pushresult(&b); /* close buffer */ return (n == 0 || lua_objlen(L, -1) > 0); } static int g_read (lua_State *L, FILE *f, int first) { int nargs = lua_gettop(L) - 1; int success; int n; clearerr(f); if (nargs == 0) { /* no arguments? */ success = read_line(L, f); n = first+1; /* to return 1 result */ } else { /* ensure stack space for all results and for auxlib's buffer */ luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); success = 1; for (n = first; nargs-- && success; n++) { if (lua_type(L, n) == LUA_TNUMBER) { size_t l = (size_t)lua_tointeger(L, n); success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); } else { const char *p = lua_tostring(L, n); luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); switch (p[1]) { case 'n': /* number */ success = read_number(L, f); break; case 'l': /* line */ success = read_line(L, f); break; case 'a': /* file */ read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ success = 1; /* always success */ break; default: return luaL_argerror(L, n, "invalid format"); } } } } if (ferror(f)) return pushresult(L, 0, NULL); if (!success) { lua_pop(L, 1); /* remove last result */ lua_pushnil(L); /* push nil instead */ } return n - first; } static int io_read (lua_State *L) { return g_read(L, getiofile(L, IO_INPUT), 1); } static int f_read (lua_State *L) { return g_read(L, tofile(L), 2); } static int io_readline (lua_State *L) { FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); int sucess; if (f == NULL) /* file is already closed? */ luaL_error(L, "file is already closed"); sucess = read_line(L, f); if (ferror(f)) return luaL_error(L, "%s", strerror(errno)); if (sucess) return 1; else { /* EOF */ if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ lua_settop(L, 0); lua_pushvalue(L, lua_upvalueindex(1)); aux_close(L); /* close it */ } return 0; } } /* }====================================================== */ static int g_write (lua_State *L, FILE *f, int arg) { int nargs = lua_gettop(L) - 1; int status = 1; for (; nargs--; arg++) { if (lua_type(L, arg) == LUA_TNUMBER) { /* optimization: could be done exactly as for strings */ status = status && fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; } else { size_t l; const char *s = luaL_checklstring(L, arg, &l); status = status && (fwrite(s, sizeof(char), l, f) == l); } } return pushresult(L, status, NULL); } static int io_write (lua_State *L) { return g_write(L, getiofile(L, IO_OUTPUT), 1); } static int f_write (lua_State *L) { return g_write(L, tofile(L), 2); } static int f_seek (lua_State *L) { static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; static const char *const modenames[] = {"set", "cur", "end", NULL}; FILE *f = tofile(L); int op = luaL_checkoption(L, 2, "cur", modenames); long offset = luaL_optlong(L, 3, 0); op = fseek(f, offset, mode[op]); if (op) return pushresult(L, 0, NULL); /* error */ else { lua_pushinteger(L, ftell(f)); return 1; } } static int f_setvbuf (lua_State *L) { static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; static const char *const modenames[] = {"no", "full", "line", NULL}; FILE *f = tofile(L); int op = luaL_checkoption(L, 2, NULL, modenames); lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); int res = setvbuf(f, NULL, mode[op], sz); return pushresult(L, res == 0, NULL); } static int io_flush (lua_State *L) { return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); } static int f_flush (lua_State *L) { return pushresult(L, fflush(tofile(L)) == 0, NULL); } static const luaL_Reg iolib[] = { {"close", io_close}, {"flush", io_flush}, {"input", io_input}, {"lines", io_lines}, {"open", io_open}, {"output", io_output}, {"popen", io_popen}, {"read", io_read}, {"tmpfile", io_tmpfile}, {"type", io_type}, {"write", io_write}, {NULL, NULL} }; static const luaL_Reg flib[] = { {"close", io_close}, {"flush", f_flush}, {"lines", f_lines}, {"read", f_read}, {"seek", f_seek}, {"setvbuf", f_setvbuf}, {"write", f_write}, {"__gc", io_gc}, {"__tostring", io_tostring}, {NULL, NULL} }; static void createmeta (lua_State *L) { luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ lua_pushvalue(L, -1); /* push metatable */ lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ luaL_register(L, NULL, flib); /* file methods */ } static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { *newfile(L) = f; if (k > 0) { lua_pushvalue(L, -1); lua_rawseti(L, LUA_ENVIRONINDEX, k); } lua_pushvalue(L, -2); /* copy environment */ lua_setfenv(L, -2); /* set it */ lua_setfield(L, -3, fname); } static void newfenv (lua_State *L, lua_CFunction cls) { lua_createtable(L, 0, 1); lua_pushcfunction(L, cls); lua_setfield(L, -2, "__close"); } LUALIB_API int luaopen_io (lua_State *L) { createmeta(L); /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ newfenv(L, io_fclose); lua_replace(L, LUA_ENVIRONINDEX); /* open library */ luaL_register(L, LUA_IOLIBNAME, iolib); /* create (and set) default files */ newfenv(L, io_noclose); /* close function for default files */ createstdfile(L, stdin, IO_INPUT, "stdin"); createstdfile(L, stdout, IO_OUTPUT, "stdout"); createstdfile(L, stderr, 0, "stderr"); lua_pop(L, 1); /* pop environment for default files */ lua_getfield(L, -1, "popen"); newfenv(L, io_pclose); /* create environment for 'popen' */ lua_setfenv(L, -2); /* set fenv for 'popen' */ lua_pop(L, 1); /* pop 'popen' */ return 1; } debian/grub-extras/lua/ldo.h0000664000000000000000000000357312524662415013162 0ustar /* ** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ #ifndef ldo_h #define ldo_h #include "lobject.h" #include "lstate.h" #include "lzio.h" #define luaD_checkstack(L,n) \ if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ luaD_growstack(L, n); \ else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); #define incr_top(L) {luaD_checkstack(L,1); L->top++;} #define savestack(L,p) ((TValue *)(p) - (TValue *)L->stack) #define restorestack(L,n) ((TValue *)((TValue *)L->stack + (n))) #define saveci(L,p) ((CallInfo *)(p) - (CallInfo *)L->base_ci) #define restoreci(L,n) ((CallInfo *)((CallInfo *)L->base_ci + (n))) /* results from luaD_precall */ #define PCRLUA 0 /* initiated a call to a Lua function */ #define PCRC 1 /* did a call to a C function */ #define PCRYIELD 2 /* C funtion yielded */ /* type of protected functions, to be ran by `runprotected' */ typedef void (*Pfunc) (lua_State *L, void *ud); LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, ptrdiff_t oldtop, ptrdiff_t ef); LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); LUAI_FUNC void luaD_growstack (lua_State *L, int n); LUAI_FUNC void luaD_throw (lua_State *L, int errcode); LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); #endif debian/grub-extras/lua/loslib.c0000664000000000000000000001355012524662415013657 0ustar /* ** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ ** Standard Operating System library ** See Copyright Notice in lua.h */ #include #include #include #include #include #define loslib_c #define LUA_LIB #include "lua.h" #include "lauxlib.h" #include "lualib.h" static int os_pushresult (lua_State *L, int i, const char *filename) { int en = errno; /* calls to Lua API may change this value */ if (i) { lua_pushboolean(L, 1); return 1; } else { lua_pushnil(L); lua_pushfstring(L, "%s: %s", filename, strerror(en)); lua_pushinteger(L, en); return 3; } } static int os_execute (lua_State *L) { lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); return 1; } static int os_remove (lua_State *L) { const char *filename = luaL_checkstring(L, 1); return os_pushresult(L, remove(filename) == 0, filename); } static int os_rename (lua_State *L) { const char *fromname = luaL_checkstring(L, 1); const char *toname = luaL_checkstring(L, 2); return os_pushresult(L, rename(fromname, toname) == 0, fromname); } static int os_tmpname (lua_State *L) { char buff[LUA_TMPNAMBUFSIZE]; int err; lua_tmpnam(buff, err); if (err) return luaL_error(L, "unable to generate a unique filename"); lua_pushstring(L, buff); return 1; } static int os_getenv (lua_State *L) { lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ return 1; } static int os_clock (lua_State *L) { lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); return 1; } /* ** {====================================================== ** Time/Date operations ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, ** wday=%w+1, yday=%j, isdst=? } ** ======================================================= */ static void setfield (lua_State *L, const char *key, int value) { lua_pushinteger(L, value); lua_setfield(L, -2, key); } static void setboolfield (lua_State *L, const char *key, int value) { if (value < 0) /* undefined? */ return; /* does not set field */ lua_pushboolean(L, value); lua_setfield(L, -2, key); } static int getboolfield (lua_State *L, const char *key) { int res; lua_getfield(L, -1, key); res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); lua_pop(L, 1); return res; } static int getfield (lua_State *L, const char *key, int d) { int res; lua_getfield(L, -1, key); if (lua_isnumber(L, -1)) res = (int)lua_tointeger(L, -1); else { if (d < 0) return luaL_error(L, "field " LUA_QS " missing in date table", key); res = d; } lua_pop(L, 1); return res; } static int os_date (lua_State *L) { const char *s = luaL_optstring(L, 1, "%c"); time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); struct tm *stm; if (*s == '!') { /* UTC? */ stm = gmtime(&t); s++; /* skip `!' */ } else stm = localtime(&t); if (stm == NULL) /* invalid date? */ lua_pushnil(L); else if (strcmp(s, "*t") == 0) { lua_createtable(L, 0, 9); /* 9 = number of fields */ setfield(L, "sec", stm->tm_sec); setfield(L, "min", stm->tm_min); setfield(L, "hour", stm->tm_hour); setfield(L, "day", stm->tm_mday); setfield(L, "month", stm->tm_mon+1); setfield(L, "year", stm->tm_year+1900); setfield(L, "wday", stm->tm_wday+1); setfield(L, "yday", stm->tm_yday+1); setboolfield(L, "isdst", stm->tm_isdst); } else { char cc[3]; luaL_Buffer b; cc[0] = '%'; cc[2] = '\0'; luaL_buffinit(L, &b); for (; *s; s++) { if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ luaL_addchar(&b, *s); else { size_t reslen; char buff[200]; /* should be big enough for any conversion result */ cc[1] = *(++s); reslen = strftime(buff, sizeof(buff), cc, stm); luaL_addlstring(&b, buff, reslen); } } luaL_pushresult(&b); } return 1; } static int os_time (lua_State *L) { time_t t; if (lua_isnoneornil(L, 1)) /* called without args? */ t = time(NULL); /* get current time */ else { struct tm ts; luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 1); /* make sure table is at the top */ ts.tm_sec = getfield(L, "sec", 0); ts.tm_min = getfield(L, "min", 0); ts.tm_hour = getfield(L, "hour", 12); ts.tm_mday = getfield(L, "day", -1); ts.tm_mon = getfield(L, "month", -1) - 1; ts.tm_year = getfield(L, "year", -1) - 1900; ts.tm_isdst = getboolfield(L, "isdst"); t = mktime(&ts); } if (t == (time_t)(-1)) lua_pushnil(L); else lua_pushnumber(L, (lua_Number)t); return 1; } static int os_difftime (lua_State *L) { lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), (time_t)(luaL_optnumber(L, 2, 0)))); return 1; } /* }====================================================== */ static int os_setlocale (lua_State *L) { static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME}; static const char *const catnames[] = {"all", "collate", "ctype", "monetary", "numeric", "time", NULL}; const char *l = luaL_optstring(L, 1, NULL); int op = luaL_checkoption(L, 2, "all", catnames); lua_pushstring(L, setlocale(cat[op], l)); return 1; } static int os_exit (lua_State *L) { exit(luaL_optint(L, 1, EXIT_SUCCESS)); } static const luaL_Reg syslib[] = { {"clock", os_clock}, {"date", os_date}, {"difftime", os_difftime}, {"execute", os_execute}, {"exit", os_exit}, {"getenv", os_getenv}, {"remove", os_remove}, {"rename", os_rename}, {"setlocale", os_setlocale}, {"time", os_time}, {"tmpname", os_tmpname}, {NULL, NULL} }; /* }====================================================== */ LUALIB_API int luaopen_os (lua_State *L) { luaL_register(L, LUA_OSLIBNAME, syslib); return 1; } debian/grub-extras/lua/ldump.c0000664000000000000000000000605212524662415013513 0ustar /* ** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ ** save precompiled Lua chunks ** See Copyright Notice in lua.h */ #include #define ldump_c #define LUA_CORE #include "lua.h" #include "lobject.h" #include "lstate.h" #include "lundump.h" typedef struct { lua_State* L; lua_Writer writer; void* data; int strip; int status; } DumpState; #define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) #define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) static void DumpBlock(const void* b, size_t size, DumpState* D) { if (D->status==0) { lua_unlock(D->L); D->status=(*D->writer)(D->L,b,size,D->data); lua_lock(D->L); } } static void DumpChar(int y, DumpState* D) { char x=(char)y; DumpVar(x,D); } static void DumpInt(int x, DumpState* D) { DumpVar(x,D); } static void DumpNumber(lua_Number x, DumpState* D) { DumpVar(x,D); } static void DumpVector(const void* b, int n, size_t size, DumpState* D) { DumpInt(n,D); DumpMem(b,n,size,D); } static void DumpString(const TString* s, DumpState* D) { if (s==NULL || getstr(s)==NULL) { size_t size=0; DumpVar(size,D); } else { size_t size=s->tsv.len+1; /* include trailing '\0' */ DumpVar(size,D); DumpBlock(getstr(s),size,D); } } #define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) static void DumpFunction(const Proto* f, const TString* p, DumpState* D); static void DumpConstants(const Proto* f, DumpState* D) { int i,n=f->sizek; DumpInt(n,D); for (i=0; ik[i]; DumpChar(ttype(o),D); switch (ttype(o)) { case LUA_TNIL: break; case LUA_TBOOLEAN: DumpChar(bvalue(o),D); break; case LUA_TNUMBER: DumpNumber(nvalue(o),D); break; case LUA_TSTRING: DumpString(rawtsvalue(o),D); break; default: lua_assert(0); /* cannot happen */ break; } } n=f->sizep; DumpInt(n,D); for (i=0; ip[i],f->source,D); } static void DumpDebug(const Proto* f, DumpState* D) { int i,n; n= (D->strip) ? 0 : f->sizelineinfo; DumpVector(f->lineinfo,n,sizeof(int),D); n= (D->strip) ? 0 : f->sizelocvars; DumpInt(n,D); for (i=0; ilocvars[i].varname,D); DumpInt(f->locvars[i].startpc,D); DumpInt(f->locvars[i].endpc,D); } n= (D->strip) ? 0 : f->sizeupvalues; DumpInt(n,D); for (i=0; iupvalues[i],D); } static void DumpFunction(const Proto* f, const TString* p, DumpState* D) { DumpString((f->source==p || D->strip) ? NULL : f->source,D); DumpInt(f->linedefined,D); DumpInt(f->lastlinedefined,D); DumpChar(f->nups,D); DumpChar(f->numparams,D); DumpChar(f->is_vararg,D); DumpChar(f->maxstacksize,D); DumpCode(f,D); DumpConstants(f,D); DumpDebug(f,D); } static void DumpHeader(DumpState* D) { char h[LUAC_HEADERSIZE]; luaU_header(h); DumpBlock(h,LUAC_HEADERSIZE,D); } /* ** dump Lua function as precompiled chunk */ int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) { DumpState D; D.L=L; D.writer=w; D.data=data; D.strip=strip; D.status=0; DumpHeader(&D); DumpFunction(f,NULL,&D); return D.status; } debian/grub-extras/lua/lundump.h0000664000000000000000000000157212524662415014065 0ustar /* ** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ #ifndef lundump_h #define lundump_h #include "lobject.h" #include "lzio.h" /* load one chunk; from lundump.c */ LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); /* make header; from lundump.c */ LUAI_FUNC void luaU_header (char* h); /* dump one chunk; from ldump.c */ LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); #ifdef luac_c /* print one chunk; from print.c */ LUAI_FUNC void luaU_print (const Proto* f, int full); #endif /* for header of binary files -- this is Lua 5.1 */ #define LUAC_VERSION 0x51 /* for header of binary files -- this is the official format */ #define LUAC_FORMAT 0 /* size of header of binary files */ #define LUAC_HEADERSIZE 12 #endif debian/grub-extras/lua/ltablib.c0000664000000000000000000001627312524662415014011 0ustar /* ** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ #if 0 #include #endif #define ltablib_c #define LUA_LIB #include "lua.h" #include "lauxlib.h" #include "lualib.h" #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) static int foreachi (lua_State *L) { int i; int n = aux_getn(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); for (i=1; i <= n; i++) { lua_pushvalue(L, 2); /* function */ lua_pushinteger(L, i); /* 1st argument */ lua_rawgeti(L, 1, i); /* 2nd argument */ lua_call(L, 2, 1); if (!lua_isnil(L, -1)) return 1; lua_pop(L, 1); /* remove nil result */ } return 0; } static int foreach (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 2, LUA_TFUNCTION); lua_pushnil(L); /* first key */ while (lua_next(L, 1)) { lua_pushvalue(L, 2); /* function */ lua_pushvalue(L, -3); /* key */ lua_pushvalue(L, -3); /* value */ lua_call(L, 2, 1); if (!lua_isnil(L, -1)) return 1; lua_pop(L, 2); /* remove value and result */ } return 0; } static int maxn (lua_State *L) { lua_Number max = 0; luaL_checktype(L, 1, LUA_TTABLE); lua_pushnil(L); /* first key */ while (lua_next(L, 1)) { lua_pop(L, 1); /* remove value */ if (lua_type(L, -1) == LUA_TNUMBER) { lua_Number v = lua_tonumber(L, -1); if (v > max) max = v; } } lua_pushnumber(L, max); return 1; } static int getn (lua_State *L) { lua_pushinteger(L, aux_getn(L, 1)); return 1; } static int setn (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); #ifndef luaL_setn luaL_setn(L, 1, luaL_checkint(L, 2)); #else luaL_error(L, LUA_QL("setn") " is obsolete"); #endif lua_pushvalue(L, 1); return 1; } static int tinsert (lua_State *L) { int e = aux_getn(L, 1) + 1; /* first empty element */ int pos; /* where to insert new element */ switch (lua_gettop(L)) { case 2: { /* called with only 2 arguments */ pos = e; /* insert new element at the end */ break; } case 3: { int i; pos = luaL_checkint(L, 2); /* 2nd argument is the position */ if (pos > e) e = pos; /* `grow' array if necessary */ for (i = e; i > pos; i--) { /* move up elements */ lua_rawgeti(L, 1, i-1); lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ } break; } default: { return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); } } luaL_setn(L, 1, e); /* new size */ lua_rawseti(L, 1, pos); /* t[pos] = v */ return 0; } static int tremove (lua_State *L) { int e = aux_getn(L, 1); int pos = luaL_optint(L, 2, e); if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ return 0; /* nothing to remove */ luaL_setn(L, 1, e - 1); /* t.n = n-1 */ lua_rawgeti(L, 1, pos); /* result = t[pos] */ for ( ;pos= P */ while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { if (i>u) luaL_error(L, "invalid order function for sorting"); lua_pop(L, 1); /* remove a[i] */ } /* repeat --j until a[j] <= P */ while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { if (j #endif #define ltm_c #define LUA_CORE #include "lua.h" #include "lobject.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" const char *const luaT_typenames[] = { "nil", "boolean", "userdata", "number", "string", "table", "function", "userdata", "thread", "proto", "upval" }; void luaT_init (lua_State *L) { static const char *const luaT_eventname[] = { /* ORDER TM */ "__index", "__newindex", "__gc", "__mode", "__eq", "__add", "__sub", "__mul", "__div", "__mod", "__pow", "__unm", "__len", "__lt", "__le", "__concat", "__call" }; int i; for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); luaS_fix(G(L)->tmname[i]); /* never collect these names */ } } /* ** function to be used with macro "fasttm": optimized for absence of ** tag methods */ const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { const TValue *tm = luaH_getstr(events, ename); lua_assert(event <= TM_EQ); if (ttisnil(tm)) { /* no tag method? */ events->flags |= cast_byte(1u<metatable; break; case LUA_TUSERDATA: mt = uvalue(o)->metatable; break; default: mt = G(L)->mt[ttype(o)]; } return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); } debian/grub-extras/lua/grub_lib.h0000664000000000000000000000150412524662415014161 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GRUB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ #ifndef GRUB_LUA_LIB_HEADER #define GRUB_LUA_LIB_HEADER 1 extern luaL_Reg grub_lua_lib[]; #endif debian/grub-extras/lua/lgc.h0000664000000000000000000000612712524662415013147 0ustar /* ** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ #ifndef lgc_h #define lgc_h #include "lobject.h" /* ** Possible states of the Garbage Collector */ #define GCSpause 0 #define GCSpropagate 1 #define GCSsweepstring 2 #define GCSsweep 3 #define GCSfinalize 4 /* ** some userful bit tricks */ #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) #define setbits(x,m) ((x) |= (m)) #define testbits(x,m) ((x) & (m)) #define bitmask(b) (1<<(b)) #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) #define l_setbit(x,b) setbits(x, bitmask(b)) #define resetbit(x,b) resetbits(x, bitmask(b)) #define testbit(x,b) testbits(x, bitmask(b)) #define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) #define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) #define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) /* ** Layout for bit use in `marked' field: ** bit 0 - object is white (type 0) ** bit 1 - object is white (type 1) ** bit 2 - object is black ** bit 3 - for userdata: has been finalized ** bit 3 - for tables: has weak keys ** bit 4 - for tables: has weak values ** bit 5 - object is fixed (should not be collected) ** bit 6 - object is "super" fixed (only the main thread) */ #define WHITE0BIT 0 #define WHITE1BIT 1 #define BLACKBIT 2 #define FINALIZEDBIT 3 #define KEYWEAKBIT 3 #define VALUEWEAKBIT 4 #define FIXEDBIT 5 #define SFIXEDBIT 6 #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) #define isblack(x) testbit((x)->gch.marked, BLACKBIT) #define isgray(x) (!isblack(x) && !iswhite(x)) #define otherwhite(g) (g->currentwhite ^ WHITEBITS) #define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) #define luaC_checkGC(L) { \ condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ if (G(L)->totalbytes >= G(L)->GCthreshold) \ luaC_step(L); } #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ luaC_barrierf(L,obj2gco(p),gcvalue(v)); } #define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ luaC_barrierback(L,t); } #define luaC_objbarrier(L,p,o) \ { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ luaC_barrierf(L,obj2gco(p),obj2gco(o)); } #define luaC_objbarriert(L,t,o) \ { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); LUAI_FUNC void luaC_callGCTM (lua_State *L); LUAI_FUNC void luaC_freeall (lua_State *L); LUAI_FUNC void luaC_step (lua_State *L); LUAI_FUNC void luaC_fullgc (lua_State *L); LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); #endif debian/grub-extras/lua/lmem.c0000664000000000000000000000417412524662415013327 0ustar /* ** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ #include #define lmem_c #define LUA_CORE #include "lua.h" #include "ldebug.h" #include "ldo.h" #include "lmem.h" #include "lobject.h" #include "lstate.h" /* ** About the realloc function: ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); ** (`osize' is the old size, `nsize' is the new size) ** ** Lua ensures that (ptr == NULL) iff (osize == 0). ** ** * frealloc(ud, NULL, 0, x) creates a new block of size `x' ** ** * frealloc(ud, p, x, 0) frees the block `p' ** (in this specific case, frealloc must return NULL). ** particularly, frealloc(ud, NULL, 0, 0) does nothing ** (which is equivalent to free(NULL) in ANSI C) ** ** frealloc returns NULL if it cannot create or reallocate the area ** (any reallocation to an equal or smaller size cannot fail!) */ #define MINSIZEARRAY 4 void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, int limit, const char *errormsg) { void *newblock; int newsize; if (*size >= limit/2) { /* cannot double it? */ if (*size >= limit) /* cannot grow even a little? */ luaG_runerror(L, errormsg); newsize = limit; /* still have at least one free place */ } else { newsize = (*size)*2; if (newsize < MINSIZEARRAY) newsize = MINSIZEARRAY; /* minimum size */ } newblock = luaM_reallocv(L, block, *size, newsize, size_elems); *size = newsize; /* update only when everything else is OK */ return newblock; } void *luaM_toobig (lua_State *L) { luaG_runerror(L, "memory allocation error: block too big"); return NULL; /* to avoid warnings */ } /* ** generic allocation routine. */ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { global_State *g = G(L); lua_assert((osize == 0) == (block == NULL)); block = (*g->frealloc)(g->ud, block, osize, nsize); if (block == NULL && nsize > 0) luaD_throw(L, LUA_ERRMEM); lua_assert((nsize == 0) == (block == NULL)); g->totalbytes = (g->totalbytes - osize) + nsize; return block; } debian/grub-extras/lua/lcode.h0000664000000000000000000000527612524662415013474 0ustar /* ** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ #ifndef lcode_h #define lcode_h #include "llex.h" #include "lobject.h" #include "lopcodes.h" #include "lparser.h" /* ** Marks the end of a patch list. It is an invalid value both as an absolute ** address, and as a list link (would link an element to itself). */ #define NO_JUMP (-1) /* ** grep "ORDER OPR" if you change these enums */ typedef enum BinOpr { OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, OPR_CONCAT, OPR_NE, OPR_EQ, OPR_LT, OPR_LE, OPR_GT, OPR_GE, OPR_AND, OPR_OR, OPR_NOBINOPR } BinOpr; typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; #define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); LUAI_FUNC void luaK_fixline (FuncState *fs, int line); LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); LUAI_FUNC int luaK_jump (FuncState *fs); LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); LUAI_FUNC int luaK_getlabel (FuncState *fs); LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); #endif debian/grub-extras/lua/lstring.c0000664000000000000000000000606212524662415014055 0ustar /* ** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ #if 0 #include #endif #define lstring_c #define LUA_CORE #include "lua.h" #include "lmem.h" #include "lobject.h" #include "lstate.h" #include "lstring.h" void luaS_resize (lua_State *L, int newsize) { GCObject **newhash; stringtable *tb; int i; if (G(L)->gcstate == GCSsweepstring) return; /* cannot resize during GC traverse */ newhash = luaM_newvector(L, newsize, GCObject *); tb = &G(L)->strt; for (i=0; isize; i++) { GCObject *p = tb->hash[i]; while (p) { /* for each node in the list */ GCObject *next = p->gch.next; /* save next */ unsigned int h = gco2ts(p)->hash; int h1 = lmod(h, newsize); /* new position */ lua_assert(cast_int(h%newsize) == lmod(h, newsize)); p->gch.next = newhash[h1]; /* chain it */ newhash[h1] = p; p = next; } } luaM_freearray(L, tb->hash, tb->size, TString *); tb->size = newsize; tb->hash = newhash; } static TString *newlstr (lua_State *L, const char *str, size_t l, unsigned int h) { TString *ts; stringtable *tb; if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) luaM_toobig(L); ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); ts->tsv.len = l; ts->tsv.hash = h; ts->tsv.marked = luaC_white(G(L)); ts->tsv.tt = LUA_TSTRING; ts->tsv.reserved = 0; memcpy(ts+1, str, l*sizeof(char)); ((char *)(ts+1))[l] = '\0'; /* ending 0 */ tb = &G(L)->strt; h = lmod(h, tb->size); ts->tsv.next = tb->hash[h]; /* chain new entry */ tb->hash[h] = obj2gco(ts); tb->nuse++; if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) luaS_resize(L, tb->size*2); /* too crowded */ return ts; } TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { GCObject *o; unsigned int h = cast(unsigned int, l); /* seed */ size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ size_t l1; for (l1=l; l1>=step; l1-=step) /* compute hash */ h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; o != NULL; o = o->gch.next) { TString *ts = rawgco2ts(o); if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { /* string may be dead */ if (isdead(G(L), o)) changewhite(o); return ts; } } return newlstr(L, str, l, h); /* not found */ } Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { Udata *u; if (s > MAX_SIZET - sizeof(Udata)) luaM_toobig(L); u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); u->uv.marked = luaC_white(G(L)); /* is not finalized */ u->uv.tt = LUA_TUSERDATA; u->uv.len = s; u->uv.metatable = NULL; u->uv.env = e; /* chain it on udata list (after main thread) */ u->uv.next = G(L)->mainthread->next; G(L)->mainthread->next = obj2gco(u); return u; } debian/grub-extras/lua/lmathlib.c0000664000000000000000000001330712524662415014167 0ustar /* ** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ ** Standard mathematical library ** See Copyright Notice in lua.h */ #include #include #define lmathlib_c #define LUA_LIB #include "lua.h" #include "lauxlib.h" #include "lualib.h" #undef PI #define PI (3.14159265358979323846) #define RADIANS_PER_DEGREE (PI/180.0) static int math_abs (lua_State *L) { lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); return 1; } static int math_sin (lua_State *L) { lua_pushnumber(L, sin(luaL_checknumber(L, 1))); return 1; } static int math_sinh (lua_State *L) { lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); return 1; } static int math_cos (lua_State *L) { lua_pushnumber(L, cos(luaL_checknumber(L, 1))); return 1; } static int math_cosh (lua_State *L) { lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); return 1; } static int math_tan (lua_State *L) { lua_pushnumber(L, tan(luaL_checknumber(L, 1))); return 1; } static int math_tanh (lua_State *L) { lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); return 1; } static int math_asin (lua_State *L) { lua_pushnumber(L, asin(luaL_checknumber(L, 1))); return 1; } static int math_acos (lua_State *L) { lua_pushnumber(L, acos(luaL_checknumber(L, 1))); return 1; } static int math_atan (lua_State *L) { lua_pushnumber(L, atan(luaL_checknumber(L, 1))); return 1; } static int math_atan2 (lua_State *L) { lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); return 1; } static int math_ceil (lua_State *L) { lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); return 1; } static int math_floor (lua_State *L) { lua_pushnumber(L, floor(luaL_checknumber(L, 1))); return 1; } static int math_fmod (lua_State *L) { lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); return 1; } static int math_modf (lua_State *L) { double ip; double fp = modf(luaL_checknumber(L, 1), &ip); lua_pushnumber(L, ip); lua_pushnumber(L, fp); return 2; } static int math_sqrt (lua_State *L) { lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); return 1; } static int math_pow (lua_State *L) { lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); return 1; } static int math_log (lua_State *L) { lua_pushnumber(L, log(luaL_checknumber(L, 1))); return 1; } static int math_log10 (lua_State *L) { lua_pushnumber(L, log10(luaL_checknumber(L, 1))); return 1; } static int math_exp (lua_State *L) { lua_pushnumber(L, exp(luaL_checknumber(L, 1))); return 1; } static int math_deg (lua_State *L) { lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); return 1; } static int math_rad (lua_State *L) { lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); return 1; } static int math_frexp (lua_State *L) { int e; lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); lua_pushinteger(L, e); return 2; } static int math_ldexp (lua_State *L) { lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); return 1; } static int math_min (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ lua_Number dmin = luaL_checknumber(L, 1); int i; for (i=2; i<=n; i++) { lua_Number d = luaL_checknumber(L, i); if (d < dmin) dmin = d; } lua_pushnumber(L, dmin); return 1; } static int math_max (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ lua_Number dmax = luaL_checknumber(L, 1); int i; for (i=2; i<=n; i++) { lua_Number d = luaL_checknumber(L, i); if (d > dmax) dmax = d; } lua_pushnumber(L, dmax); return 1; } static int math_random (lua_State *L) { /* the `%' avoids the (rare) case of r==1, and is needed also because on some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; switch (lua_gettop(L)) { /* check number of arguments */ case 0: { /* no arguments */ lua_pushnumber(L, r); /* Number between 0 and 1 */ break; } case 1: { /* only upper limit */ int u = luaL_checkint(L, 1); luaL_argcheck(L, 1<=u, 1, "interval is empty"); lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ break; } case 2: { /* lower and upper limits */ int l = luaL_checkint(L, 1); int u = luaL_checkint(L, 2); luaL_argcheck(L, l<=u, 2, "interval is empty"); lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ break; } default: return luaL_error(L, "wrong number of arguments"); } return 1; } static int math_randomseed (lua_State *L) { srand(luaL_checkint(L, 1)); return 0; } static const luaL_Reg mathlib[] = { {"abs", math_abs}, {"acos", math_acos}, {"asin", math_asin}, {"atan2", math_atan2}, {"atan", math_atan}, {"ceil", math_ceil}, {"cosh", math_cosh}, {"cos", math_cos}, {"deg", math_deg}, {"exp", math_exp}, {"floor", math_floor}, {"fmod", math_fmod}, {"frexp", math_frexp}, {"ldexp", math_ldexp}, {"log10", math_log10}, {"log", math_log}, {"max", math_max}, {"min", math_min}, {"modf", math_modf}, {"pow", math_pow}, {"rad", math_rad}, {"random", math_random}, {"randomseed", math_randomseed}, {"sinh", math_sinh}, {"sin", math_sin}, {"sqrt", math_sqrt}, {"tanh", math_tanh}, {"tan", math_tan}, {NULL, NULL} }; /* ** Open math library */ LUALIB_API int luaopen_math (lua_State *L) { luaL_register(L, LUA_MATHLIBNAME, mathlib); lua_pushnumber(L, PI); lua_setfield(L, -2, "pi"); lua_pushnumber(L, HUGE_VAL); lua_setfield(L, -2, "huge"); #if defined(LUA_COMPAT_MOD) lua_getfield(L, -1, "fmod"); lua_setfield(L, -2, "mod"); #endif return 1; } debian/grub-extras/lua/loadlib.c0000664000000000000000000004516212524662415014005 0ustar /* ** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h ** ** This module contains an implementation of loadlib for Unix systems ** that have dlfcn, an implementation for Darwin (Mac OS X), an ** implementation for Windows, and a stub for other systems. */ #include #include #define loadlib_c #define LUA_LIB #include "lua.h" #include "lauxlib.h" #include "lualib.h" /* prefix for open functions in C libraries */ #define LUA_POF "luaopen_" /* separator for open functions in C libraries */ #define LUA_OFSEP "_" #define LIBPREFIX "LOADLIB: " #define POF LUA_POF #define LIB_FAIL "open" /* error codes for ll_loadfunc */ #define ERRLIB 1 #define ERRFUNC 2 #define setprogdir(L) ((void)0) static void ll_unloadlib (void *lib); static void *ll_load (lua_State *L, const char *path); static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); #if defined(LUA_DL_DLOPEN) /* ** {======================================================================== ** This is an implementation of loadlib based on the dlfcn interface. ** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, ** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least ** as an emulation layer on top of native functions. ** ========================================================================= */ #include static void ll_unloadlib (void *lib) { dlclose(lib); } static void *ll_load (lua_State *L, const char *path) { void *lib = dlopen(path, RTLD_NOW); if (lib == NULL) lua_pushstring(L, dlerror()); return lib; } static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { lua_CFunction f = (lua_CFunction)dlsym(lib, sym); if (f == NULL) lua_pushstring(L, dlerror()); return f; } /* }====================================================== */ #elif defined(LUA_DL_DLL) /* ** {====================================================================== ** This is an implementation of loadlib for Windows using native functions. ** ======================================================================= */ #include #undef setprogdir static void setprogdir (lua_State *L) { char buff[MAX_PATH + 1]; char *lb; DWORD nsize = sizeof(buff)/sizeof(char); DWORD n = GetModuleFileNameA(NULL, buff, nsize); if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) luaL_error(L, "unable to get ModuleFileName"); else { *lb = '\0'; luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); lua_remove(L, -2); /* remove original string */ } } static void pusherror (lua_State *L) { int error = GetLastError(); char buffer[128]; if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, buffer, sizeof(buffer), NULL)) lua_pushstring(L, buffer); else lua_pushfstring(L, "system error %d\n", error); } static void ll_unloadlib (void *lib) { FreeLibrary((HINSTANCE)lib); } static void *ll_load (lua_State *L, const char *path) { HINSTANCE lib = LoadLibraryA(path); if (lib == NULL) pusherror(L); return lib; } static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); if (f == NULL) pusherror(L); return f; } /* }====================================================== */ #elif defined(LUA_DL_DYLD) /* ** {====================================================================== ** Native Mac OS X / Darwin Implementation ** ======================================================================= */ #include /* Mac appends a `_' before C function names */ #undef POF #define POF "_" LUA_POF static void pusherror (lua_State *L) { const char *err_str; const char *err_file; NSLinkEditErrors err; int err_num; NSLinkEditError(&err, &err_num, &err_file, &err_str); lua_pushstring(L, err_str); } static const char *errorfromcode (NSObjectFileImageReturnCode ret) { switch (ret) { case NSObjectFileImageInappropriateFile: return "file is not a bundle"; case NSObjectFileImageArch: return "library is for wrong CPU type"; case NSObjectFileImageFormat: return "bad format"; case NSObjectFileImageAccess: return "cannot access file"; case NSObjectFileImageFailure: default: return "unable to load library"; } } static void ll_unloadlib (void *lib) { NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); } static void *ll_load (lua_State *L, const char *path) { NSObjectFileImage img; NSObjectFileImageReturnCode ret; /* this would be a rare case, but prevents crashing if it happens */ if(!_dyld_present()) { lua_pushliteral(L, "dyld not present"); return NULL; } ret = NSCreateObjectFileImageFromFile(path, &img); if (ret == NSObjectFileImageSuccess) { NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(img); if (mod == NULL) pusherror(L); return mod; } lua_pushstring(L, errorfromcode(ret)); return NULL; } static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); if (nss == NULL) { lua_pushfstring(L, "symbol " LUA_QS " not found", sym); return NULL; } return (lua_CFunction)NSAddressOfSymbol(nss); } /* }====================================================== */ #else /* ** {====================================================== ** Fallback for other systems ** ======================================================= */ #undef LIB_FAIL #define LIB_FAIL "absent" #define DLMSG "dynamic libraries not enabled; check your Lua installation" static void ll_unloadlib (void *lib) { (void)lib; /* to avoid warnings */ } static void *ll_load (lua_State *L, const char *path) { (void)path; /* to avoid warnings */ lua_pushliteral(L, DLMSG); return NULL; } static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { (void)lib; (void)sym; /* to avoid warnings */ lua_pushliteral(L, DLMSG); return NULL; } /* }====================================================== */ #endif static void **ll_register (lua_State *L, const char *path) { void **plib; lua_pushfstring(L, "%s%s", LIBPREFIX, path); lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ if (!lua_isnil(L, -1)) /* is there an entry? */ plib = (void **)lua_touserdata(L, -1); else { /* no entry yet; create one */ lua_pop(L, 1); plib = (void **)lua_newuserdata(L, sizeof(const void *)); *plib = NULL; luaL_getmetatable(L, "_LOADLIB"); lua_setmetatable(L, -2); lua_pushfstring(L, "%s%s", LIBPREFIX, path); lua_pushvalue(L, -2); lua_settable(L, LUA_REGISTRYINDEX); } return plib; } /* ** __gc tag method: calls library's `ll_unloadlib' function with the lib ** handle */ static int gctm (lua_State *L) { void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); if (*lib) ll_unloadlib(*lib); *lib = NULL; /* mark library as closed */ return 0; } static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { void **reg = ll_register(L, path); if (*reg == NULL) *reg = ll_load(L, path); if (*reg == NULL) return ERRLIB; /* unable to load library */ else { lua_CFunction f = ll_sym(L, *reg, sym); if (f == NULL) return ERRFUNC; /* unable to find function */ lua_pushcfunction(L, f); return 0; /* return function */ } } static int ll_loadlib (lua_State *L) { const char *path = luaL_checkstring(L, 1); const char *init = luaL_checkstring(L, 2); int stat = ll_loadfunc(L, path, init); if (stat == 0) /* no errors? */ return 1; /* return the loaded function */ else { /* error; error message is on stack top */ lua_pushnil(L); lua_insert(L, -2); lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); return 3; /* return nil, error message, and where */ } } /* ** {====================================================== ** 'require' function ** ======================================================= */ static int readable (const char *filename) { FILE *f = fopen(filename, "r"); /* try to open file */ if (f == NULL) return 0; /* open failed */ fclose(f); return 1; } static const char *pushnexttemplate (lua_State *L, const char *path) { const char *l; while (*path == *LUA_PATHSEP) path++; /* skip separators */ if (*path == '\0') return NULL; /* no more templates */ l = strchr(path, *LUA_PATHSEP); /* find next separator */ if (l == NULL) l = path + strlen(path); lua_pushlstring(L, path, l - path); /* template */ return l; } static const char *findfile (lua_State *L, const char *name, const char *pname) { const char *path; name = luaL_gsub(L, name, ".", LUA_DIRSEP); lua_getfield(L, LUA_ENVIRONINDEX, pname); path = lua_tostring(L, -1); if (path == NULL) luaL_error(L, LUA_QL("package.%s") " must be a string", pname); lua_pushliteral(L, ""); /* error accumulator */ while ((path = pushnexttemplate(L, path)) != NULL) { const char *filename; filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); lua_remove(L, -2); /* remove path template */ if (readable(filename)) /* does file exist and is readable? */ return filename; /* return that file name */ lua_pushfstring(L, "\n\tno file " LUA_QS, filename); lua_remove(L, -2); /* remove file name */ lua_concat(L, 2); /* add entry to possible error message */ } return NULL; /* not found */ } static void loaderror (lua_State *L, const char *filename) { luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", lua_tostring(L, 1), filename, lua_tostring(L, -1)); } static int loader_Lua (lua_State *L) { const char *filename; const char *name = luaL_checkstring(L, 1); filename = findfile(L, name, "path"); if (filename == NULL) return 1; /* library not found in this path */ if (luaL_loadfile(L, filename) != 0) loaderror(L, filename); return 1; /* library loaded successfully */ } static const char *mkfuncname (lua_State *L, const char *modname) { const char *funcname; const char *mark = strchr(modname, *LUA_IGMARK); if (mark) modname = mark + 1; funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); funcname = lua_pushfstring(L, POF"%s", funcname); lua_remove(L, -2); /* remove 'gsub' result */ return funcname; } static int loader_C (lua_State *L) { const char *funcname; const char *name = luaL_checkstring(L, 1); const char *filename = findfile(L, name, "cpath"); if (filename == NULL) return 1; /* library not found in this path */ funcname = mkfuncname(L, name); if (ll_loadfunc(L, filename, funcname) != 0) loaderror(L, filename); return 1; /* library loaded successfully */ } static int loader_Croot (lua_State *L) { const char *funcname; const char *filename; const char *name = luaL_checkstring(L, 1); const char *p = strchr(name, '.'); int stat; if (p == NULL) return 0; /* is root */ lua_pushlstring(L, name, p - name); filename = findfile(L, lua_tostring(L, -1), "cpath"); if (filename == NULL) return 1; /* root not found */ funcname = mkfuncname(L, name); if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { if (stat != ERRFUNC) loaderror(L, filename); /* real error */ lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, name, filename); return 1; /* function not found */ } return 1; } static int loader_preload (lua_State *L) { const char *name = luaL_checkstring(L, 1); lua_getfield(L, LUA_ENVIRONINDEX, "preload"); if (!lua_istable(L, -1)) luaL_error(L, LUA_QL("package.preload") " must be a table"); lua_getfield(L, -1, name); if (lua_isnil(L, -1)) /* not found? */ lua_pushfstring(L, "\n\tno field package.preload['%s']", name); return 1; } static const int sentinel_ = 0; #define sentinel ((void *)&sentinel_) static int ll_require (lua_State *L) { const char *name = luaL_checkstring(L, 1); int i; lua_settop(L, 1); /* _LOADED table will be at index 2 */ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, 2, name); if (lua_toboolean(L, -1)) { /* is it there? */ if (lua_touserdata(L, -1) == sentinel) /* check loops */ luaL_error(L, "loop or previous error loading module " LUA_QS, name); return 1; /* package is already loaded */ } /* else must load it; iterate over available loaders */ lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); if (!lua_istable(L, -1)) luaL_error(L, LUA_QL("package.loaders") " must be a table"); lua_pushliteral(L, ""); /* error message accumulator */ for (i=1; ; i++) { lua_rawgeti(L, -2, i); /* get a loader */ if (lua_isnil(L, -1)) luaL_error(L, "module " LUA_QS " not found:%s", name, lua_tostring(L, -2)); lua_pushstring(L, name); lua_call(L, 1, 1); /* call it */ if (lua_isfunction(L, -1)) /* did it find module? */ break; /* module loaded successfully */ else if (lua_isstring(L, -1)) /* loader returned error message? */ lua_concat(L, 2); /* accumulate it */ else lua_pop(L, 1); } lua_pushlightuserdata(L, sentinel); lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ lua_pushstring(L, name); /* pass name as argument to module */ lua_call(L, 1, 1); /* run loaded module */ if (!lua_isnil(L, -1)) /* non-nil return? */ lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ lua_getfield(L, 2, name); if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ lua_pushboolean(L, 1); /* use true as result */ lua_pushvalue(L, -1); /* extra copy to be returned */ lua_setfield(L, 2, name); /* _LOADED[name] = true */ } return 1; } /* }====================================================== */ /* ** {====================================================== ** 'module' function ** ======================================================= */ static void setfenv (lua_State *L) { lua_Debug ar; if (lua_getstack(L, 1, &ar) == 0 || lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ lua_iscfunction(L, -1)) luaL_error(L, LUA_QL("module") " not called from a Lua function"); lua_pushvalue(L, -2); lua_setfenv(L, -2); lua_pop(L, 1); } static void dooptions (lua_State *L, int n) { int i; for (i = 2; i <= n; i++) { lua_pushvalue(L, i); /* get option (a function) */ lua_pushvalue(L, -2); /* module */ lua_call(L, 1, 0); } } static void modinit (lua_State *L, const char *modname) { const char *dot; lua_pushvalue(L, -1); lua_setfield(L, -2, "_M"); /* module._M = module */ lua_pushstring(L, modname); lua_setfield(L, -2, "_NAME"); dot = strrchr(modname, '.'); /* look for last dot in module name */ if (dot == NULL) dot = modname; else dot++; /* set _PACKAGE as package name (full module name minus last part) */ lua_pushlstring(L, modname, dot - modname); lua_setfield(L, -2, "_PACKAGE"); } static int ll_module (lua_State *L) { const char *modname = luaL_checkstring(L, 1); int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ if (!lua_istable(L, -1)) { /* not found? */ lua_pop(L, 1); /* remove previous result */ /* try global variable (and create one if it does not exist) */ if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) return luaL_error(L, "name conflict for module " LUA_QS, modname); lua_pushvalue(L, -1); lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ } /* check whether table already has a _NAME field */ lua_getfield(L, -1, "_NAME"); if (!lua_isnil(L, -1)) /* is table an initialized module? */ lua_pop(L, 1); else { /* no; initialize it */ lua_pop(L, 1); modinit(L, modname); } lua_pushvalue(L, -1); setfenv(L); dooptions(L, loaded - 1); return 0; } static int ll_seeall (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); if (!lua_getmetatable(L, 1)) { lua_createtable(L, 0, 1); /* create new metatable */ lua_pushvalue(L, -1); lua_setmetatable(L, 1); } lua_pushvalue(L, LUA_GLOBALSINDEX); lua_setfield(L, -2, "__index"); /* mt.__index = _G */ return 0; } /* }====================================================== */ /* auxiliary mark (for internal use) */ #define AUXMARK "\1" static void setpath (lua_State *L, const char *fieldname, const char *envname, const char *def) { const char *path = getenv(envname); if (path == NULL) /* no environment variable? */ lua_pushstring(L, def); /* use default */ else { /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, LUA_PATHSEP AUXMARK LUA_PATHSEP); luaL_gsub(L, path, AUXMARK, def); lua_remove(L, -2); } setprogdir(L); lua_setfield(L, -2, fieldname); } static const luaL_Reg pk_funcs[] = { {"loadlib", ll_loadlib}, {"seeall", ll_seeall}, {NULL, NULL} }; static const luaL_Reg ll_funcs[] = { {"module", ll_module}, {"require", ll_require}, {NULL, NULL} }; static const lua_CFunction loaders[] = {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; LUALIB_API int luaopen_package (lua_State *L) { int i; /* create new type _LOADLIB */ luaL_newmetatable(L, "_LOADLIB"); lua_pushcfunction(L, gctm); lua_setfield(L, -2, "__gc"); /* create `package' table */ luaL_register(L, LUA_LOADLIBNAME, pk_funcs); #if defined(LUA_COMPAT_LOADLIB) lua_getfield(L, -1, "loadlib"); lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); #endif lua_pushvalue(L, -1); lua_replace(L, LUA_ENVIRONINDEX); /* create `loaders' table */ lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1); /* fill it with pre-defined loaders */ for (i=0; loaders[i] != NULL; i++) { lua_pushcfunction(L, loaders[i]); lua_rawseti(L, -2, i+1); } lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */ setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */ /* store config information */ lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" LUA_EXECDIR "\n" LUA_IGMARK); lua_setfield(L, -2, "config"); /* set field `loaded' */ luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); lua_setfield(L, -2, "loaded"); /* set field `preload' */ lua_newtable(L); lua_setfield(L, -2, "preload"); lua_pushvalue(L, LUA_GLOBALSINDEX); luaL_register(L, NULL, ll_funcs); /* open lib into global table */ lua_pop(L, 1); return 1; /* return 'package' table */ } debian/grub-extras/lua/README0000664000000000000000000000043612524662415013106 0ustar grub-extras is meant to be used as an overlay on grub2 source tree. Build instructions: - Copy grub-extras in a subdirectory of your grub2 checkout. For example, "grub-extras". - Export GRUB_CONTRIB environment variable to point to this directory. - Build GRUB as usual. debian/grub-extras/lua/llimits.h0000664000000000000000000000447312524662415014061 0ustar /* ** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $ ** Limits, basic types, and some other `installation-dependent' definitions ** See Copyright Notice in lua.h */ #ifndef llimits_h #define llimits_h #if 0 #include #include #endif #include "lua.h" typedef LUAI_UINT32 lu_int32; typedef LUAI_UMEM lu_mem; typedef LUAI_MEM l_mem; /* chars used as small naturals (so that `char' is reserved for characters) */ typedef unsigned char lu_byte; #define MAX_SIZET ((size_t)(~(size_t)0)-2) #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) #define MAX_INT (int)(INT_MAX-2) /* maximum value of an int (-2 for safety) */ /* ** conversion of pointer to integer ** this is for hashing only; there is no problem if the integer ** cannot hold the whole pointer value */ #define IntPoint(p) ((unsigned int)(lu_mem)(p)) /* type to ensure maximum alignment */ typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; /* result of a `usual argument conversion' over lua_Number */ typedef LUAI_UACNUMBER l_uacNumber; /* internal assertions for in-house debugging */ #ifdef lua_assert #define check_exp(c,e) (lua_assert(c), (e)) #define api_check(l,e) lua_assert(e) #else #define lua_assert(c) ((void)0) #define check_exp(c,e) (e) #define api_check luai_apicheck #endif #ifndef UNUSED #define UNUSED(x) ((void)(x)) /* to avoid warnings */ #endif #ifndef cast #define cast(t, exp) ((t)(exp)) #endif #define cast_byte(i) cast(lu_byte, (i)) #define cast_num(i) cast(lua_Number, (i)) #define cast_int(i) cast(int, (i)) /* ** type for virtual-machine instructions ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) */ typedef lu_int32 Instruction; /* maximum stack for a Lua function */ #define MAXSTACK 250 /* minimum size for the string table (must be power of 2) */ #ifndef MINSTRTABSIZE #define MINSTRTABSIZE 32 #endif /* minimum size for string buffer */ #ifndef LUA_MINBUFFER #define LUA_MINBUFFER 32 #endif #ifndef lua_lock #define lua_lock(L) ((void) 0) #define lua_unlock(L) ((void) 0) #endif #ifndef luai_threadyield #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} #endif /* ** macro to control inclusion of some hard tests on stack reallocation */ #ifndef HARDSTACKTESTS #define condhardstacktests(x) ((void)0) #else #define condhardstacktests(x) x #endif #endif debian/grub-extras/lua/lstate.c0000664000000000000000000001310012524662415013656 0ustar /* ** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ #include #define lstate_c #define LUA_CORE #include "lua.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lgc.h" #include "llex.h" #include "lmem.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" #define state_size(x) (sizeof(x) + LUAI_EXTRASPACE * sizeof (lua_State)) #define fromstate(l) (cast(lua_State *, (l)) - LUAI_EXTRASPACE) #define tostate(l) (cast(lua_State *, cast(lua_State *, l) + LUAI_EXTRASPACE)) /* ** Main thread combines a thread state and the global state */ typedef struct LG { lua_State l; global_State g; } LG; static void stack_init (lua_State *L1, lua_State *L) { /* initialize CallInfo array */ L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); L1->ci = L1->base_ci; L1->size_ci = BASIC_CI_SIZE; L1->end_ci = L1->base_ci + L1->size_ci - 1; /* initialize stack array */ L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; L1->top = L1->stack; L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; /* initialize first ci */ L1->ci->func = L1->top; setnilvalue(L1->top++); /* `function' entry for this `ci' */ L1->base = L1->ci->base = L1->top; L1->ci->top = L1->top + LUA_MINSTACK; } static void freestack (lua_State *L, lua_State *L1) { luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); luaM_freearray(L, L1->stack, L1->stacksize, TValue); } /* ** open parts that may cause memory-allocation errors */ static void f_luaopen (lua_State *L, void *ud) { global_State *g = G(L); UNUSED(ud); stack_init(L, L); /* init stack */ sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ luaT_init(L); luaX_init(L); luaS_fix(luaS_newliteral(L, MEMERRMSG)); g->GCthreshold = 4*g->totalbytes; } static void preinit_state (lua_State *L, global_State *g) { G(L) = g; L->stack = NULL; L->stacksize = 0; L->errorJmp = NULL; L->hook = NULL; L->hookmask = 0; L->basehookcount = 0; L->allowhook = 1; resethookcount(L); L->openupval = NULL; L->size_ci = 0; L->nCcalls = L->baseCcalls = 0; L->status = 0; L->base_ci = L->ci = NULL; L->savedpc = NULL; L->errfunc = 0; setnilvalue(gt(L)); } static void close_state (lua_State *L) { global_State *g = G(L); luaF_close(L, L->stack); /* close all upvalues for this thread */ luaC_freeall(L); /* collect all objects */ lua_assert(g->rootgc == obj2gco(L)); lua_assert(g->strt.nuse == 0); luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); luaZ_freebuffer(L, &g->buff); freestack(L, L); lua_assert(g->totalbytes == sizeof(LG)); (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); } lua_State *luaE_newthread (lua_State *L) { lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); luaC_link(L, obj2gco(L1), LUA_TTHREAD); preinit_state(L1, G(L)); stack_init(L1, L); /* init stack */ setobj2n(L, gt(L1), gt(L)); /* share table of globals */ L1->hookmask = L->hookmask; L1->basehookcount = L->basehookcount; L1->hook = L->hook; resethookcount(L1); lua_assert(iswhite(obj2gco(L1))); return L1; } void luaE_freethread (lua_State *L, lua_State *L1) { luaF_close(L1, L1->stack); /* close all upvalues for this thread */ lua_assert(L1->openupval == NULL); luai_userstatefree(L1); freestack(L, L1); luaM_freemem(L, fromstate(L1), state_size(lua_State)); } LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { int i; lua_State *L; global_State *g; void *l = (*f)(ud, NULL, 0, state_size(LG)); if (l == NULL) return NULL; L = tostate(l); g = &((LG *)L)->g; L->next = NULL; L->tt = LUA_TTHREAD; g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); L->marked = luaC_white(g); set2bits(L->marked, FIXEDBIT, SFIXEDBIT); preinit_state(L, g); g->frealloc = f; g->ud = ud; g->mainthread = L; g->uvhead.u.l.prev = &g->uvhead; g->uvhead.u.l.next = &g->uvhead; g->GCthreshold = 0; /* mark it as unfinished state */ g->strt.size = 0; g->strt.nuse = 0; g->strt.hash = NULL; setnilvalue(registry(L)); luaZ_initbuffer(L, &g->buff); g->panic = NULL; g->gcstate = GCSpause; g->rootgc = obj2gco(L); g->sweepstrgc = 0; g->sweepgc = &g->rootgc; g->gray = NULL; g->grayagain = NULL; g->weak = NULL; g->tmudata = NULL; g->totalbytes = sizeof(LG); g->gcpause = LUAI_GCPAUSE; g->gcstepmul = LUAI_GCMUL; g->gcdept = 0; for (i=0; imt[i] = NULL; if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { /* memory allocation error: free partial state */ close_state(L); L = NULL; } else luai_userstateopen(L); return L; } static void callallgcTM (lua_State *L, void *ud) { UNUSED(ud); luaC_callGCTM(L); /* call GC metamethods for all udata */ } LUA_API void lua_close (lua_State *L) { L = G(L)->mainthread; /* only the main thread can be closed */ lua_lock(L); luaF_close(L, L->stack); /* close all upvalues for this thread */ luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ L->errfunc = 0; /* no error function during GC metamethods */ do { /* repeat until no more errors */ L->ci = L->base_ci; L->base = L->top = L->ci->base; L->nCcalls = L->baseCcalls = 0; } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); lua_assert(G(L)->tmudata == NULL); luai_userstateclose(L); close_state(L); } debian/grub-extras/lua/COPYING0000664000000000000000000010451312524662415013262 0ustar GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . debian/grub-extras/lua/lzio.c0000664000000000000000000000315012524662415013343 0ustar /* ** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ ** a generic input stream interface ** See Copyright Notice in lua.h */ #if 0 #include #endif #define lzio_c #define LUA_CORE #include "lua.h" #include "llimits.h" #include "lmem.h" #include "lstate.h" #include "lzio.h" int luaZ_fill (ZIO *z) { size_t size; lua_State *L = z->L; const char *buff; lua_unlock(L); buff = z->reader(L, z->data, &size); lua_lock(L); if (buff == NULL || size == 0) return EOZ; z->n = size - 1; z->p = buff; return char2int(*(z->p++)); } int luaZ_lookahead (ZIO *z) { if (z->n == 0) { if (luaZ_fill(z) == EOZ) return EOZ; else { z->n++; /* luaZ_fill removed first byte; put back it */ z->p--; } } return char2int(*z->p); } void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { z->L = L; z->reader = reader; z->data = data; z->n = 0; z->p = NULL; } /* --------------------------------------------------------------- read --- */ size_t luaZ_read (ZIO *z, void *b, size_t n) { while (n) { size_t m; if (luaZ_lookahead(z) == EOZ) return n; /* return number of missing bytes */ m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ memcpy(b, z->p, m); z->n -= m; z->p += m; b = (char *)b + m; n -= m; } return 0; } /* ------------------------------------------------------------------------ */ char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { if (n > buff->buffsize) { if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; luaZ_resizebuffer(L, buff, n); } return buff->buffer; } debian/grub-extras/lua/lfunc.h0000664000000000000000000000214512524662415013505 0ustar /* ** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ #ifndef lfunc_h #define lfunc_h #include "lobject.h" #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ cast(int, sizeof(TValue)*((n)-1))) #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ cast(int, sizeof(TValue *)*((n)-1))) LUAI_FUNC Proto *luaF_newproto (lua_State *L); LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); LUAI_FUNC UpVal *luaF_newupval (lua_State *L); LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); LUAI_FUNC void luaF_close (lua_State *L, StkId level); LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, int pc); #endif debian/grub-extras/lua/Makefile.core.def0000664000000000000000000000222612524662415015351 0ustar AutoGen definitions Makefile.tpl; module = { name = lua; common = contrib/lua/lapi.c; common = contrib/lua/lcode.c; common = contrib/lua/ldebug.c; common = contrib/lua/ldo.c; common = contrib/lua/ldump.c; common = contrib/lua/lfunc.c; common = contrib/lua/lgc.c; common = contrib/lua/llex.c; common = contrib/lua/lmem.c; common = contrib/lua/lobject.c; common = contrib/lua/lopcodes.c; common = contrib/lua/lparser.c; common = contrib/lua/lstate.c; common = contrib/lua/lstring.c; common = contrib/lua/ltable.c; common = contrib/lua/ltm.c; common = contrib/lua/lundump.c; common = contrib/lua/lvm.c; common = contrib/lua/lzio.c; common = contrib/lua/lauxlib.c; common = contrib/lua/lbaselib.c; common = contrib/lua/linit.c; common = contrib/lua/ltablib.c; common = contrib/lua/lstrlib.c; common = contrib/lua/grub_main.c; common = contrib/lua/grub_lib.c; cflags = '$(CFLAGS_POSIX)'; cppflags = '$(CPPFLAGS_POSIX)'; pci_cppflags = '$(CPPFLAGS_POSIX) -DENABLE_LUA_PCI'; }; /* Extra libraries for lua script/lua/lmathlib.c script/lua/loslib.c script/lua/liolib.c script/lua/ldblib.c script/lua/loadlib.c */ debian/grub-extras/lua/grub_main.c0000664000000000000000000001146312524662415014337 0ustar /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GRUB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include "grub_lib.h" #include #include #include #include #include GRUB_MOD_LICENSE("GPLv3+"); static const char * scan_str (const char *s1, const char *s2) { while (*s1) { const char *p = s2; while (*p) { if (*s1 == *p) return s1; p++; } s1++; } return s1; } int strcspn (const char *s1, const char *s2) { const char *r; r = scan_str (s1, s2); return r - s1; } char * strpbrk (const char *s1, const char *s2) { const char *r; r = scan_str (s1, s2); return (*r) ? (char *) r : 0; } static lua_State *state; /* Call `grub_error' to report a Lua error. The error message string must be on the top of the Lua stack (at index -1). The error message is popped off the Lua stack before this function returns. */ static void handle_lua_error (const char *error_type) { const char *error_msg; error_msg = lua_tostring (state, -1); if (error_msg == NULL) error_msg = "(error message not a string)"; grub_error (GRUB_ERR_BAD_ARGUMENT, "%s: %s", error_type, error_msg); /* Pop the error message. */ lua_pop (state, 1); } /* Taken from lua.c */ static int incomplete (lua_State * L, int status) { if (status == LUA_ERRSYNTAX) { size_t lmsg; const char *msg = lua_tolstring (L, -1, &lmsg); const char *tp = msg + lmsg - (sizeof (LUA_QL ("")) - 1); if (strstr (msg, LUA_QL ("")) == tp) { lua_pop (L, 1); return 1; } } return 0; /* else... */ } static grub_err_t interactive (void) { const char *ps1 = "lua> "; const char *ps2 = "lua>> "; const char *prompt = ps1; char *line; char *chunk = NULL; size_t len; size_t oldlen = 0; int r; grub_printf ("%s", N_ ("Welcome to lua, press the escape key to exit.")); while ((line = grub_cmdline_get (prompt)) != NULL) { /* len = lenght of chunk + line + newline character */ len = oldlen + grub_strlen (line) + 1; chunk = grub_realloc (chunk, len + 1); grub_strcpy (chunk + oldlen , line); chunk[len - 1] = '\n'; chunk[len] = '\0'; grub_free (line); r = luaL_loadbuffer (state, chunk, len, "stdin"); if (!r) { /* No error: Execute this chunk and prepare to read another */ r = lua_pcall (state, 0, 0, 0); if (r) { handle_lua_error ("Lua"); grub_print_error (); } grub_free (chunk); chunk = NULL; len = 0; prompt = ps1; } else if (incomplete (state, r)) { /* Chunk is incomplete, try reading another line */ prompt = ps2; } else if (r == LUA_ERRSYNTAX) { handle_lua_error ("Lua"); grub_print_error (); /* This chunk is garbage, try starting another one */ grub_free (chunk); chunk = NULL; len = 0; prompt = ps1; } else { /* Handle errors other than syntax errors (out of memory, etc.) */ grub_free (chunk); handle_lua_error ("Lua parser failed"); return grub_errno; } oldlen = len; } grub_free (chunk); lua_gc (state, LUA_GCCOLLECT, 0); return grub_errno; } static grub_err_t grub_cmd_lua (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { if (argc == 1) { if (luaL_loadfile (state, args[0])) { handle_lua_error ("Lua"); } else if (lua_pcall (state, 0, 0, 0)) { handle_lua_error ("Lua"); } } else if (argc == 0) { return interactive (); } else { return grub_error (GRUB_ERR_BAD_ARGUMENT, "1 or 0 arguments expected"); } return grub_errno; } static grub_command_t cmd; GRUB_MOD_INIT (lua) { (void) mod; state = lua_open (); if (state) { lua_gc (state, LUA_GCSTOP, 0); luaL_openlibs (state); luaL_register (state, "grub", grub_lua_lib); lua_gc (state, LUA_GCRESTART, 0); cmd = grub_register_command ("lua", grub_cmd_lua, N_("[FILE]"), N_ ("Run lua script FILE or start interactive lua shell")); } } GRUB_MOD_FINI (lua) { if (state) { lua_close (state); grub_unregister_command (cmd); } } debian/grub-extras/lua/lcode.c0000664000000000000000000005203112524662415013456 0ustar /* ** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ #if 0 #include #endif #define lcode_c #define LUA_CORE #include "lua.h" #include "lcode.h" #include "ldebug.h" #include "ldo.h" #include "lgc.h" #include "llex.h" #include "lmem.h" #include "lobject.h" #include "lopcodes.h" #include "lparser.h" #include "ltable.h" #define hasjumps(e) ((e)->t != (e)->f) static int isnumeral(expdesc *e) { return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); } void luaK_nil (FuncState *fs, int from, int n) { Instruction *previous; if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ if (fs->pc == 0) { /* function start? */ if (from >= fs->nactvar) return; /* positions are already clean */ } else { previous = &fs->f->code[fs->pc-1]; if (GET_OPCODE(*previous) == OP_LOADNIL) { int pfrom = GETARG_A(*previous); int pto = GETARG_B(*previous); if (pfrom <= from && from <= pto+1) { /* can connect both? */ if (from+n-1 > pto) SETARG_B(*previous, from+n-1); return; } } } } luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ } int luaK_jump (FuncState *fs) { int jpc = fs->jpc; /* save list of jumps to here */ int j; fs->jpc = NO_JUMP; j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); luaK_concat(fs, &j, jpc); /* keep them on hold */ return j; } void luaK_ret (FuncState *fs, int first, int nret) { luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); } static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { luaK_codeABC(fs, op, A, B, C); return luaK_jump(fs); } static void fixjump (FuncState *fs, int pc, int dest) { Instruction *jmp = &fs->f->code[pc]; int offset = dest-(pc+1); lua_assert(dest != NO_JUMP); if (abs(offset) > MAXARG_sBx) luaX_syntaxerror(fs->ls, "control structure too long"); SETARG_sBx(*jmp, offset); } /* ** returns current `pc' and marks it as a jump target (to avoid wrong ** optimizations with consecutive instructions not in the same basic block). */ int luaK_getlabel (FuncState *fs) { fs->lasttarget = fs->pc; return fs->pc; } static int getjump (FuncState *fs, int pc) { int offset = GETARG_sBx(fs->f->code[pc]); if (offset == NO_JUMP) /* point to itself represents end of list */ return NO_JUMP; /* end of list */ else return (pc+1)+offset; /* turn offset into absolute position */ } static Instruction *getjumpcontrol (FuncState *fs, int pc) { Instruction *pi = &fs->f->code[pc]; if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) return pi-1; else return pi; } /* ** check whether list has any jump that do not produce a value ** (or produce an inverted value) */ static int need_value (FuncState *fs, int list) { for (; list != NO_JUMP; list = getjump(fs, list)) { Instruction i = *getjumpcontrol(fs, list); if (GET_OPCODE(i) != OP_TESTSET) return 1; } return 0; /* not found */ } static int patchtestreg (FuncState *fs, int node, int reg) { Instruction *i = getjumpcontrol(fs, node); if (GET_OPCODE(*i) != OP_TESTSET) return 0; /* cannot patch other instructions */ if (reg != NO_REG && reg != GETARG_B(*i)) SETARG_A(*i, reg); else /* no register to put value or register already has the value */ *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); return 1; } static void removevalues (FuncState *fs, int list) { for (; list != NO_JUMP; list = getjump(fs, list)) patchtestreg(fs, list, NO_REG); } static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, int dtarget) { while (list != NO_JUMP) { int next = getjump(fs, list); if (patchtestreg(fs, list, reg)) fixjump(fs, list, vtarget); else fixjump(fs, list, dtarget); /* jump to default target */ list = next; } } static void dischargejpc (FuncState *fs) { patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); fs->jpc = NO_JUMP; } void luaK_patchlist (FuncState *fs, int list, int target) { if (target == fs->pc) luaK_patchtohere(fs, list); else { lua_assert(target < fs->pc); patchlistaux(fs, list, target, NO_REG, target); } } void luaK_patchtohere (FuncState *fs, int list) { luaK_getlabel(fs); luaK_concat(fs, &fs->jpc, list); } void luaK_concat (FuncState *fs, int *l1, int l2) { if (l2 == NO_JUMP) return; else if (*l1 == NO_JUMP) *l1 = l2; else { int list = *l1; int next; while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ list = next; fixjump(fs, list, l2); } } void luaK_checkstack (FuncState *fs, int n) { int newstack = fs->freereg + n; if (newstack > fs->f->maxstacksize) { if (newstack >= MAXSTACK) luaX_syntaxerror(fs->ls, "function or expression too complex"); fs->f->maxstacksize = cast_byte(newstack); } } void luaK_reserveregs (FuncState *fs, int n) { luaK_checkstack(fs, n); fs->freereg += n; } static void freereg (FuncState *fs, int reg) { if (!ISK(reg) && reg >= fs->nactvar) { fs->freereg--; lua_assert(reg == fs->freereg); } } static void freeexp (FuncState *fs, expdesc *e) { if (e->k == VNONRELOC) freereg(fs, e->u.s.info); } static int addk (FuncState *fs, TValue *k, TValue *v) { lua_State *L = fs->L; TValue *idx = luaH_set(L, fs->h, k); Proto *f = fs->f; int oldsize = f->sizek; if (ttisnumber(idx)) { lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); return cast_int(nvalue(idx)); } else { /* constant not found; create a new entry */ setnvalue(idx, cast_num(fs->nk)); luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, MAXARG_Bx, "constant table overflow"); while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); setobj(L, &f->k[fs->nk], v); luaC_barrier(L, f, v); return fs->nk++; } } int luaK_stringK (FuncState *fs, TString *s) { TValue o; setsvalue(fs->L, &o, s); return addk(fs, &o, &o); } int luaK_numberK (FuncState *fs, lua_Number r) { TValue o; setnvalue(&o, r); return addk(fs, &o, &o); } static int boolK (FuncState *fs, int b) { TValue o; setbvalue(&o, b); return addk(fs, &o, &o); } static int nilK (FuncState *fs) { TValue k, v; setnilvalue(&v); /* cannot use nil as key; instead use table itself to represent nil */ sethvalue(fs->L, &k, fs->h); return addk(fs, &k, &v); } void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { if (e->k == VCALL) { /* expression is an open function call? */ SETARG_C(getcode(fs, e), nresults+1); } else if (e->k == VVARARG) { SETARG_B(getcode(fs, e), nresults+1); SETARG_A(getcode(fs, e), fs->freereg); luaK_reserveregs(fs, 1); } } void luaK_setoneret (FuncState *fs, expdesc *e) { if (e->k == VCALL) { /* expression is an open function call? */ e->k = VNONRELOC; e->u.s.info = GETARG_A(getcode(fs, e)); } else if (e->k == VVARARG) { SETARG_B(getcode(fs, e), 2); e->k = VRELOCABLE; /* can relocate its simple result */ } } void luaK_dischargevars (FuncState *fs, expdesc *e) { switch (e->k) { case VLOCAL: { e->k = VNONRELOC; break; } case VUPVAL: { e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); e->k = VRELOCABLE; break; } case VGLOBAL: { e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); e->k = VRELOCABLE; break; } case VINDEXED: { freereg(fs, e->u.s.aux); freereg(fs, e->u.s.info); e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); e->k = VRELOCABLE; break; } case VVARARG: case VCALL: { luaK_setoneret(fs, e); break; } default: break; /* there is one value available (somewhere) */ } } static int code_label (FuncState *fs, int A, int b, int jump) { luaK_getlabel(fs); /* those instructions may be jump targets */ return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); } static void discharge2reg (FuncState *fs, expdesc *e, int reg) { luaK_dischargevars(fs, e); switch (e->k) { case VNIL: { luaK_nil(fs, reg, 1); break; } case VFALSE: case VTRUE: { luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); break; } case VK: { luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); break; } case VKNUM: { luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); break; } case VRELOCABLE: { Instruction *pc = &getcode(fs, e); SETARG_A(*pc, reg); break; } case VNONRELOC: { if (reg != e->u.s.info) luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); break; } default: { lua_assert(e->k == VVOID || e->k == VJMP); return; /* nothing to do... */ } } e->u.s.info = reg; e->k = VNONRELOC; } static void discharge2anyreg (FuncState *fs, expdesc *e) { if (e->k != VNONRELOC) { luaK_reserveregs(fs, 1); discharge2reg(fs, e, fs->freereg-1); } } static void exp2reg (FuncState *fs, expdesc *e, int reg) { discharge2reg(fs, e, reg); if (e->k == VJMP) luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ if (hasjumps(e)) { int final; /* position after whole expression */ int p_f = NO_JUMP; /* position of an eventual LOAD false */ int p_t = NO_JUMP; /* position of an eventual LOAD true */ if (need_value(fs, e->t) || need_value(fs, e->f)) { int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); p_f = code_label(fs, reg, 0, 1); p_t = code_label(fs, reg, 1, 0); luaK_patchtohere(fs, fj); } final = luaK_getlabel(fs); patchlistaux(fs, e->f, final, reg, p_f); patchlistaux(fs, e->t, final, reg, p_t); } e->f = e->t = NO_JUMP; e->u.s.info = reg; e->k = VNONRELOC; } void luaK_exp2nextreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); freeexp(fs, e); luaK_reserveregs(fs, 1); exp2reg(fs, e, fs->freereg - 1); } int luaK_exp2anyreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); if (e->k == VNONRELOC) { if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ exp2reg(fs, e, e->u.s.info); /* put value on it */ return e->u.s.info; } } luaK_exp2nextreg(fs, e); /* default */ return e->u.s.info; } void luaK_exp2val (FuncState *fs, expdesc *e) { if (hasjumps(e)) luaK_exp2anyreg(fs, e); else luaK_dischargevars(fs, e); } int luaK_exp2RK (FuncState *fs, expdesc *e) { luaK_exp2val(fs, e); switch (e->k) { case VKNUM: case VTRUE: case VFALSE: case VNIL: { if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ e->u.s.info = (e->k == VNIL) ? nilK(fs) : (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : boolK(fs, (e->k == VTRUE)); e->k = VK; return RKASK(e->u.s.info); } else break; } case VK: { if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ return RKASK(e->u.s.info); else break; } default: break; } /* not a constant in the right range: put it in a register */ return luaK_exp2anyreg(fs, e); } void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { switch (var->k) { case VLOCAL: { freeexp(fs, ex); exp2reg(fs, ex, var->u.s.info); return; } case VUPVAL: { int e = luaK_exp2anyreg(fs, ex); luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); break; } case VGLOBAL: { int e = luaK_exp2anyreg(fs, ex); luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info); break; } case VINDEXED: { int e = luaK_exp2RK(fs, ex); luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); break; } default: { lua_assert(0); /* invalid var kind to store */ break; } } freeexp(fs, ex); } void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { int func; luaK_exp2anyreg(fs, e); freeexp(fs, e); func = fs->freereg; luaK_reserveregs(fs, 2); luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); freeexp(fs, key); e->u.s.info = func; e->k = VNONRELOC; } static void invertjump (FuncState *fs, expdesc *e) { Instruction *pc = getjumpcontrol(fs, e->u.s.info); lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && GET_OPCODE(*pc) != OP_TEST); SETARG_A(*pc, !(GETARG_A(*pc))); } static int jumponcond (FuncState *fs, expdesc *e, int cond) { if (e->k == VRELOCABLE) { Instruction ie = getcode(fs, e); if (GET_OPCODE(ie) == OP_NOT) { fs->pc--; /* remove previous OP_NOT */ return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); } /* else go through */ } discharge2anyreg(fs, e); freeexp(fs, e); return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); } void luaK_goiftrue (FuncState *fs, expdesc *e) { int pc; /* pc of last jump */ luaK_dischargevars(fs, e); switch (e->k) { case VK: case VKNUM: case VTRUE: { pc = NO_JUMP; /* always true; do nothing */ break; } case VFALSE: { pc = luaK_jump(fs); /* always jump */ break; } case VJMP: { invertjump(fs, e); pc = e->u.s.info; break; } default: { pc = jumponcond(fs, e, 0); break; } } luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ luaK_patchtohere(fs, e->t); e->t = NO_JUMP; } static void luaK_goiffalse (FuncState *fs, expdesc *e) { int pc; /* pc of last jump */ luaK_dischargevars(fs, e); switch (e->k) { case VNIL: case VFALSE: { pc = NO_JUMP; /* always false; do nothing */ break; } case VTRUE: { pc = luaK_jump(fs); /* always jump */ break; } case VJMP: { pc = e->u.s.info; break; } default: { pc = jumponcond(fs, e, 1); break; } } luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ luaK_patchtohere(fs, e->f); e->f = NO_JUMP; } static void codenot (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); switch (e->k) { case VNIL: case VFALSE: { e->k = VTRUE; break; } case VK: case VKNUM: case VTRUE: { e->k = VFALSE; break; } case VJMP: { invertjump(fs, e); break; } case VRELOCABLE: case VNONRELOC: { discharge2anyreg(fs, e); freeexp(fs, e); e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); e->k = VRELOCABLE; break; } default: { lua_assert(0); /* cannot happen */ break; } } /* interchange true and false lists */ { int temp = e->f; e->f = e->t; e->t = temp; } removevalues(fs, e->f); removevalues(fs, e->t); } void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { t->u.s.aux = luaK_exp2RK(fs, k); t->k = VINDEXED; } static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { lua_Number v1, v2, r; if (!isnumeral(e1) || !isnumeral(e2)) return 0; v1 = e1->u.nval; v2 = e2->u.nval; switch (op) { case OP_ADD: r = luai_numadd(v1, v2); break; case OP_SUB: r = luai_numsub(v1, v2); break; case OP_MUL: r = luai_nummul(v1, v2); break; case OP_DIV: if (v2 == 0) return 0; /* do not attempt to divide by 0 */ r = luai_numdiv(v1, v2); break; case OP_MOD: if (v2 == 0) return 0; /* do not attempt to divide by 0 */ r = luai_nummod(v1, v2); break; case OP_POW: r = luai_numpow(v1, v2); break; case OP_UNM: r = luai_numunm(v1); break; case OP_LEN: return 0; /* no constant folding for 'len' */ default: lua_assert(0); r = 0; break; } if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */ e1->u.nval = r; return 1; } static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { if (constfolding(op, e1, e2)) return; else { int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; int o1 = luaK_exp2RK(fs, e1); if (o1 > o2) { freeexp(fs, e1); freeexp(fs, e2); } else { freeexp(fs, e2); freeexp(fs, e1); } e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); e1->k = VRELOCABLE; } } static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, expdesc *e2) { int o1 = luaK_exp2RK(fs, e1); int o2 = luaK_exp2RK(fs, e2); freeexp(fs, e2); freeexp(fs, e1); if (cond == 0 && op != OP_EQ) { int temp; /* exchange args to replace by `<' or `<=' */ temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ cond = 1; } e1->u.s.info = condjump(fs, op, cond, o1, o2); e1->k = VJMP; } void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { expdesc e2; e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; switch (op) { case OPR_MINUS: { if (!isnumeral(e)) luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ codearith(fs, OP_UNM, e, &e2); break; } case OPR_NOT: codenot(fs, e); break; case OPR_LEN: { luaK_exp2anyreg(fs, e); /* cannot operate on constants */ codearith(fs, OP_LEN, e, &e2); break; } default: lua_assert(0); } } void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { switch (op) { case OPR_AND: { luaK_goiftrue(fs, v); break; } case OPR_OR: { luaK_goiffalse(fs, v); break; } case OPR_CONCAT: { luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ break; } case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: case OPR_MOD: case OPR_POW: { if (!isnumeral(v)) luaK_exp2RK(fs, v); break; } default: { luaK_exp2RK(fs, v); break; } } } void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { switch (op) { case OPR_AND: { lua_assert(e1->t == NO_JUMP); /* list must be closed */ luaK_dischargevars(fs, e2); luaK_concat(fs, &e2->f, e1->f); #if 0 *e1 = *e2; #else memcpy (e1, e2, sizeof (*e1)); #endif break; } case OPR_OR: { lua_assert(e1->f == NO_JUMP); /* list must be closed */ luaK_dischargevars(fs, e2); luaK_concat(fs, &e2->t, e1->t); #if 0 *e1 = *e2; #else memcpy (e1, e2, sizeof (*e1)); #endif break; } case OPR_CONCAT: { luaK_exp2val(fs, e2); if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); freeexp(fs, e1); SETARG_B(getcode(fs, e2), e1->u.s.info); e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; } else { luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ codearith(fs, OP_CONCAT, e1, e2); } break; } case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break; case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break; case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break; case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break; case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break; case OPR_POW: codearith(fs, OP_POW, e1, e2); break; case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break; case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break; case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break; case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break; case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break; case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break; default: lua_assert(0); } } void luaK_fixline (FuncState *fs, int line) { fs->f->lineinfo[fs->pc - 1] = line; } static int luaK_code (FuncState *fs, Instruction i, int line) { Proto *f = fs->f; dischargejpc(fs); /* `pc' will change */ /* put new instruction in code array */ luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, MAX_INT, "code size overflow"); f->code[fs->pc] = i; /* save corresponding line information */ luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, MAX_INT, "code size overflow"); f->lineinfo[fs->pc] = line; return fs->pc++; } int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { lua_assert(getOpMode(o) == iABC); lua_assert(getBMode(o) != OpArgN || b == 0); lua_assert(getCMode(o) != OpArgN || c == 0); return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); } int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); lua_assert(getCMode(o) == OpArgN); return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); } void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { int c; int b = (tostore == LUA_MULTRET) ? 0 : tostore; if (nelems == 0) c = 1; else c = ((unsigned) nelems + LFIELDS_PER_FLUSH - 1)/LFIELDS_PER_FLUSH; lua_assert(tostore != 0); if (c <= MAXARG_C) luaK_codeABC(fs, OP_SETLIST, base, b, c); else { luaK_codeABC(fs, OP_SETLIST, base, b, 0); luaK_code(fs, cast(Instruction, c), fs->ls->lastline); } fs->freereg = base + 1; /* free registers with list values */ } debian/grub-extras/lua/ldebug.h0000664000000000000000000000204512524662415013637 0ustar /* ** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions from Debug Interface module ** See Copyright Notice in lua.h */ #ifndef ldebug_h #define ldebug_h #include "lstate.h" #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) #define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) #define resethookcount(L) (L->hookcount = L->basehookcount) LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, const char *opname); LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2); LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2); LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); LUAI_FUNC void luaG_errormsg (lua_State *L); LUAI_FUNC int luaG_checkcode (const Proto *pt); LUAI_FUNC int luaG_checkopenop (Instruction i); #endif debian/grub-extras/lua/lauxlib.h0000664000000000000000000001323512524662415014040 0ustar /* ** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ #ifndef lauxlib_h #define lauxlib_h #if 0 #include #include #endif #include "lua.h" #if defined(LUA_COMPAT_GETN) LUALIB_API int (luaL_getn) (lua_State *L, int t); LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); #else #define luaL_getn(L,i) ((int)lua_objlen(L, i)) #define luaL_setn(L,i,j) ((void)0) /* no op! */ #endif #if defined(LUA_COMPAT_OPENLIB) #define luaI_openlib luaL_openlib #endif /* extra error code for `luaL_load' */ #define LUA_ERRFILE (LUA_ERRERR+1) typedef struct luaL_Reg { const char *name; lua_CFunction func; } luaL_Reg; LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, const luaL_Reg *l, int nup); LUALIB_API void (luaL_register) (lua_State *L, const char *libname, const luaL_Reg *l); LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, size_t *l); LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, const char *def, size_t *l); LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, lua_Integer def); LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); LUALIB_API void (luaL_checkany) (lua_State *L, int narg); LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); LUALIB_API void (luaL_where) (lua_State *L, int lvl); LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, const char *const lst[]); LUALIB_API int (luaL_ref) (lua_State *L, int t); LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name); LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); LUALIB_API lua_State *(luaL_newstate) (void); LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, const char *r); LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, const char *fname, int szhint); /* ** =============================================================== ** some useful macros ** =============================================================== */ #define luaL_argcheck(L, cond,numarg,extramsg) \ ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) #define luaL_dofile(L, fn) \ (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) #define luaL_dostring(L, s) \ (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) /* ** {====================================================== ** Generic Buffer manipulation ** ======================================================= */ typedef struct luaL_Buffer { char *p; /* current position in buffer */ int lvl; /* number of strings in the stack (level) */ lua_State *L; char buffer[LUAL_BUFFERSIZE]; } luaL_Buffer; #define luaL_addchar(B,c) \ ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ (*(B)->p++ = (char)(c))) /* compatibility only */ #define luaL_putchar(B,c) luaL_addchar(B,c) #define luaL_addsize(B,n) ((B)->p += (n)) LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); /* }====================================================== */ /* compatibility with ref system */ /* pre-defined references */ #define LUA_NOREF (-2) #define LUA_REFNIL (-1) #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) #define luaL_reg luaL_Reg #endif debian/grub-extras/lua/lzio.h0000664000000000000000000000302412524662415013350 0ustar /* ** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $ ** Buffered streams ** See Copyright Notice in lua.h */ #ifndef lzio_h #define lzio_h #include "lua.h" #include "lmem.h" #define EOZ (-1) /* end of stream */ typedef struct Zio ZIO; #define char2int(c) cast(int, cast(unsigned char, (c))) #define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) typedef struct Mbuffer { char *buffer; size_t n; size_t buffsize; } Mbuffer; #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) #define luaZ_buffer(buff) ((buff)->buffer) #define luaZ_sizebuffer(buff) ((buff)->buffsize) #define luaZ_bufflen(buff) ((buff)->n) #define luaZ_resetbuffer(buff) ((buff)->n = 0) #define luaZ_resizebuffer(L, buff, size) \ (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ (buff)->buffsize = size) #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data); LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ LUAI_FUNC int luaZ_lookahead (ZIO *z); /* --------- Private Part ------------------ */ struct Zio { size_t n; /* bytes still unread */ const char *p; /* current position in buffer */ lua_Reader reader; void* data; /* additional data */ lua_State *L; /* Lua state (for reader) */ }; LUAI_FUNC int luaZ_fill (ZIO *z); #endif debian/grub-extras/ntldr-img/0000775000000000000000000000000012524676037013344 5ustar debian/grub-extras/ntldr-img/g2hdr.S0000664000000000000000000000350612524662415014475 0ustar /* * GRUB Utilities -- Utilities for GRUB Legacy, GRUB2 and GRUB for DOS * Copyright (C) 2007 Bean (bean123@126.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include .file "g2hdr.S" .text .code16 .globl start, _start start: _start: // We are at 0x2000:0 // Move itself to 0x800:0 // Don't modify dx cld movw %cs, %ax movw %ax, %ds movw $0x800, %ax movw %ax, %es xorw %si, %si movw %si, %di movw $0x80, %cx rep movsl ljmp $0, $(jump_start-start+0x8000) jump_start: // Move data from 0x2040:0 to 0x820:0 movw $0x2040, %ax movw %ax, %ds movw $0x820, %ax movw %ax, %es xorl %eax, %eax movb %dh, (GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE + 2) movl GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE, %eax addl $GRUB_DECOMPRESSOR_I386_PC_MAX_DECOMPRESSOR_SIZE, %eax xorl %ecx, %ecx 1: xorw %si, %si movw %si, %di movw $0x8000, %cx cmpl %ecx, %eax jae 2f movw %ax, %cx 2: pushw %cx addw $3, %cx shrw $2, %cx rep movsl popw %cx movw %ds, %si addw $0x800, %si movw %si, %ds movw %es, %si addw $0x800, %si movw %si, %es subl %ecx, %eax jnz 1b ljmp $0, $(0x8000 + 0x200) . = _start + 0x200 - 2 .word 0xAA55 debian/grub-extras/ntldr-img/ntfsbs.S0000664000000000000000000006223412524662415014771 0ustar /* * GRUB Utilities -- Utilities for GRUB Legacy, GRUB2 and GRUB for DOS * Copyright (C) 2007 Bean (bean123@126.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* NTFS boot sector for loading GRLDR , written by bean * * This file can be compiled as standaolne boot sector, or it can be embeded in * GRLDR.MBR at 0xA00 , right after the ext2 boot sector * * To compile the standalone ntfsbs.bin: * gcc -c -o ntfsbs.o ntfsbs.S * gcc -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 -o ntfsbs_exec ntfsbs.o * objcopy -O binary ntfsbs_exec ntfsbs.bin * * To install the standalone ntfsbs.bin: * grubinst --restore=ntfsbs.bin DEVICE_OR_FILE * * Where DEVICE_OR_FILE specify a NTFS partition * * Limitations: * 1. Don't support >1K MFT record size, >4K INDEX record size * 2. Don't support encrypted file * 3. Don't support >4K non-resident attribute list and $BITMAP * */ #ifndef INSIDE_GRLDR .text .code16 #endif #define AT_STANDARD_INFORMATION 0x10 #define AT_ATTRIBUTE_LIST 0x20 #define AT_FILENAME 0x30 #define AT_OBJECT_ID 0x40 #define AT_SECURITY_DESCRIPTOR 0x50 #define AT_VOLUME_NAME 0x60 #define AT_VOLUME_INFORMATION 0x70 #define AT_DATA 0x80 #define AT_INDEX_ROOT 0x90 #define AT_INDEX_ALLOCATION 0xA0 #define AT_BITMAP 0xB0 #define AT_SYMLINK 0xC0 #define AT_EA_INFORMATION 0xD0 #define AT_EA 0xE0 #define MAX_MFT_SIZE 1 // 1<<(1+9) = 1024 #define MAX_IDX_SIZE 3 // 1<<(3+9) = 4096 #define LOADSEG_NT 0x2000 #define MMFT_BASE 0x2000 #define MMFT_EMFT (MMFT_BASE +1024) #define MMFT_EBUF (MMFT_BASE + 2048) #define CMFT_BASE (MMFT_BASE + 6144) #define CMFT_EMFT (CMFT_BASE + 1024) #define CMFT_EBUF (CMFT_BASE + 2048) #define INDX_BASE (CMFT_BASE + 6144) #define SBUF_BASE (INDX_BASE + 4096) #define NTFS_Large_Structure_Error_Code 1 #define NTFS_Corrupt_Error_Code 2 #define NTFS_Run_Overflow_Error_Code 3 #define NTFS_No_Data_Error_Code 4 #define NTFS_Decompress_Error_Code 5 #define NT_FG_COMP 1 #define NT_FG_MMFT 2 #define NT_FG_ALST 4 #define NT_FG_GPOS 8 #define nt_boot_drive -2(%bp) #define nt_blocksize -4(%bp) #define nt_spc -5(%bp) #define nt_mft_size -6(%bp) #define nt_idx_size -7(%bp) #define nt_mft_start -12(%bp) #define nt_remain_len -16(%bp) //#define nt_file_count -18(%bp) #define nt_flag (%di) #define nt_attr_cur 2(%di) #define nt_attr_nxt 4(%di) #define nt_attr_end 6(%di) #define nt_curr_vcn 8(%di) #define nt_curr_lcn 0x10(%di) #define nt_attr_ofs 0x14(%di) #define nt_target_vcn 0x18(%di) #define nt_read_count 0x1C(%di) #define nt_vcn_offset 0x20(%di) #define nt_emft_buf 1024(%di) #define nt_edat_buf 2048(%di) .arch i586 Entry_nt: jmp 1f . = Entry_nt + 0x02 .byte 0x90 /* for CHS. Another possible value is 0x0e for LBA */ .ascii "NTFS " .word 0 /* 0B - Bytes per sector */ .byte 0 /* 0D - Sectors per cluster */ .word 0 /* 0E - reserved sectors, unused */ .byte 0 /* 10 - number of FATs, unused */ .word 0 /* 11 - Max dir entries for FAT12/FAT16, unused */ .word 0 /* 13 - total sectors for FAT12/FAT16, unused */ .byte 0xF8 /* 15 - Media descriptor */ .word 0 /* 16 - sectors per FAT for FAT12/FAT16, unused */ .word 255 /* 18 - Sectors per track */ .word 63 /* 1A - Number of heads */ nt_part_ofs: .long 0 /* 1C - hidden sectors */ .long 0 /* 20 - total sectors for FAT32, unused */ .long 0x800080 /* 24 - Usually 80 00 80 00, A value of 80 00 00 00 has * been seen on a USB thumb drive which is formatted * with NTFS under Windows XP. Note this is removable * media and is not partitioned, the drive as a whole * is NTFS formatted. */ .long 0,0 /* 28 - Number of sectors in the volume */ .long 0,0 /* 30 - LCN of VCN 0 of the $MFT */ .long 0,0 /* 38 - LCN of VCN 0 of the $MFTMirr */ .long 0 /* 40 - Clusters per MFT Record */ .long 4 /* 44 - Clusters per Index Record */ .long 0,0 /* 48 - Volume serial number */ .long 0 /* 50 - Checksum, usually 0 */ 1: . = Entry_nt + 0x54 cli cld . = Entry_nt + 0x56 /* the byte at offset 0x57 stores the real partition number for read. * the format program or the caller should set it to a correct value. * For floppies, it should be 0xff, which stands for whole drive. */ movb $0xff, %dh /* boot partition number */ xorw %ax, %ax movw %ax, %ds movw $0x7c00, %bp movw %ax, %es movw %ax, %ss /* stack and BP-relative moves up, too */ leaw -0x20(%bp), %sp sti movw %dx, nt_boot_drive /* Test if your BIOS support LBA mode */ movb $0x41, %ah movw $0x55AA, %bx int $0x13 jc 1f /* No EBIOS */ cmpw $0xAA55, %bx jne 1f /* No EBIOS */ testb $1, %cl jz 1f /* No EBIOS */ /* EBIOS supported */ movb $0x42, (ebios_nt - 1 - Entry_nt)(%bp) 1: cmpl $0x42555247, (nt_sector_mark - Entry_nt)(%bp) jz 1f // Must be called from GRLDR.MBR movw $0x7E00, %bx movl (nt_part_ofs - Entry_nt)(%bp), %eax incl %eax call readDisk_nt // Load the second sector from disk call readDisk_nt // Load the third sector from disk call readDisk_nt 1: xorl %eax, %eax movw 0xb(%bp), %ax // Bytes per sector (blocksize) movw %ax, nt_blocksize call convert_to_power_2 movb %cl, %bl movb 0xd(%bp), %al // Sectors per cluster call convert_to_power_2 movb %cl, %ch addb %bl, %ch subb $9, %ch // 1<> 8; } static inline void set32 (void *buf_, unsigned offset, unsigned int val) { unsigned char *buf = (unsigned char *) buf_ + offset; buf[0] = val; buf[1] = val >> 8; buf[2] = val >> 16; buf[3] = val >> 24; } extern int mbr_nhd, mbr_spt; int go_sect(int,unsigned long); int xd_enum(int,xde_t*); int get_fstype(unsigned char*); const char* fst2str(int); const char* dfs2str(int); #if defined(__cplusplus) || defined(c_plusplus) } #endif #endif /* __UTILS_H */ debian/grub-extras/ntldr-img/bin2h.c0000664000000000000000000000264412524662415014513 0ustar /* * Copyright (C) 2008 Robert Millan * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include int main (int argc, char *argv[]) { int b, i; char *sym; unsigned int len; if (argc != 3) { fprintf (stderr, "Usage: %s symbol_name length\n", argv[0]); exit (1); } sym = argv[1]; len = atoi (argv[2]); b = getchar (); if (b == EOF) goto abort; printf ("/* THIS CHUNK OF BYTES IS AUTOMATICALY GENERATED */\n" "unsigned char %s[%u] =\n{\n", sym, len); while (1) { printf ("0x%02x", b); b = getchar (); if (b == EOF) goto end; for (i = 0; i < 16 - 1; i++) { printf (", 0x%02x", b); b = getchar (); if (b == EOF) goto end; } printf (",\n"); } end: printf ("\n};\n"); abort: exit (0); } debian/grub-extras/ntldr-img/grubinst.c0000664000000000000000000007317412524662415015354 0ustar /* * GRUB Utilities -- Utilities for GRUB Legacy, GRUB2 and GRUB for DOS * Copyright (C) 2007 Bean (bean123@126.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #ifndef WIN32 #define O_BINARY 0 #endif #include "grub_mbr.h" #include "utils.h" #include "version.h" // Application flags, used by this program #define AFG_VERBOSE 1 #define AFG_PAUSE 2 #define AFG_READ_ONLY 4 #define AFG_NO_BACKUP_MBR 8 #define AFG_FORCE_BACKUP_MBR 16 #define AFG_RESTORE_PREVMBR 32 #define AFG_LIST_PART 64 #define AFG_IS_FLOPPY 128 #define AFG_LBA_MODE 256 #define AFG_CHS_MODE 512 #define AFG_OUTPUT 1024 #define AFG_EDIT 2048 // Grldr flags, this flag is used by grldr.mbr #define GFG_DISABLE_FLOPPY 1 #define GFG_DISABLE_OSBR 2 #define GFG_DUCE 4 #define GFG_PREVMBR_LAST 128 #define APP_NAME "grubinst: " #define print_pause if (afg & AFG_PAUSE) {fputs("Press to continue ...\n",stderr); fflush(stderr); fgetc(stdin);} #define print_apperr(a) { fprintf(stderr,APP_NAME "%s\n",a); print_pause; } #define print_syserr(a) { perror(APP_NAME a); print_pause; } static void help(void) { fputs("Usage:\n" "\tgrubinst [OPTIONS] DEVICE_OR_FILE\n\n" "OPTIONS:\n\n" "\t--help,-h\t\tShow usage information\n\n" "\t--pause\t\t\tPause before exiting\n\n" "\t--version\t\tShow version information\n\n" "\t--verbose,-v\t\tVerbose output\n\n" "\t--list-part,-l\t\tList all logical partitions in DEVICE_OR_FILE\n\n" "\t--save=FN,-s=FN\t\tSave the orginal MBR/BS to FN\n\n" "\t--restore=FN,-r=FN\tRestore MBR/BS from previously saved FN\n\n" "\t--restore-prevmbr,-r\tRestore previous MBR saved in the second sector\n" "\t\t\t\tof DEVICE_OR_FILE\n\n" "\t--read-only,-t\t\tdo everything except the actual write to the\n" "\t\t\t\tspecified DEVICE_OR_FILE. (test mode)\n\n" "\t--no-backup-mbr\t\tdo not copy the old MBR to the second sector of\n" "\t\t\t\tDEVICE_OR_FILE.\n\n" "\t--force-backup-mbr\tforce the copy of old MBR to the second sector\n" "\t\t\t\tof DEVICE_OR_FILE.(default)\n\n" "\t--mbr-enable-floppy\tenable the search for GRLDR on floppy.(default)\n\n" "\t--mbr-disable-floppy\tdisable the search for GRLDR on floppy.\n\n" "\t--mbr-enable-osbr\tenable the boot of PREVIOUS MBR with invalid\n" "\t\t\t\tpartition table (usually an OS boot sector).\n" "\t\t\t\t(default)\n\n" "\t--mbr-disable-osbr\tdisable the boot of PREVIOUS MBR with invalid\n" "\t\t\t\tpartition table (usually an OS boot sector).\n\n" "\t--duce\t\t\tdisable the feature of unconditional entrance\n" "\t\t\t\tto the command-line.\n\n" "\t--boot-prevmbr-first\ttry to boot PREVIOUS MBR before the search for\n" "\t\t\t\tGRLDR.\n\n" "\t--boot-prevmbr-last\ttry to boot PREVIOUS MBR after the search for\n" "\t\t\t\tGRLDR.(default)\n\n" "\t--preferred-drive=D\tpreferred boot drive number, 0 <= D < 255.\n\n" "\t--preferred-partition=P\tpreferred partition number, 0 <= P < 255.\n\n" "\t--time-out=T,-t=T\twait T seconds before booting PREVIOUS MBR. if\n" "\t\t\t\tT is 0xff, wait forever. The default is 5.\n\n" "\t\t\t\tbefore booting PREVIOUS MBR. K is a word\n" "\t\t\t\tvalue, just as the value in AX register\n" "\t\t\t\treturned from int16/AH=1. The high byte is the\n" "\t\t\t\tscan code and the low byte is ASCII code. The\n" "\t\t\t\tdefault is 0x3920 for space bar.\n\n" "\t--key-name=S\t\tSpecify the name of the hot key.\n\n" "\t--floppy,-f\t\tif DEVICE_OR_FILE is floppy, use this option.\n\n" "\t--floppy=N\t\tif DEVICE_OR_FILE is a partition on a hard\n" "\t\t\t\tdrive, use this option. N is used to specify\n" "\t\t\t\tthe partition number: 0,1,2 and 3 for the\n" "\t\t\t\tprimary partitions, and 4,5,6,... for the\n" "\t\t\t\tlogical partitions.\n\n" "\t--sectors-per-track=S\tspecifies sectors per track for --floppy.\n" "\t\t\t\t1 <= S <= 63, default is 63.\n\n" "\t--heads=H\t\tspecifies number of heads for --floppy.\n" "\t\t\t\t1 <= H <= 256, default is 255.\n\n" "\t--start-sector=B\tspecifies hidden sectors for --floppy=N.\n\n" "\t--total-sectors=C\tspecifies total sectors for --floppy.\n" "\t\t\t\tdefault is 0.\n\n" "\t--lba\t\t\tuse lba mode for --floppy. If the floppy BIOS\n" "\t\t\t\thas LBA support, you can specify --lba here.\n" "\t\t\t\tIt is assumed that all floppy BIOSes have CHS\n" "\t\t\t\tsupport. So you would rather specify --chs.\n" "\t\t\t\tIf neither --chs nor --lba is specified, then\n" "\t\t\t\tthe LBA indicator(i.e., the third byte of the\n" "\t\t\t\tboot sector) will not be touched.\n\n" "\t--chs\t\t\tuse chs mode for --floppy. You should specify\n" "\t\t\t\t--chs if the floppy BIOS does not support LBA.\n" "\t\t\t\tWe assume all floppy BIOSes have CHS support.\n" "\t\t\t\tSo it is likely you want to specify --chs.\n" "\t\t\t\tIf neither --chs nor --lba is specified, then\n" "\t\t\t\tthe LBA indicator(i.e., the third byte of the\n" "\t\t\t\tboot sector) will not be touched.\n\n" "\t--install-partition=I\tInstall the boot record onto the boot area of\n" "\t-p=I\t\t\tpartition number I of the specified hard drive\n" "\t\t\t\tor harddrive image DEVICE_OR_FILE.\n\n" "\t--boot-file=F,-b=F\tChange the name of boot file.\n\n" "\t--load-seg=S\t\tChange load segment for boot file.\n\n" "\t--grub2,-2\t\tLoad grub2 kernel g2ldr instead of grldr.\n\n" "\t--output,-o\t\tSave embeded grldr.mbr to DEVICE_OR_FILE.\n\n" "\t--edit,-e\t\tEdit external grldr/grldr.mbr.\n", stderr); } int afg,gfg,def_drive,def_part,time_out,hot_key,part_num; int def_spt,def_hds,def_ssc,def_tsc; char *save_fn,*restore_fn,boot_file_83[12]; const char *key_name; const char *boot_file; unsigned short load_seg; static char fn_buf[24]; static char* get_disk_name(int n) { #if defined(WIN32) sprintf(fn_buf,"\\\\.\\PhysicalDrive%d",n); #elif defined(LINUX) sprintf(fn_buf,"/dev/hd%c",'a'+n); #elif defined(FREEBSD) sprintf(fn_buf,"/dev/ad%d",n); #else print_apperr("Disk device is not supported in your system"); return NULL; #endif return fn_buf; } static char* get_flop_name(int n) { #if defined(WIN32) if (n>1) { print_apperr("Only two floppy drives are supported"); return NULL; } sprintf(fn_buf,"\\\\.\\%c:",'A'+n); #elif defined(LINUX) || defined(FREEBSD) sprintf(fn_buf,"/dev/fd%d",n); #else print_apperr("Floppy device is not supported in your system"); return NULL; #endif return fn_buf; } static char* parse_fname(char* fn) { if ((afg & AFG_OUTPUT) && (fn[0]=='(')) { print_apperr("Can\'t use device name while using --output option"); return NULL; } if ((! strncmp(fn,"(hd",3)) || (! strncmp(fn,"(fd",3))) { int n; char *p; n=strtol(&fn[3],&p,0); if ((n<0) || (n>=MAX_DISKS)) { print_apperr("Invalid device number"); return NULL; } if (*p==',') { part_num=strtol(p+1,&p,0); if ((part_num<0) || (part_num>=MAX_PARTS)) { print_apperr("Invalid partition number"); return NULL; } } if ((*p!=')') || (*(p+1)!=0)) { print_apperr("Invalid device name"); return NULL; } if (fn[1]=='h') fn=get_disk_name(n); else { fn=get_flop_name(n); afg|=AFG_IS_FLOPPY; } } return fn; } static char* str_upcase(char* str) { int i; for (i=0;str[i];i++) if ((str[i]>='a') && (str[i]<='z')) str[i]-='a'-'A'; return str; } static char* str_lowcase(char* str) { int i; for (i=0;str[i];i++) if ((str[i]>='A') && (str[i]<='Z')) str[i]+='a'-'A'; return str; } static int SetBootFile(char* fn) { char* pc; if (*fn==0) return 1; if (strlen(fn)>7) return 1; pc=strchr(fn,'.'); if (pc) if ((pc==fn) || (pc-fn>8) || (strlen(pc+1)>3)) return 1; str_upcase(fn); memset(boot_file_83,' ',sizeof(boot_file_83)-1); if (pc) { memcpy(boot_file_83,fn,pc-fn); memcpy(&boot_file_83[8],pc+1,strlen(pc+1)); } else memcpy(boot_file_83,fn,strlen(fn)); str_lowcase(fn); boot_file=fn; return 0; } static void list(int hd) { xde_t xe; xe.cur=xe.nxt=0xFF; fprintf(stderr," # id base leng\n"); while (! xd_enum(hd,&xe)) fprintf(stderr,"%2d %02llX %8llX %8llX\n",xe.cur, (unsigned long long) xe.dfs, (unsigned long long) xe.bse, (unsigned long long) xe.len); } static int is_grldr_mbr(unsigned char* buf) { int i,n; i=0x1B7; n=sizeof("Missing MBR-helper.")-1; while ((i>n) && (buf[i]==0)) i--; return (! memcmp(&buf[i-n+1],"Missing MBR-helper.", sizeof("Missing MBR-helper."))); } static int install(char* fn) { int hd = -1,nn,fs,slen; unsigned char prev_mbr[sizeof(grub_mbr)]; unsigned long ssec; if (fn==NULL) return 1; if (afg & AFG_EDIT) { unsigned short r1,r2; if (afg & AFG_VERBOSE) fprintf(stderr,"Edit mode\n"); hd=open(fn,O_RDWR | O_BINARY,0644); if (hd==-1) { print_syserr("open"); return errno; } r1=get16(&grub_mbr[0x1FFA],0); nn=read(hd,grub_mbr,sizeof(grub_mbr)); if (nn==-1) { print_syserr("read"); close(hd); return errno; } if (nn<(int)sizeof(grub_mbr)) { print_apperr("The input file is too short"); close(hd); return 1; } if (get32(&grub_mbr[0x1FFC],0)!=0xAA555247) { print_apperr("Invalid input file"); close(hd); return 1; } r2=get16(&grub_mbr[0x1FFA],0); if (r1!=r2) { char buf[80]; sprintf(buf,"Version number mismatched (old=%d new=%d)",r2,r1); print_apperr(buf); close(hd); return 1; } go_sect(hd,0); afg |= AFG_OUTPUT; } if (boot_file) { unsigned short ofs; // Patching the FAT32 boot sector ofs=get16(&grub_mbr,0x400+0x1EC) & 0x7FF; strcpy((char *) &grub_mbr[0x400+ofs],boot_file_83); if (load_seg) set16(&grub_mbr,0x400+0x1EA,load_seg); // Patching the FAT12/FAT16 boot sector ofs=get16(&grub_mbr,0x600+0x1EC) & 0x7FF; strcpy((char *) &grub_mbr[0x600+ofs],boot_file_83); if (load_seg) set16(&grub_mbr,0x600+0x1EA,load_seg); // Patching the EXT2 boot sector ofs=get16(grub_mbr,0x800+0x1EE) & 0x7FF; strcpy((char *) &grub_mbr[0x800+ofs],boot_file); // Patching the NTFS sector ofs=get16(grub_mbr,0xA00+0x1EC) & 0x7FF; strcpy((char *) &grub_mbr[0xA00+ofs],boot_file); if (load_seg) set16(grub_mbr,0xA00+0x1EA,load_seg); if (afg & AFG_VERBOSE) { fprintf(stderr,"Boot file changed to %s\n",boot_file); if (load_seg) fprintf(stderr,"Load segment changed to %04X\n",load_seg); } } if (afg & AFG_OUTPUT) { int mode; mode=(! (afg & AFG_READ_ONLY))?(O_TRUNC | O_CREAT):0; if (! (afg & AFG_EDIT)) { if (afg & AFG_VERBOSE) fprintf(stderr,"Extract mode\n"); hd=open(fn,O_RDWR | O_BINARY | mode,0644); if (hd==-1) { print_syserr("open"); return errno; } } if (! (afg & AFG_READ_ONLY)) if (write(hd,grub_mbr,sizeof(grub_mbr))!=sizeof(grub_mbr)) { print_apperr("Write to output file fails"); close(hd); return 1; } goto quit; } memset(&grub_mbr[512],0,512); grub_mbr[2] = gfg; grub_mbr[3]=time_out; set16(&grub_mbr,4,hot_key); grub_mbr[6] = def_drive; grub_mbr[7] = def_part; if ((key_name==NULL) && (hot_key==0x3920)) key_name="SPACE"; if (key_name) strcpy((char *) &grub_mbr[0x1fec],key_name); hd=open(fn,O_RDWR | O_BINARY,S_IREAD | S_IWRITE); if (hd==-1) { print_syserr("open"); return errno; } if (afg & AFG_LIST_PART) { list(hd); close(hd); return 0; } if (part_num!=-1) { if (def_ssc!=-1) ssec=def_ssc; else { xde_t xe; xe.cur=0xFF; xe.nxt=part_num; if (xd_enum(hd,&xe)) { print_apperr("Partition not found"); close(hd); return 1; } ssec=xe.bse; if (afg & AFG_VERBOSE) fprintf(stderr,"Part Fs: %02X (%s)\nPart Leng: %llu\n",xe.dfs,dfs2str(xe.dfs), (unsigned long long) xe.len); } } else ssec=0; if (afg & AFG_VERBOSE) fprintf(stderr,"Start sector: %llu\n", (unsigned long long) ssec); if ((ssec) && (go_sect(hd,ssec))) { print_apperr("Can\'t seek to the start sector"); close(hd); return 1; } nn=read(hd,prev_mbr,sizeof(prev_mbr)); if (nn==-1) { print_syserr("read"); close(hd); return errno; } if (nn<(int)sizeof(prev_mbr)) { print_apperr("The input file is too short"); close(hd); return 1; } fs=get_fstype(prev_mbr); if (afg & AFG_VERBOSE) { fprintf(stderr,"Image type: %s\n",fst2str(fs)); if (fs==FST_MBR) fprintf(stderr,"Num of heads: %d\nSectors per track: %d\n",mbr_nhd,mbr_spt); } if (fs==FST_OTHER) { print_apperr("Unknown image type"); close(hd); return 1; } if (((part_num!=-1) || (afg & AFG_IS_FLOPPY)) && (fs==FST_MBR)) { print_apperr("Should be a file system image"); close(hd); return 1; } if ((part_num==-1) && ((afg & AFG_IS_FLOPPY)==0) && (fs!=FST_MBR)) { print_apperr("Should be a disk image"); close(hd); return 1; } if (fs==FST_MBR) { int n,nfs,sln; unsigned long ofs; unsigned char bs[1024]; ofs=0xFFFFFFFF; for (n=0x1BE;n<0x1FE;n+=16) if (prev_mbr[n+4]) { if (ofs>get32(&prev_mbr[n],8)) ofs=get32(&prev_mbr[n],8); } if (ofs<(sizeof(prev_mbr)>>9)) { print_apperr("Not enough room to install mbr"); close(hd); return 1; } slen=sizeof(prev_mbr); if (go_sect(hd,ofs)) { print_apperr("Can\'t seek to the first partition"); close(hd); return 1; } if (read(hd,bs,sizeof(bs))!=sizeof(bs)) { print_apperr("Fail to read boot sector"); close(hd); return 1; } nfs=get_fstype(bs); if (nfs==FST_FAT32) sln=0x5A - 0xB; else if (nfs==FST_FAT16) sln=0x3E - 0xB; else sln=0; if (sln) { memcpy(&grub_mbr[0xB],&bs[0xB],sln); set32(&grub_mbr[0],0x1C,0); set16(&grub_mbr[0],0xE,get16(&grub_mbr[0],0xE) + ofs); } } else if (fs==FST_NTFS) slen=2048; else slen=512; if (go_sect(hd,ssec)) { print_apperr("Can\'t seek to the start sector"); close(hd); return 1; } if (save_fn) { int h2; h2=open(save_fn,O_CREAT | O_TRUNC | O_RDWR | O_BINARY,S_IREAD | S_IWRITE); if (h2==-1) { print_syserr("open save file"); close(hd); return errno; } nn=write(h2,prev_mbr,slen); if (nn==-1) { print_syserr("write save file"); close(hd); close(h2); return errno; } if (nn=argc) { print_apperr("No filename specified"); return 1; } if (idx grldr * */ #ifndef STAGE1_5 //#include #else #error cannot compile with STAGE1_5 #endif #ifdef GRLDR_MBR .file "mbrstart.S" #elif defined(GRLDR_INSTALL) .file "bootlacestart.S" #else .file "grldrstart.S" #endif #ifdef GRLDR_INSTALL //.data #else .text .globl start, _start start: _start: #endif _start1: /* Tell GAS to generate 16-bit real mode instructions */ .code16 . = _start1 + 0x00 /* 1 byte at offset 0x00 will be overwritten for the EBIOS indicator * later. This is safe because the jmp instruction only get executed * once. The write happens after the jmp instruction have got * executed. * * The value written would be 0x42 for EBIOS present(LBA) and 0x02 * for non-present(CHS). * */ /* No cli, we use stack! BIOS or caller usually sets SS:SP=0000:0400 */ jmp 1f /* FAT32/NTFS routine comes to offset 0 */ . = _start1 + 0x02 .byte 0x80 /* bit0=1: disable GRLDR search on floppy */ /* bit1=1: disable the boot of the previous MBR with * invalid partition table */ /* bit2=1: disable the feature of unconditional * entrance to the command-line */ /* bit7=1: disable the boot of the previous MBR prior to the search for GRLDR */ /* GRLDR.MBR uses offset 0x03 to indicate a timer counter. */ /* 0xff indicates waiting forever, * other value specifies the time in seconds to wait */ . = _start1 + 0x03 .byte 5 /* a key press to wait. if AX returned from int16 equals this word, * the desired action will occur. */ . = _start1 + 0x04 .word 0x3920 /* the space bar */ . = _start1 + 0x06 .byte 0xff /* preferred boot drive number, 0xff for no-drive(i.e., drive not defined) */ .byte 0xff /* preferred partition number, 0xff for whole drive(a floppy that has no partition table) */ . = _start1 + 8 #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) /* filled in by mkisofs using the -boot-info-table option */ #;bi_pvd: .long 0xDEADBEEF /* LBA of primary volume descript */ #;bi_file: .long 0xDEADBEEF /* LBA of boot file */ #;bi_length: .long 0xDEADBEEF /* Length of boot file */ #;bi_csum: .long 0xDEADBEEF /* Checksum of boot file */ #;bi_reserved: .space (10*4) /* Reserved */ . = _start1 + 0x40 #else /* filled in with BPB in case the drive(typically USB) is treated as floppy by buggy BIOSes */ . = _start1 + 0x60 #endif /* ! defined(GRLDR_MBR) && (! defined(GRLDR_INSTALL)) */ 1: call 1f #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) . = _start1 + 0x43 #else . = _start1 + 0x63 #endif /* ! defined(GRLDR_MBR) && (! defined(GRLDR_INSTALL)) */ 1: popw %bx /* Instruction Pointer of 1b */ #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) subw $(1b - _start1), %bx /* CS:BX=_start1 */ #else subw $(1b - _start1), %bx /* CS:BX=_start1 */ #endif /* ! defined(GRLDR_MBR) && (! defined(GRLDR_INSTALL)) */ shrw $4, %bx movw %cs, %ax addw %ax, %bx /* BX:0000=_start1 */ #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) /* we are booted from BOOT.INI, or whole GRLDR image already loaded */ pushw %bx /* BX:0000=_start1 */ addw $((grldr_signature - _start1 + 4 + STAGE2_SIZE - 4) >> 4), %bx movw %bx, %ds cmpl $0xCE1A02B0, ((STAGE2_SIZE - 4) & 0x0F) popw %ds /* DS:0000=_start1 */ je grldr_real_start /* whole image loaded. boot it! */ /* bad! we might be loaded by a buggy BIOS with a no-emulation-mode * bootable CD. The buggy BIOS might load only 1 CD-ROM sector(2048 * bytes) of our grldr image. So we need this check. */ /* Our cdrom_check code begins at 0x1BE and overlaps the partition * table. Just in case someone replace it with a partition table and * use this sector as an MBR, we do this additional test for safety. */ /* We should avoid using opcode 0x00 and 0x80 at cdrom_check. */ /* Note that if cdrom_check code is present, then we are booting from * no-emulation mode cdrom. */ testb $0x7F, cdrom_check - _start1 /* is it 0x00 or 0x80? */ jz 1f /* yes, cdrom_check not found */ call cdrom_check /* no, cdrom_check is present */ 1: /* DS:0000=_start1 */ /* Let CS:0000=_start1 */ pushw %ds #;pushw $(1f - _start1) .byte 0x6A, (1f - _start1) lret . = . - (. - _start1) / 0x80 1: #else /* BX:0000=_start1 */ movw %bx, %ds /* Let CS:0000=_start1 */ pushw %bx #;pushw $(1f - _start1) .byte 0x6A, (1f - _start1) lret . = . - (. - _start1) / 0x80 1: testb $0x04, 0x02 jz 1f /* set the DUCE indicator */ xorw %ax, %ax movw %ax, %es movw $0x5FC, %di movl $0x45435544, %eax stosl 1: #endif /* CS:0000=DS:0000=_start1 */ /* we are loaded by BIOS or another boot loader */ #define GRLDR_CS 0x2000 /* grldr code segment */ /* hope this segment never be used by all */ /* subsequent partition boot records */ #if 0 /* for single sector boot record */ #define MONITOR 0x7e10 #else /* for 4-sector NTFS boot record */ #define MONITOR 0x8410 #endif // cli pushw $GRLDR_CS popw %ss movw $0x9000, %sp /* SS:SP=0x9d000, keep away from EBDA data */ // sti /* Extended BIOS Data Area should not take up space below 0x9d000 */ /* * 0x07c00-0x07dff This sector. Another boot loader load us here * 0x0d000-0x14dff partition/floppy boot track(bootsector,etc) * 0x94000-0x9bdff master boot track(MBR,etc,usually 63 sectors) * 0x9be00-0x9c3ff 3 sectors for temp extended partition entries * 0x9c400-0x9cfff 6 sectors for stack */ #define FS_BOOT 0xd00 /* segment of partition boot track */ xorw %cx, %cx pushw %cx /* CX=0 */ movw $0x0080, %dx pushw %dx movb $8, %ah /* read drive parameters changes DX,ES,DI */ stc int $0x13 popw %dx popw %ax /* AX=0 */ pushw %ss /* SS=0x9400 */ popw %es /* ES=0x9400 */ jc Error1 andb $63, %cl /* AL=sectors per track, CF cleared */ stc jz Error1 xchgw %ax, %cx /* this moves CL to AL, and CX=0 */ movb $0x02, %ah movw %ax, %bp /* save AX to BP: read 1 track */ xorw %bx, %bx /* ES already has a known value of 0x9400 */ incw %cx pushw %dx stc int $0x13 /* read master boot track to ES:0000 */ popw %dx jc Error1 negb %ah /* set CF=1 if non-zero */ Error1: pushw %cs /* DS=0 */ popw %ds /* DS=CS */ pushfw /* CF=1 on error */ /* CS=DS=old segment. ES=SS=new segment. */ /* Move the code and error messages from DS:0000 to 9400:0000, do not * touch the partition table */ xorw %si, %si xorw %di, %di movw $223, %cx /* 223 words = 446 bytes = 0x1be bytes */ cld repz movsw /* SI=DI=0x1be, CX=0 */ movw $(grldr_signature - _start1), %bx /* if the boot loader has loaded more than one sector, we use them */ movl $0xAA555247, %eax /* "GR" 0x55 0xAA */ //#if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) cmpl %eax, (%bx) /* DS=old segment! */ jne 1f /* The MOVE_HELPER code is in the old segment! */ call move_helper /* SI=0x1be, CX=0 */ 1: //#endif /* Jump to new segment! */ #if 1 ljmp $GRLDR_CS, $(1f - _start1) #else pushw %ss /* 0x9400 */ //pushw $(1f - _start1) .byte 0x6A, (1f - _start1) lret . = . - (. - _start1) / 0x80 #endif 1: /* We are at the new segment. CS=ES=SS=new segment. */ /* But DS is still old segment. */ pushw %ss popw %ds /* CS=DS=ES=SS=new segment. */ //movw $0x01be, %si /* check the existence of helper */ cmpl %eax, (%bx) #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) jne Error_or_prev_MBR /* Missing helper */ #else je 1f /* try to load helper from floppy */ pushal movw 0x18, %ax /* BPB sectors per track at offset 0x18 */ cmpw $0x3F, %ax ja 3f cmpb $((pre_stage2_start - _start1) >> 9), %al jb 3f decw %ax /* skip the first sector already loaded */ movw $3, %di /* retry 3 times on read failure */ 2: movb $2, %ah /* BIOS disk read */ cwd /* DX=0 for floppy head 0 */ movw $0x200, %bx /* ES:BX immediately follow this sector */ movw $2, %cx /* skip the first sector already loaded */ pushaw int $0x13 popaw jnc 3f pushaw xorw %ax, %ax int $0x13 popaw decw %di jnz 2b 3: popal cmpl %eax, (%bx) /* helper loaded? */ jne Error_or_prev_MBR /* Missing helper */ 1: #endif popfw /* CF=1 on error */ jc try_floppy /* harddisk (hd0) failed, try floppy (fd0) */ 1: pushw %cs popw %ds lodsw movb %ah, %dh /* head number */ lodsw movw %ax, %cx /* sector and cylinder number */ andb $63, %al //stc jz helper_call_c /* use BP to calculate the sectors to read within 1 track */ subw %bp, %ax decw %ax /* decb %al */ negb %al /* AL=sectors upto the end of the track */ 7: movw $3, %di /* retry 3 times on read failure */ 2: movb $2, %ah pushw $FS_BOOT popw %es /* ES=FS_BOOT */ xorw %bx, %bx pushaw int $0x13 /* read partition boot track to FS_BOOT:0000 */ popaw jnc helper_call pushaw xorw %ax, %ax int $0x13 popaw decw %di jnz 2b helper_call_c: stc helper_call: /* find GRLDR in this partition * before the call: * CF=1 : indicates an invalid or corrupt entry * CF=0 : indicates a valid entry * * on return: * CF=1 : means "below", try next entry * CF=0,ZF=1 : means "equal", helper did nothing, so we need * a further try to boot via NT bootsector * CF=0,ZF=0 : means "above", helper succeeded, boot it now */ call helper_start /* change to jmp 6f if helper not present */ ja filesystem_boot /* helper succeeded, directly boot it */ 6: add_sub_si: /* extended partition check routine will adjust this to * * 0x83, 0xEE, 0x04 for "subw $4, %si" * * or * * 0x83, 0xC6, 0xFC for "addw $-4, %si" * * so that SI keeps the value 0x1fe. */ addw $12, %si /* 0x83, 0xC6, 0x0C */ . = add_sub_si + 3 /* extended partition check routine will adjust the word 0x1fe at * (add_sub_si + 5). The value 0x1ff or greater indicates there are * entries need to be treated. The value 0x1fe indicates no entries * left, and the floppy should be checked. */ cmpw $0x01fe, %si /* 0x81, 0xFE, 0xfe, 0x01 */ /* All entries checked done? */ jb 1b /* No, check the next entry */ ja 5f /* floppy already checked. Fail and hang */ try_floppy: movw $0x31b2, %si /* a value big enough */ movb $0x08, %ah /* read drive parameters changes DX,ES,DI */ cwd /* DL=0 for floppy */ pushw %dx /* DX=0 */ int $0x13 popw %ax /* AX=0 */ jc 5f /* floppy failure, issue "Error" and hang */ cwd /* DX=0 */ xchgw %ax, %cx /* this moves CL to AL, and CX=0 */ andb $63, %al /* AL=sectors per track */ jz 5f /* invalid value. floppy failure. hangs */ //movw $1, %cx incw %cx jmp 7b 5: Error_or_prev_MBR: /* GRLDR not found, print "Error" or launch previous MBR */ movw $(message_string - _start1), %si Error2: call print_message /* CS:SI points to message string */ 3: jmp 3b #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) filesystem_boot: /* The partition boot record successfully modified, just boot it */ /* * The boot might fail, but we want to take back the control. * So we save the registers now. */ pushw %ds pushw %es pushal /* DS=CS=GRLDR_CS, ES=FS_BOOT */ /* save GRLDR_CS */ movw %es, %bx # save old ES to BX cli lgdt gdt - _start1 movl %cr0, %eax orb $1, %al movl %eax, %cr0 movw $8, %si movw %si, %es xorl %esi, %esi xorl %edi, %edi movl $(0x9000 / 4), %ecx cld repz movsl movw $16, %si movw %si, %es andb $0xfe, %al movl %eax, %cr0 movw %bx, %es # restore ES from BX /* move FS_BOOT:0000 to 0:7c00 */ #if 0 /* for single sector boot record */ movw $0x0200, %cx /* move 2 sectors, the old FS_BOOT:0000 will * keep untouched. */ #else /* for 4-sector NTFS boot record */ movw $0x0400, %cx /* move 4 sectors, the old FS_BOOT:0000 will * keep untouched. */ #endif xorw %si, %si pushw %si /* SI=0, for the segment of 0000:7c00 */ movw $0x7c00, %di pushw %di /* DI=0x7c00, for the offset of 0000:7c00 */ pushw %es /* ES=FS_BOOT */ popw %ds /* DS=FS_BOOT */ pushw %si /* SI=0 */ popw %es /* ES=0 */ cld repz movsw movw $MONITOR, %di movw $(restore_GRLDR_CS - _start1), %si movw $((gdt_end - restore_GRLDR_CS) / 4), %cx cld repz cs movsl /* CS segment override prefix(=0x2E) */ pushw %es /* ES=0 */ popw %ds /* DS=0 */ sti lret //ljmp $0, $0x7c00 #endif try_next_partition: cli movw $GRLDR_CS, %ax movw %ax, %ss movw $(0x9000-36), %sp sti /* restore the registers and continue */ popal popw %es popw %ds jmp add_sub_si /* prints string CS:SI (modifies AX BX SI) */ 3: //xorw %bx, %bx /* video page 0 */ movb $0x0e, %ah /* print char in AL */ int $0x10 /* via TTY mode */ print_message: lodsb %cs:(%si), %al /* get token */ cmpb $0, %al /* end of string? */ jne 3b ret message_string: #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) .ascii "\r\nMissing helper.\0" #else .ascii "\r\nMissing MBR-helper.\0" #endif #;buggy_bios_string: #; #; .ascii "\r\nBuggy BIOS!\0" /* Make sure the above code does not occupy the partition table */ #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) /* offset value here must be less than or equal to 0x1be */ . = . - ((. - _start1) / 0x1bf) #else /* offset value here must be less than or equal to 0x1b8 */ . = . - ((. - _start1) / 0x1b9) #endif /* The following code may occupy the same area as the partition table */ #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) /* we are not booted from MBR. So we can reuse the area of partition * table for our code. */ . = _start1 + 0x1be cdrom_check: /* DS points to the sector start, but CS does not. */ /* BX segment points to near the end of GRLDR image. */ popw %ax /* old return IP */ /* set BX as the new safe stack. */ movw %bx, %ss movw $0xFFF0, %sp pushw %ax /* old return IP */ /* check if DL is no-emulation-mode bootable CDROM. */ pushw %ds cmpb $0x80, %dl jb 1f /* not a valid no-emulation-mode cdrom drive number */ cmpw $0xAA55, 0x7FE /* 2048 bytes loaded? */ jne 1f // cmpw $0xAA55, 0x5FE /* 2048 bytes loaded? */ // jne 1f movw $0x0180, %si movw $0x4B01, %ax pushw $0x0040 //.byte 0x6A, 0x40 popw %ds pushw %ds popw %es movb $0x13, (%si) int $0x13 /* ignore CF */ #; jc 2f /* not in emulation mode */ xorl %eax, %eax xorw %bp, %bp testb $0x0F, 1(%si) /* boot media type is No Emulation? */ jnz 2f /* no, it simulates floppy or hard disk. */ cmpb %dl, 2(%si) /* drive number */ jnz 2f /* invalid drive */ /* OK! it is no-emulation-mode cdrom drive. */ movl 4(%si), %eax /* LBA of GRLDR */ incw %bp 2: jmp cdrom_helper 1: popw %ds ret #endif /* ! defined(GRLDR_MBR) && (! defined(GRLDR_INSTALL)) */ . = _start1 + 0x1fe /* boot signature */ /* partition entries in the extended partitions will overwrite code here upto * 0x3fd. * * the extended partition entries will occupy a temp area at 0x9be00-0x9c3ff */ #if (defined(GRLDR_MBR)) || (defined(GRLDR_INSTALL)) .word 0xaa55 #endif . = _start1 + 0x200 /* if it is in the Master Boot Track, the second sector can be used to backup * the previously working MBR, typically, the MS MBR. if the backup copy of * the MBR cannot boot(because, e.g., it depends on another sector of code * that does not exist for now), then please do not set the ending signature * to 0xAA55, that is to say, if the signature is already 0xAA55, you should * change it to another value(for example, 0x0000). */ #if (! defined(GRLDR_INSTALL)) #if 0 print_cl: pushaw movw %cx, %ax movb $16, %cl divb %cl # quo=AL, rem=AH orw $0x3030, %ax cmpb $0x39, %ah jbe 1f addb $7, %ah 1: cmpb $0x39, %al jbe 1f addb $7, %al 1: movb %ah, %cl xorw %bx, %bx movb $0x0e, %ah int $0x10 movb $0x0e, %ah movb %cl, %al int $0x10 movw $0x0e20, %ax int $0x10 popaw ret #else #if 0 .word 5, 0x47, 0x52, 0x4c, 0x44, 0x52, 4, 0x24 .word 0x49, 0x33, 0x30, 0xe000, 0, 0x3000, 0, 0 #else .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 #endif .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 #endif . = _start1 + 0x256 /* cmdcons comes here */ #if 0 jmp 1f #else .byte 0x90, 0x90 #endif . = _start1 + 0x258 .byte 0x90, 0x90 . = _start1 + 0x25a .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 . = _start1 + 0x26a 1: //movw %cs, %ax //movw %ax, %ds //jmp single_boot_sector /* a value < 0x80 here means we are not booted from no-emulation-mode * bootable CD. */ movb $0x7F, %dl jmp _start1 #endif /* (! defined(GRLDR_INSTALL)) */ #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) cdrom_helper: /* IP and old_DS is on the stack. */ /* DS=ES=40h */ /* Stack is high and safe. */ /* EAX is LBA. if EAX==0, LBA is unknown. */ /* check if the first sector is the same as the current one */ /* load the first sector onto the sector immediately follows */ 1: popw %bx /* BX = old_DS = load_segment */ pushw %bx movw %bx, %es addw $0x0080, %bx /* buffer segment */ call load_cd_sector /* compare the two sectors */ movw $0x200, %cx movw %bx, %ds xorw %si, %si xorw %di, %di cld repz cmpsl je load_the_rest /* 1st sector is ok, continue */ not_grldr: testw %bp, %bp jz 2f xorw %bp, %bp xorl %eax, %eax 2: incl %eax jnz 1b /* try next */ cd_no_grldr: popw %ds /* DS=load_segment */ # Here we use error message and routine in FAT32 boot sector # which is also inside the 2048-byte CD sector. movw $(msg_BootError_32 - _start1), %si jmp boot_error_32 load_cd_sector: /* input: EAX LBA * BX buffer segment(buffer offset=0) * DS 0x40 (or another safe one) */ movw $0x1A0, %si /* disk address packet */ movl $0x00010010, (%si) /* load 1 sector each time. */ movw $0, 4(%si) /* buffer offset=0 */ movw %bx, 6(%si) /* buffer segment */ movl %eax, 8(%si) /* LBA lo 32 bits */ movl $0, 12(%si) /* LBA hi 32 bits */ pushal movb $0x42, %ah int $0x13 popal ret load_the_rest: /* load all sectors (except the first one) */ /* EAX = first sector(LBA) of GRLDR */ popw %bx /* BX = old_DS = load_segment */ pushw %bx movw %bx, %es /* 6144 = 0x1800 = 3 sectors > 4KB, this is for the additional 4KB-preset-menu at the end of grldr */ movw $((grldr_signature - _start1 + 4 + STAGE2_SIZE - 1 + 6144) / 2048), %cx /* sectors to load */ 1: incl %eax /* next sector */ addw $0x0080, %bx /* buffer segment */ call load_cd_sector loop 1b /* loading is completed. BX=segment of the last sector. */ subw $0x0181, %bx /* decw %bx */ movw %bx, %ds /* check the ending signature */ cmpl $0xCE1A02B0, ((grldr_signature - _start1 + 4 + STAGE2_SIZE - 1) % 2048) + 13 jne not_grldr #; je grldr_real_start /* yes. boot it! */ #; /* it is not our grldr image, return and use MBR-helper. */ #; #;4: #; //jmp grldr_real_start #; popw %ds #; ret grldr_real_start: #; FAT_12_16 no longer be used. So comment out. #;je 1f /* jc 1f */ #;//ZF=0 /* CF cleared, so we are coming from FAT_12_16 */ #;popw %dx /* discard the cluster number */ #;popw %dx /* this is our boot_drive/boot_partition */ #;1: #; The partition number for no-emulation-mode bootable CDROM will be #; set to 0xFF later(in common.c). So comment out. #;cli #;movw %cs, %ax #;cmpw $0x1000, %ax #;jne 1f #; #;/* CS=0x1000, may be booted from ext2 or no-emulation-mode CDROM */ #; #;cmpw $0x1000, %di #;jne 2f #;cmpw $0x7c00, %bp #;jne 2f #;movw %es, %ax #;cmpw $0x1000, %ax #;jbe 2f #;cmpw $0x7c00, %si #;jbe 2f #;movl %edx, %eax #;shrl $16, %eax #;jnz 2f #;jecxz 1f // booted from ext2 partition #;2: #;// booted from no-emulation-mode bootable CDROM #;movb $0xff, %dh // partition 0xff means whole drive(for CDROM) #; #; if needed, 0xfe can be used as an indicator #; #; here for the bootable CDROM and changed to #; #; 0xff later. #;1: #; #;//if not booted from CDROM, don't touch the boot partition number(dh) cli xorw %ax, %ax movw %ax, %ss movw $0x0400, %sp /* tmp use real-mode IDT as stack */ movw %cs, %bp /* save CS to BP */ call 1f 1: popw %bx /* BX=Instruction Pointer of 1b */ subw $(1b - _start1), %bx movw %bx, %cx shrw $4, %bx addw %bp, %bx pushw %bx /* new CS */ andw $0x000f, %cx addw $(1f - _start1), %cx pushw %cx /* new IP */ lret 1: pushw %cs popw %ds /* CS=DS=BX, CS:0000 = _start1 */ addw $((pre_stage2_start - _start1) >> 4), %bx /* BX:0000 = pre_stage2_start */ cmpw $0x820, %bx jb 2f movw $((0x8200 - (pre_stage2_start - _start1) - 0x400) >> 4), %cx /* Now CS(=DS) >= CX+0x40 */ movw %cx, %es xorw %di, %di xorw %si, %si ///////////////////////////////////////////////////////////// // // CS // DS 0x820 BX // _start1---------------pre_stage2_start // CX+0x40---------------0x820 // CX // ES // ///////////////////////////////////////////////////////////// movw $0x200, %cx /* move 2 sectors */ cld repz movsw pushw %es /* ES:0000 = _start */ pushw $(1f - _start) lret /* CS=ES, CS:0000 = _start1 */ 1: /* move BX:0000 to 0820:0000 upward since BX >= 0x820 */ cld movw %bx, %ds movw $0x820, %bx movw %bx, %es xorw %si, %si xorw %di, %di movw $6, %bx /* 64K pages: 0x20000 - 0x7ffff */ 1: movw $0x8000, %cx repz movsw movw %ds, %ax addw $0x1000, %ax movw %ax, %ds movw %es, %ax addw $0x1000, %ax movw %ax, %es decw %bx jnz 1b jmp 3f 2: /* move BX:0000 to 0820:0000 downward since BX < 0x820 */ std addw $0x7000, %bx movw %bx, %ds movw $0x7820, %bx movw %bx, %es movw $0xfffe, %si movw %si, %di movw $8, %bx /* 64K pages: 0x08200 - 0x881ff */ 1: movw $0x8000, %cx repz movsw movw %ds, %ax subw $0x1000, %ax movw %ax, %ds movw %es, %ax subw $0x1000, %ax movw %ax, %es decw %bx jnz 1b cld 3: /* put the config file name */ xorw %ax, %ax movw %ax, %es movw %ax, %ds xorl %ebp, %ebp movb %dh, 0x820A /* this is the boot partition number */ #; clear saved_entryno so that force_cdrom_as_boot_device be cleared #; later in common.c movl %ebp, 0x820C /* EBP=0, clear saved_entryno */ movw $0x0010, %cx /* set max length of grub version string */ movw $0x8212, %di /* version string */ cld /* AL is already 0. Locate the end of version string */ repnz scasb /* find the location of the default config file name */ jcxz 1f /* failed, will not use the default config file name */ movw $0x4e, %cx /* max length of config file name */ movw %cs, %si /* CS:0000 = _start1 */ shlw $4, %si /* 0000:SI = _start1 */ addw $(default_config_file - _start1), %si //movw $(default_config_file + 0x8200 - pre_stage2_start), %si cld repz movsb /* move file name to the config-file field of stage2 */ 1: movw $0x0003, %ax /* set display mode: 80*25 color text */ int $0x10 xorw %bx, %bx movw $(launch_pre_stage2 - _start1), %si call print_message /* CS:SI points to message string */ xorw %ax, %ax movw %ax, %ss movw $0x2000, %sp sti ljmp $0, $0x8200 launch_pre_stage2: .ascii "\r\n\r\nBooting GRLDR...\r\n" .byte 0 /* mark the end of ascii zero string */ default_config_file: //#ifndef PRESET_MENU_STRING .ascii "/menu.lst" //#else // .ascii "[default menu is disabled]" //#endif .byte 0 /* mark the end of ascii zero string */ #endif /* ! defined(GRLDR_MBR) && (! defined(GRLDR_INSTALL)) */ . = _start1 + 0x400 #define ALTERNATIVE_KERNEL /* * The following is based on FreeDOS, modified heavily by Tinybit in Feb, 2004 * * Merges LBA and CHS boot sectors to ONE FAT32 boot sector! * * Memory layout for GRLDR FAT32 single stage boot process: * * ... * |-------| 1FE0:7E00 * |BOOTSEC| (GRUB does not use this relocation area) * |RELOC. | (overwritten by kernel loaded) * |-------| 1FE0:7C00 * ... * |-------| * |KERNEL | (overwrites bootsec reloc.) * |LOADED | (holds 1 sector directory buffer before kernel load) * |-------| 2000:0000 * ... * |-------| 0000:7E00 * |BOOTSEC| GRUB always run inside this sector, * |ORIGIN | no relocation. * |-------| 0000:7C00 * ... * |-------| 0060:0200 * | FAT | (only 1 sector buffered) * |-------| 0060:0000 * ... * */ /* ; This is an LBA-enabled FreeDOS FAT32 boot sector (single sector!). ; You can use and copy source code and binaries under the terms of the ; GNU Public License (GPL), version 2 or newer. See www.gnu.org for more. ; Based on earlier work by FreeDOS kernel hackers, modified heavily by ; Eric Auer and Jon Gentle in 7 / 2003. ; ; Features: Uses LBA and calculates all variables from BPB/EBPB data, ; thus making partition move / resize / image-restore easier. FreeDOS ; can boot from FAT32 partitions which start > 8 GB boundary with this ; boot sector. Disk geometry knowledge is not needed for booting. ; ; Windows uses 2-3 sectors for booting (sector stage, statistics sector, ; filesystem stage). Only using 1 sector for FreeDOS makes multi-booting ; of FreeDOS and Windows on the same filesystem easier. ; ; Requirements: LBA BIOS and 386 or better CPU. Use the older CHS-only ; boot sector if you want FAT32 on really old PCs (problems: you cannot ; boot from > 8 GB boundary, cannot move / resize / ... without applying ; SYS again if you use the CHS-only FAT32 boot sector). ; ; FAT12 / FAT16 hints: Use the older CHS-only boot sector unless you ; have to boot from > 8 GB. The LBA-and-CHS FAT12 / FAT16 boot sector ; needs applying SYS again after move / resize / ... a variant of that ; boot sector without CHS support but with better move / resize / ... ; support would be good for use on LBA harddisks. ; Memory layout for the FreeDOS FAT32 single stage boot process: ; ... ; |-------| 1FE0:7E00 ; |BOOTSEC| ; |RELOC. | ; |-------| 1FE0:7C00 ; ... ; |-------| 2000:0200 ; | FAT | (only 1 sector buffered) ; |-------| 2000:0000 ; ... ; |-------| 0000:7E00 ; |BOOTSEC| overwritten by the kernel, so the ; |ORIGIN | bootsector relocates itself up... ; |-------| 0000:7C00 ; ... ; |-------| ; |KERNEL | maximum size 134k (overwrites bootsec origin) ; |LOADED | (holds 1 sector directory buffer before kernel load) ; |-------| 0060:0000 ; ... */ #define BOOTGRUB /* undef this if compiled for loading FreeDOS */ //#undef BOOTGRUB #ifdef BOOTGRUB #define LOADSEG 0x2000 #define FATSEG 0x0060 #else #define LOADSEG 0x0060 #define FATSEG 0x2000 #endif Entry_32: jmp 1f . = Entry_32 + 0x02 /* The default mode is CHS. This is for maximum compatiblity with * small-sized disks, e.g., floppies. * * Valid values are 0x90 for CHS mode, or 0x0e for LBA mode. * * If the BIOS int13 supports LBA, this byte can be safely set to 0x0e. * * Some USB BIOSes might have bugs when using CHS mode, so the format * program should set this byte to 0x0e. It seems that (generally) all * USB BIOSes have LBA support. * * If the format program does not know whether the BIOS has LBA * support, it may operate this way: * * if (partition_start + total_sectors_in_partition) exceeds the CHS * addressing ability(especially when it is greater than 1024*256*63), * the caller should set this byte to 0x0e, otherwise, set to 0x90. */ .byte 0x90 /* for CHS. Another possible value is 0x0e for LBA */ . = Entry_32 + 0x03 #ifdef BOOTGRUB .ascii "GRLDR " /* OEM name string (of OS which formatted the disk). */ #endif . = Entry_32 + 0x0b .word 0x200 /* bytes per sector. Must be 512 */ . = Entry_32 + 0x0d /* Sectors per cluster. Valid values are 1, 2, 4, 8, 16, 32, 64 and 128. * But a cluster size larger than 32K should not occur. */ .byte 1 /* sectors per cluster */ . = Entry_32 + 0x0e /* Reserved sectors(number of sectors before the first FAT, * including the boot sector), usually 1. */ .word 1 /* reserved sectors */ . = Entry_32 + 0x10 /* Number of FATs(nearly always 2). */ .byte 2 /* number of FATs */ . = Entry_32 + 0x11 /* (Maximum number of root directory entries)Must be 0. */ .word 0 /* Max dir entries for FAT12/FAT16 */ . = Entry_32 + 0x13 /* (Total number of sectors for small disks only)Must be 0. */ .word 0 /* total sectors for FAT12/FAT16 */ . = Entry_32 + 0x15 /* Media descriptor byte, pretty meaningless now. */ .byte 0xf8 /* media descriptor */ . = Entry_32 + 0x16 /* (Sectors per FAT)Must be 0. */ .word 0 /* sectors per FAT for FAT12/FAT16 */ . = Entry_32 + 0x18 .word 18 /* sectors per track */ . = Entry_32 + 0x1a .word 2 /* number of heads */ . = Entry_32 + 0x1c /* Number of hidden sectors (those preceding the boot sector). * Also referred to as the starting sector of the partition. * For floppies, it should be 0. */ .long 0 /* hidden sectors */ . = Entry_32 + 0x20 /* Total number of sectors in the filesystem. */ .long 0 /* total sectors for FAT32 */ . = Entry_32 + 0x24 /* FAT32 sectors per FAT. */ .long 0 . = Entry_32 + 0x28 /* If bit 7 is clear then all FATs are updated, otherwise bits 0-3 * give the current active FAT, all other bits are reserved. * This word is not used by grldr boot code. */ .word 0 . = Entry_32 + 0x2a /* High byte is major revision number, low byte is minor revision * number, currently both are 0. * This word is not used by grldr boot code. */ .word 0 . = Entry_32 + 0x2c /* Root directory starting cluster. */ .long 0 . = Entry_32 + 0x30 /* File system information sector number. * This word is not used by grldr boot code. */ .word 0 . = Entry_32 + 0x32 /* If non-zero this gives the sector which holds a copy of the * boot record, usually 6. * This word is not used by grldr boot code. */ .word 6 . = Entry_32 + 0x34 /* Reserved, 12 bytes, set to 0. */ .long 0 .long 0 .long 0 . = Entry_32 + 0x40 /* drive number of the boot device. * This byte is ignored for read. The program will write DL onto * this byte. The caller should set drive number in DL. * We assume all BIOSes pass correct drive number in DL. * That is to say, buggy BIOSes are not supported!! */ .byte 0 . = Entry_32 + 0x41 /* partition number of this filesystem in the boot drive. * This byte is ignored for read. The boot code will write partition * number onto this byte. See Entry + 0x5d below. */ .byte 0 . = Entry_32 + 0x42 /* Signature (must be 28h or 29h to be recognised by NT). */ .byte 0x29 /* extended boot signature for FAT12/FAT16 */ . = Entry_32 + 0x43 .long 0x0AC4AF63 /* volume serial number */ . = Entry_32 + 0x47 .ascii "NO NAME " /* volume label, 11 bytes. */ . = Entry_32 + 0x52 .ascii "FAT32 " /* filesystem ID, 8 bytes. */ /* ; bp is initialized to 7c00h ; %define bsOemName bp+0x03 ; OEM label (8) %define bsBytesPerSec bp+0x0b ; bytes/sector (dw) %define bsSecPerClust bp+0x0d ; sectors/allocation unit (db) %define bsResSectors bp+0x0e ; # reserved sectors (dw) %define bsFATs bp+0x10 ; # of fats (db) ; %define bsRootDirEnts bp+0x11 ; # of root dir entries (dw, 0 for FAT32) ; (FAT32 has root dir in a cluster chain) ; %define bsSectors bp+0x13 ; # sectors total in image (dw, 0 for FAT32) ; (if 0 use nSectorHuge even if FAT16) ; %define bsMedia bp+0x15 ; media descriptor: fd=2side9sec, etc... (db) ; %define sectPerFat bp+0x16 ; # sectors in a fat (dw, 0 for FAT32) ; (FAT32 always uses xsectPerFat) %define sectPerTrack bp+0x18 ; # sectors/track ; %define nHeads bp+0x1a ; # heads (dw) %define nHidden bp+0x1c ; # hidden sectors (dd) ; %define nSectorHuge bp+0x20 ; # sectors if > 65536 (dd) %define xsectPerFat bp+0x24 ; Sectors/Fat (dd) ; +0x28 dw flags (for fat mirroring) ; +0x2a dw filesystem version (usually 0) %define xrootClst bp+0x2c ; Starting cluster of root directory (dd) ; +0x30 dw -1 or sector number of fs.-info sector ; +0x32 dw -1 or sector number of boot sector backup ; (+0x34 .. +0x3f reserved) %define drive bp+0x40 ; Drive number bp+0x41 ; partition number for GRLDR %define fat_sector bp+0x44 ; last accessed FAT sector (dd) ; (overwriting unused bytes) %define fat_start bp+0x48 ; first FAT sector (dd) ; (overwriting unused bytes) %define data_start bp+0x4c ; first data sector (dd) ; (overwriting unused bytes) */ /* not used: [0x42] = byte 0x29 (ext boot param flag) * [0x43] = dword serial * [0x47] = label (padded with 00, 11 bytes) * [0x52] = "FAT32",32,32,32 (not used by Windows) * ([0x5a] is where FreeDOS parts start) */ . = Entry_32 + 0x5a 1: cli cld #ifdef BOOTGRUB . = Entry_32 + 0x5c /* the byte at offset 0x5d stores the real partition number for read. * the format program or the caller should set it to a correct value. * For floppies, it should be 0xff, which stands for whole drive. */ movb $0xff, %dh /* boot partition number */ cmpb $0xff, %dh /* is floppy? */ jne 1f movb $0, %dl /* yes, let drive number = 0 */ 1: #endif xorw %ax, %ax movw %ax, %ds movw $0x7c00, %bp #ifdef BOOTGRUB movw %ax, %es #else movw $0x1fe0, %ax movw %ax, %es movw %bp, %si /* move from 0000:7c00 */ movw %bp, %di /* move to 1fe0:7c00 */ movw $0x0100, %cx /* one sector to move */ repz movsw ljmp $0x1fe0, $(1f - Entry_32 + 0x7c00) 1: movw %ax, %ds #endif movw %ax, %ss /* stack and BP-relative moves up, too */ leaw -0x20(%bp), %sp sti movw %dx, 0x40(%bp) /* BIOS passes drive number in DL */ movb $0x41, %ah movw $0x55AA, %bx int $0x13 jc 1f /* No EBIOS */ cmpw $0xAA55, %bx jne 1f /* No EBIOS */ testb $1, %cl jz 1f /* No EBIOS */ /* EBIOS supported */ movb $0x42, (ebios_32 - 1 - Entry_32 + 0x7c00) 1: /* figure out where FAT and DATA area starts * (modifies EAX EDX, sets fat_start and data_start variables) */ xorl %eax, %eax movl %eax, 0x44(%bp) /* init buffer status */ /* first, find fat_start */ movw 0x0e(%bp), %ax /* reserved sectors */ addl 0x1c(%bp), %eax /* hidden sectors */ movl %eax, 0x48(%bp) /* first FAT sector */ movl %eax, 0x4c(%bp) /* first data sector, initial value */ /* next, find data_start */ movl 0x10(%bp), %eax /* number of fats, no movzbl needed: the 2 words after 0x10(%bp) are 0 for fat32 */ mull 0x24(%bp) /* sectors per fat (EDX=0) */ addl %eax, 0x4c(%bp) /* first DATA sector */ /* Searches for the file in the root directory. * Returns: EAX = first cluster of file */ movl 0x2c(%bp), %eax /* root dir cluster */ 1: pushl %eax /* save cluster */ call cluster_to_lba_32 /* EDX is sectors per cluster, EAX is sector number */ movw $(msg_BootError_32 - Entry_32 + 0x7c00), %si jc boot_error_32 /* EOC encountered */ 2: lesw (loadseg_off_32 - Entry_32)(%bp), %bx /* load to loadseg:0 */ call readDisk_32 xorw %di, %di /* Search for kernel file name, and find start cluster */ 3: movw $11, %cx movw $(filename_32 - Entry_32 + 0x7c00), %si repz cmpsb jz 1f /* note that di now is at dirent+11 */ addw $0x20, %di andw $-0x20, %di /* 0xffe0 */ cmp 0x0b(%bp), %di /* bytes per sector */ jnz 3b /* next directory entry */ decw %dx /* initially DX holds sectors per cluster */ jnz 2b /* loop over sectors in cluster */ popl %eax /* restore current cluster */ call next_cluster_32 jmp 1b /* read next cluster */ #ifndef ALTERNATIVE_KERNEL loadseg_off_32: .word 0 .word LOADSEG #endif 1: /* kernel directory entry is found */ pushw %es:(0x14-11)(%di) /* get cluster number HI */ pushw %es:(0x1a-11)(%di) /* get cluster number LO */ popl %eax /* convert to 32bit */ xorw %bx, %bx /* read kernel at ES:BX=LOADSEG:0 */ /* read kernel */ 2: pushl %eax call cluster_to_lba_32 /* EDX is sectors per cluster, EAX is sector number */ jnc 1f /* EOC encountered - done */ #ifdef BOOTGRUB movw 0x40(%bp), %dx /* boot_drive and boot_partition */ #else movb 0x40(%bp), %bl /* FreeDOS kernel uses BL, not DL, for drive */ #endif ljmp *(loadseg_off_32 - Entry_32)(%bp) 1: call readDisk_32 decw %dx /* initially DX holds sectors per cluster */ jnz 1b /* loop over sectors in cluster */ popl %eax call next_cluster_32 jmp 2b /* given a cluster number, find the number of the next cluster in * the FAT chain. Needs fat_start. * input: EAX - cluster * EDX = 0 * output: EAX - next cluster * EDX = undefined */ next_cluster_32: pushw %es /* pushw %di */ pushw %bx /* hi word of EBX never used */ #if 1 /* xorl %edx, %edx */ shll $2, %eax /* 32bit FAT */ movzwl 0x0b(%bp), %ebx /* bytes per sector */ divl %ebx /* residue is in EDX */ /* movw %dx, %di */ #else shll $2, %eax /* 32bit FAT */ ;xchgw %ax, %di /* movw %ax, %di */ movw %ax, %di ;shlw $2, %di /* 32bit FAT */ pushw %cx movw 0x0b(%bp), %bx /* bytes per sector */ bsfw %bx, %cx ;decw %cx ;decw %cx decw %bx andw %bx, %di /* mask to sector size */ shrl %cl, %eax popw %cx #endif addl 0x48(%bp), %eax /* add the first FAT sector number. EAX is absolute sector number now */ movw $FATSEG, %bx movw %bx, %es xorw %bx, %bx cmpl 0x44(%bp), %eax /* is it the last accessed and already buffered FAT sector? */ jz 1f movl %eax, 0x44(%bp) /* mark sector EAX as buffered */ call readDisk_32 /* read sector EAX to buffer */ 1: #if 1 //.byte 0x67, 0x26, 0x80, 0x62, 0x03, 0x0f addr32 andb $0x0f, %es:3(%edx) /* mask out top 4 bits */ //.byte 0x67, 0x66, 0x26, 0x8b, 0x02 addr32 movl %es:(%edx), %eax /* read next cluster number */ #else andb $0x0f, %es:3(%di) /* mask out top 4 bits */ movl %es:(%di), %eax /* read next cluster number */ #endif popw %bx /* popw %di */ popw %es ret /* Convert cluster number to the absolute sector number * ... or return carry if EndOfChain! Needs data_start. * input: EAX - target cluster * output: EAX - absolute sector * EDX - [bsSectPerClust] (byte) * carry clear * (if carry set, EAX/EDX unchanged, end of chain) */ cluster_to_lba_32: cmpl $0x0ffffff8, %eax /* check End Of Chain */ cmc jb 1f /* carry is stored if EOC */ /* sector = (cluster-2) * clustersize + data_start */ decl %eax decl %eax movzbl 0x0d(%bp), %edx /* sectors per cluster */ pushw %dx /* only DX would change */ mull %edx /* EDX = 0 */ popw %dx addl 0x4c(%bp), %eax /* data_start */ /* here, carry is cleared (unless parameters are wrong) */ 1: ret /* Read a sector from disk, using LBA or CHS * input: EAX - 32-bit DOS sector number * ES:BX - destination buffer * (will be filled with 1 sector of data) * output: ES:BX points one byte after the last byte read. * EAX - next sector */ readDisk_32: pushal xorl %edx, %edx /* EDX:EAX = LBA */ pushl %edx /* hi 32bit of sector number */ pushl %eax /* lo 32bit of sector number */ pushw %es /* buffer segment */ pushw %bx /* buffer offset */ pushw $1 /* 1 sector to read */ pushw $16 /* size of this parameter block */ xorl %ecx, %ecx pushl 0x18(%bp) /* lo:sectors per track, hi:number of heads */ popw %cx /* ECX = sectors per track */ divl %ecx /* residue is in EDX */ /* quotient is in EAX */ incw %dx /* sector number in DL */ popw %cx /* ECX = number of heads */ pushw %dx /* push sector number into stack */ xorw %dx, %dx /* EDX:EAX = cylinder * TotalHeads + head */ divl %ecx /* residue is in EDX, head number */ /* quotient is in EAX, cylinder number */ xchgb %dl, %dh /* head number should be in DH */ /* DL = 0 */ popw %cx /* pop sector number from stack */ xchgb %al, %ch /* lo 8bit cylinder should be in CH */ /* AL = 0 */ shlb $6, %ah /* hi 2bit cylinder ... */ orb %ah, %cl /* ... should be in CL */ movw $0x201, %ax /* read 1 sector */ ebios_32: /* ebios_32 - 1 points to 0x02 that can be changed to 0x42 */ // cmpb $0x0e, 2(%bp) /* force LBA? */ // jnz 1f /* no, continue */ // movb $0x42, %ah /* yes, use extended disk read */ //1: movw %sp, %si /* DS:SI points to disk address packet */ movb 0x40(%bp), %dl /* hard disk drive number */ int $0x13 popaw /* remove parameter block from stack */ popal jc disk_error_32 /* disk read error, jc 1f if caller handles */ incl %eax /* next sector */ addw 0x0b(%bp), %bx /* bytes per sector */ jnc 1f /* 64K bound check */ pushw %dx movw %es, %dx addb $0x10, %dh /* add 1000h to ES */ /* here, carry is cleared */ movw %dx, %es popw %dx 1: /* carry stored on disk read error */ ret . = . - (. - readDisk_32)/91 msg_DiskReadError_32: .ascii "disk error\0" msg_BootError_32: .ascii "No " filename_32: #ifdef BOOTGRUB2 .ascii "G2LDR \0" #elif defined (BOOTGRUB) .ascii "GRLDR \0" #else .ascii "KERNEL SYS\0" #endif #ifdef ALTERNATIVE_KERNEL filename_end_32: . = Entry_32 + 0x1e8 loadseg_off_32: .word 0 .word LOADSEG . = Entry_32 + 0x1ec boot_image_ofs_32: .word (filename_32 - Entry_32)+(filename_end_32 - filename_32 - 1)*2048 #endif . = Entry_32 + 0x1ee disk_error_32: movw $(msg_DiskReadError_32 - Entry_32 + 0x7c00), %si boot_error_32: /* prints string DS:SI (modifies AX BX SI) */ //print_32: 1: lodsb (%si), %al /* get token */ //xorw %bx, %bx /* video page 0 */ movb $0x0e, %ah /* print it */ int $0x10 /* via TTY mode */ cmpb $0, %al /* end of string? */ jne 1b /* until done */ /* The caller will change this to * ljmp $0x9400, $(try_next_partition - _start1) */ 1: jmp 1b . = Entry_32 + 0x1fc .word 0, 0xAA55 /* Win9x uses all 4 bytes as magic value here */ . = Entry_32 + 0x200 . = _start1 + 0x600 //.arch i8086, nojumps .arch i186, nojumps /* * The following is based on FreeDOS, modified heavily by Tinybit in Feb, 2004 * * Merges FAT12 and FAT16 boot sectors to ONE FAT boot sector! * * Memory layout for GRLDR FAT single stage boot process: * * +--------+ * | | * |GRLDR | also used as max 128k FAT buffer * |LOADED | before GRLDR loading starts * |--------| 2000:0000 * | | * |--------| 0000:7E00 * |BOOTSECT| * |ORIGIN | * |--------| 0000:7C00 * | | * |--------| 0000:3000 * |CLUSTER | * |LIST | * |--------| 0000:2000 * | | * +--------+ */ /* ; ; File: ; boot.asm ; Description: ; DOS-C boot ; ; Copyright (c) 1997; ; Svante Frey ; All Rights Reserved ; ; This file is part of DOS-C. ; ; DOS-C is free software; you can redistribute it and/or ; modify it under the terms of the GNU General Public License ; as published by the Free Software Foundation; either version ; 2, or (at your option) any later version. ; ; DOS-C is distributed in the hope that it will be useful, but ; WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See ; the GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public ; License along with DOS-C; see the file COPYING. If not, ; write to the Free Software Foundation, 675 Mass Ave, ; Cambridge, MA 02139, USA. ; ; ; +--------+ 1FE0:7E00 ; |BOOT SEC| ; |RELOCATE| ; |--------| 1FE0:7C00 ; | | ; |--------| 1FE0:3000 ; | CLUSTER| ; | LIST | ; |--------| 1FE0:2000 ; | | ; |--------| 0000:7E00 ; |BOOT SEC| overwritten by max 128k FAT buffer ; |ORIGIN | and later by max 134k loaded kernel ; |--------| 0000:7C00 ; | | ; |--------| ; |KERNEL | also used as max 128k FAT buffer ; |LOADED | before kernel loading starts ; |--------| 0060:0000 ; | | ; +--------+ */ #ifdef BOOTGRUB #define LOADSEG_12_16 0x2000 #define FATBUF 0x2000 /* offset of temp buffer for FAT chain */ #else #define LOADSEG_12_16 0x0060 #define FATBUF 0x2000 /* offset of temp buffer for FAT chain */ #endif Entry_12_16: jmp 1f . = Entry_12_16 + 0x02 /* The default mode is CHS. This is for maximum compatiblity with * small-sized disks, e.g., floppies. * * Valid values are 0x90 for CHS mode, or 0x0e for LBA mode. * * If the BIOS int13 supports LBA, this byte can be safely set to 0x0e. * * Some USB BIOSes might have bugs when using CHS mode, so the format * program should set this byte to 0x0e. It seems that (generally) all * USB BIOSes have LBA support. * * If the format program does not know whether the BIOS has LBA * support, it may operate this way: * * if (partition_start + total_sectors_in_partition) exceeds the CHS * addressing ability(especially when it is greater than 1024*256*63), * the caller should set this byte to 0x0e, otherwise, set to 0x90. */ .byte 0x90 /* for CHS. Another possible value is 0x0e for LBA */ . = Entry_12_16 + 0x03 #ifdef BOOTGRUB .ascii "GRLDR " #endif . = Entry_12_16 + 0x0b .word 0x200 /* bytes per sector */ . = Entry_12_16 + 0x0d .byte 1 /* sectors per cluster */ . = Entry_12_16 + 0x0e .word 1 /* reserved sectors */ . = Entry_12_16 + 0x10 .byte 2 /* number of FATs */ . = Entry_12_16 + 0x11 .word 224 /* Max dir entries */ . = Entry_12_16 + 0x13 .word 2880 /* total sectors in the filesystem */ . = Entry_12_16 + 0x15 .byte 0xf0 /* media descriptor */ . = Entry_12_16 + 0x16 .word 9 /* sectors per FAT */ . = Entry_12_16 + 0x18 .word 18 /* sectors per track */ . = Entry_12_16 + 0x1a .word 2 /* number of heads */ . = Entry_12_16 + 0x1c .long 0 /* hidden sectors */ . = Entry_12_16 + 0x20 .long 0 /* total sectors for large partitions */ . = Entry_12_16 + 0x24 /* drive number of the boot device. * This byte is ignored for read. The program will write DL onto * this byte. The caller should set drive number in DL. * We assume all BIOSes pass correct drive number in DL. * That is to say, buggy BIOSes are not supported!! */ .byte 0 . = Entry_12_16 + 0x25 /* partition number of this filesystem in the boot drive. * This byte is ignored for read. The boot code will write partition * number onto this byte. See Entry_12_16 + 0x41 below. */ .byte 0 . = Entry_12_16 + 0x26 .byte 0x29 /* extended boot signature */ . = Entry_12_16 + 0x27 .long 0x0AC4AF63 /* volume serial number */ . = Entry_12_16 + 0x2b .ascii "NO NAME " /* volume label */ . = Entry_12_16 + 0x36 .ascii "FAT12 " /* filesystem ID */ /* ; bp is initialized to 7c00h %define bsOemName bp+0x03 ; OEM label %define bsBytesPerSec bp+0x0b ; bytes/sector %define bsSecPerClust bp+0x0d ; sectors/allocation unit %define bsResSectors bp+0x0e ; # reserved sectors %define bsFATs bp+0x10 ; # of fats %define bsRootDirEnts bp+0x11 ; # of root dir entries %define bsSectors bp+0x13 ; # sectors total in image %define bsMedia bp+0x15 ; media descrip: fd=2side9sec, etc... %define sectPerFat bp+0x16 ; # sectors in a fat %define sectPerTrack bp+0x18 ; # sectors/track %define nHeads bp+0x1a ; # heads %define nHidden bp+0x1c ; # hidden sectors %define nSectorHuge bp+0x20 ; # sectors if > 65536 %define drive bp+0x24 ; drive number bp+0x25 ; partition number for GRLDR %define extBoot bp+0x26 ; extended boot signature %define volid bp+0x27 %define vollabel bp+0x2b %define filesys bp+0x36 %define RootDirSecs bp+0x26 ; # of sectors root dir uses ; (overwriting unused bytes) %define fat_start bp+0x28 ; first FAT sector ; (overwriting unused bytes) %define root_dir_start bp+0x2c ; first root directory sector ; (overwriting unused bytes) %define data_start bp+0x30 ; first data sector ; (overwriting unused bytes) %define data_clusters bp+0x34 ; # of clusters in data area ; (overwriting unused bytes) bp+0x36 ; bytes per FAT( > 0x1800 means FAT16) ; (overwriting unused bytes) */ /* not used: [0x26] = byte 0x29 (ext boot param flag) * [0x27] = dword serial * [0x2b] = label (padded with 00, 11 bytes) * [0x36] = "FAT12" or "FAT16",32,32,32 (not used by Windows) * ([0x3e] is where FreeDOS parts start) */ . = Entry_12_16 + 0x3e 1: cli cld #ifdef BOOTGRUB . = Entry_12_16 + 0x40 /* the byte at offset 0x41 stores the real partition number for read. * the format program or the caller should set it to a correct value. * For floppies, it should be 0xff, which stands for whole drive. */ movb $0xff, %dh /* boot partition number */ cmpb $0xff, %dh /* is floppy? */ jne 1f movb $0, %dl /* yes, let drive number = 0 */ 1: #endif xorw %ax, %ax movw %ax, %ds movw $0x7c00, %bp #ifdef BOOTGRUB movw %ax, %es movw %ax, %ss /* stack and BP-relative moves up, too */ leaw -0x20(%bp), %sp sti movw %dx, 0x24(%bp) /* BIOS passes drive number in DL */ /* AX=0 */ // xchgw %ax, %dx /* let DX = 0 */ // xorw %cx, %cx /* CX = 0 */ #else movw %bp, %si /* move from 0000:7c00 */ movw %bp, %di /* move to 1fe0:7c00 */ movb %dl, 0x24(%si) /* BIOS passes drive number in DL */ // xchgw %ax, %dx /* let DX = 0 */ movw $0x1fe0, %ax movw %ax, %es movw $0x0100, %cx /* one sector to move */ repz movsw /* CX = 0 */ ljmp $0x1fe0, $(1f - Entry_12_16 + 0x7c00) 1: movw %ax, %ds movw %ax, %ss /* stack and BP-relative moves up, too */ leaw -0x20(%bp), %sp sti /* AX=0x1fe0 */ #endif movb $0x41, %ah movw $0x55AA, %bx int $0x13 jc 1f /* No EBIOS */ cmpw $0xAA55, %bx jne 1f /* No EBIOS */ testb $1, %cl jz 1f /* No EBIOS */ /* EBIOS supported */ movb $0x42, (ebios_12_16 - 1 - Entry_12_16 + 0x7c00) 1: // xorw %cx, %cx xorw %ax, %ax /* GET DRIVE PARMS: Calculate start of some disk areas */ movw 0x1c(%bp), %si /* number of hidden sectors(lo) */ movw 0x1e(%bp), %di /* number of hidden sectors(hi) */ addw 0x0e(%bp), %si /* number of reserved sectors */ adcw %ax, %di /* DI:SI = first FAT sector */ /* AX = 0 */ movw %si, 0x28(%bp) /* FAT start sector(lo) */ movw %di, 0x2a(%bp) /* FAT start sector(hi) */ //xchgw %ax, %dx /* let AX = 0 */ movb 0x10(%bp), %al /* number of FATs */ /* cbw */ mulw 0x16(%bp) /* sectors per FAT */ /* DX:AX = total number of FAT sectors */ /* DX = 0 since no too many FAT sectors */ addw %ax, %si adcw %dx, %di /* DI:SI = root directory start sector */ movw %si, 0x2c(%bp) /* root directory starting sector(lo) */ movw %di, 0x2e(%bp) /* root directory starting sector(hi) */ /* Calculate how many sectors the root directory occupies */ movw 0x0b(%bp), %bx /* bytes per sector */ movb $5, %cl /* divide BX by 32 */ shrw %cl, %bx /* BX = directory entries per sector */ movw 0x11(%bp), %ax /* max number of root dir entries */ /* xorw %dx, %dx */ /* assuming DX = 0 */ divw %bx /* AX = sectors per root directory */ /* DX = 0 since normally no residue */ movw %ax, 0x26(%bp) /* number of sectors the root dir occupies */ addw %ax, %si /* DI:SI = first data sector */ adcw %dx, %di /* assuming DX = 0 */ movw %si, 0x30(%bp) /* data starting sector(lo) */ movw %di, 0x32(%bp) /* data starting sector(hi) */ #ifdef USE_TOTAL_CLUSTERS movw 0x13(%bp), %cx /* total sectors(small) */ jcxz 1f movw %cx, 0x20(%bp) /* total sectors(large)(lo) */ movw %dx, 0x22(%bp) /* total sectors(large)(hi), assuming DX = 0 */ 1: movw 0x20(%bp), %ax /* total sectors(large) */ movw 0x22(%bp), %bx addw 0x1c(%bp), %ax /* number of hidden sectors */ adcw 0x1e(%bp), %bx subw %si, %ax /* data starting sector */ sbbw %di, %bx /* BX:AX = total sectors in the data area */ movb 0x0d(%bp), %dl /* sectors per cluster(DH=0) */ xchgw %bx, %dx /* DX:AX = total sectors in the data area */ /* BX = sectors per cluster */ divw %bx /* AX = total clusters in the data area */ movw %ax, 0x34(%bp) /* total clusters in the data area */ #else movw $0xffff, 0x36(%bp) movw 0x16(%bp), %ax /* sectors per FAT */ mulw 0x0b(%bp) /* bytes per sector */ jc 1f movw %ax, 0x36(%bp) 1: #endif /* Searches for the file in the root directory * * Returns: * AX = first cluster of file */ /* First, read the whole root directory into the temporary buffer */ movw 0x2c(%bp), %ax /* root directory starting sector(lo) */ movw 0x2e(%bp), %dx /* root directory starting sector(hi) */ movw 0x26(%bp), %di /* number of sectors the root dir occupies */ lesw (loadseg_off_12_16 - Entry_12_16)(%bp), %bx /* ES:BX = loadseg:0 */ call readDisk_12_16 lesw (loadseg_off_12_16 - Entry_12_16)(%bp), %di /* ES:DI = loadseg:0 */ /* Search for kernel file name, and find start cluster */ 1: movw $11, %cx movw $(filename_12_16 - Entry_12_16 + 0x7c00), %si pushw %di repz cmpsb popw %di movw %es:0x1a(%di), %ax /* get cluster number from dir entry */ jz 1f addw $0x20, %di /* go to next directory entry */ cmpb %ch, %es:(%di) /* if the first byte of the name is 0, */ /* there is no more files in the directory */ /* assuming CH = 0 */ jnz 1b movw $(msg_BootError_12_16 - Entry_12_16 + 0x7c00), %si jmp boot_error_12_16 /* fail if not found */ #ifndef ALTERNATIVE_KERNEL loadseg_off_12_16: .word 0 loadseg_seg_12_16: .word LOADSEG_12_16 #endif 1: pushw %ax /* store first cluster number */ /* CX = 0 */ /* Reads the FAT chain and stores it in a temporary buffer in the first * 64KB. The FAT chain is stored an array of 16-bit cluster numbers, * ending with 0. * * The file must fit in conventional memory, so it can't be larger than * 640KB. The sector size must be at least 512 bytes, so the FAT chain * can't be larger than around 3KB. * * Call with: AX = first cluster in chain */ /* Load the complete FAT into memory. The FAT can't be larger * than 128 kb, so it should fit in the temporary buffer. */ lesw (loadseg_off_12_16 - Entry_12_16)(%bp), %bx /* ES:BX = loadseg:0 */ movw 0x16(%bp), %di /* sectors per FAT */ movw 0x28(%bp), %ax /* FAT start sector(lo) */ movw 0x2a(%bp), %dx /* FAT start sector(hi) */ call readDisk_12_16 popw %ax /* restore first cluster number */ /* Set ES:DI to the temporary storage for the FAT chain */ pushw %ds popw %es movw (loadseg_seg_12_16 - Entry_12_16)(%bp), %ds movw $FATBUF, %di 2: stosw /* store cluster number */ movw %ax, %si /* SI = cluster number */ addw %si, %si /* multiply cluster number by two */ movw (loadseg_seg_12_16 - Entry_12_16)(%bp), %dx /* segment for FAT16 */ jnc 1f addb $0x10, %dh /* overflow. Add 0x1000 to segment value */ 1: #ifdef USE_TOTAL_CLUSTERS cmpw $0x0ff7, 0x34(%bp) /* total clusters in the data area */ #else cmpw $0x1801, 0x36(%bp) /* bytes per FAT */ #endif jnb 3f /* This is a FAT12 disk */ addw %ax, %si /* multiply cluster number by 3 ... */ shrw $1, %si /* ... and divide by 2 */ lodsw /* If the cluster number was even, the cluster value is now in * bits 0-11 of AX. If the cluster number was odd, the cluster * value is in bits 4-15, and must be shifted right 4 bits. If * the number was odd, CF was set in the last shift instruction. */ jnc 1f movb $4, %cl shrw %cl, %ax 1: andb $0x0f, %ah /* mask off the highest 4 bits */ cmpw $0x0ff7, %ax /* check for EOF */ jmp 4f 3: /* This is a FAT16 disk. The maximal size of a 16bit FAT * is 128KB, so it may not fit within a single 64KB segment */ movw %dx, %ds /* DS:SI points to next cluster */ lodsw /* AX = next cluster */ cmpw $0xfff7, %ax /* check for EOF */ 4: jbe 2b /* continue if not EOF */ /* Mark end of FAT chain with 0, so we have a single * EOF marker for both FAT12 and FAT16 systems. */ xorw %ax, %ax stosw pushw %cs popw %ds /* Loads the file into memory, one cluster at a time */ lesw (loadseg_off_12_16 - Entry_12_16)(%bp), %bx /* ES:BX = loadseg:0 */ movw $FATBUF, %si /* set DS:SI to the FAT chain */ 2: lodsw /* AX = next cluster to read */ orw %ax, %ax jnz 1f /* EOC encountered - done */ #ifdef BOOTGRUB movw 0x24(%bp), %dx /* boot_drive and boot_partition */ #else movb 0x24(%bp), %bl /* FreeDOS kernel uses BL, not DL, for drive */ #endif ljmp *(loadseg_off_12_16 - Entry_12_16)(%bp) /* boot it! */ 1: decw %ax /* cluster numbers start with 2 */ decw %ax movw 0x0d(%bp), %di /* sectors per cluster */ andw $0xff, %di /* DI = sectors per cluster */ mulw %di addw 0x30(%bp), %ax /* data starting sector(lo) */ adcw 0x32(%bp), %dx /* data starting sector(hi) */ /* DX:AX = first sector to read */ call readDisk_12_16 jmp 2b /* read next cluster */ /* Reads a number of sectors into memory. * * Call with: DX:AX = 32-bit DOS sector number * DI = number of sectors to read * ES:BX = destination buffer * * Returns: CF set on error * ES:BX points one byte after the last byte read. * DX:AX = next sector number after read */ readDisk_12_16: 2: pushaw xorw %cx, %cx pushw %cx pushw %cx pushw %dx pushw %ax pushw %es /* buffer segment */ pushw %bx /* buffer offset */ incw %cx pushw %cx /* 1 sector to read */ movb $16, %cl pushw %cx /* size of this parameter block */ xchgw %ax, %cx /* save AX to CX */ /* * translate sector number to BIOS parameters * * LBA = sector-1 offset in track * + head * sectPerTrack offset in cylinder * + cyl * sectPerTrack * nHeads offset in platter * */ pushw %bx movw 0x18(%bp), %ax /* sectors per track */ movw %ax, %bx mulb 0x1a(%bp) /* nHeads, but maybe a word value 0x100 */ jnz 1f movb %bl, %ah /* nHeads=0x100, so AX=sectPerTrack*0x100 */ 1: xchgw %ax, %cx /* restore AX from CX, and save AX to CX */ /* DX:AX = LBA, CX = nHeads * sectPerTrack <= 256*63 */ divw %cx /* AX = cyl, DX = sector-1 + head * sectPerTrack */ xchgw %ax, %dx /* DX = cyl, AX = sector-1 + head * sectPerTrack */ divb %bl /* sectors per track */ /* DX = cyl, AL = head, AH = sector-1 */ #if 1 xchgb %al, %ah /* DX = cyl, AH = head, AL = sector-1 */ incw %ax /* DX = cyl, AH = head, AL = sector */ xchgw %ax, %dx /* AX = cyl, DH = head, DL = sector */ xchgw %ax, %cx /* CX = cyl, DH = head, DL = sector */ xchgb %cl, %ch /* set cyl number low 8 bits in CH */ rorb $1, %cl /* move cyl high bits into bits 7-6 */ rorb $1, %cl /* (assumes top = 0) */ orb %dl, %cl /* merge sector into cylinder */ #else movw %dx, %cx /* CX = cyl, AL = head, AH = sector-1 */ /* * the following manipulations are necessary in order to properly place * parameters into registers. * CH = cylinder number low 8 bits * CL<7-6> = cylinder high two bits * CL<5-0> = sector */ movb %al, %dh /* save head into DH for BIOS */ xchgb %cl, %ch /* set cyl number low 8 bits in CH */ rorb $1, %cl /* move cyl high bits into bits 7-6 */ rorb $1, %cl /* (assumes top = 0) */ incb %ah /* AH = sector number */ orb %ah, %cl /* merge sector into cylinder */ #endif popw %bx movw $0x0201, %ax /* read 1 sector */ ebios_12_16: /* ebios_12_16 - 1 points to 0x02 that can be changed to 0x42 */ // cmpb $0x0e, 2(%bp) /* force LBA? */ // jnz 1f /* no, continue */ // movb $0x42, %ah /* yes, use extended disk read */ //1: movw %sp, %si /* DS:SI points to disk address packet */ movb 0x24(%bp), %dl /* drive number */ int $0x13 // stc #; only for testing the buggy Virtual PC popaw /* remove parameter block from stack */ popaw jc disk_error_12_16 /* disk read error, jc 1f if caller handles */ incw %ax /* next sector */ jnz 1f incw %dx 1: addw 0x0b(%bp), %bx /* bytes per sector */ jnc 1f /* 64K bound check */ pushw %dx movw %es, %dx addb $0x10, %dh /* add 1000h to ES */ /* here, carry is cleared */ movw %dx, %es popw %dx 1: decw %di jnz 2b /* carry stored on disk read error */ ret . = . - (. - readDisk_12_16)/99 msg_DiskReadError_12_16: .ascii "disk error\0" msg_BootError_12_16: .ascii "No " filename_12_16: #ifdef BOOTGRUB2 .ascii "G2LDR \0" #elif defined (BOOTGRUB) .ascii "GRLDR \0" #else .ascii "KERNEL SYS\0" #endif #ifdef ALTERNATIVE_KERNEL filename_end_12_16: . = Entry_12_16 + 0x1e8 loadseg_off_12_16: .word 0 loadseg_seg_12_16: .word LOADSEG_12_16 . = Entry_12_16 + 0x1ec boot_image_ofs_12_16: .word (filename_12_16 - Entry_12_16)+(filename_end_12_16 - filename_12_16 - 1)*2048 #endif . = Entry_12_16 + 0x1ee disk_error_12_16: movw $(msg_DiskReadError_12_16 - Entry_12_16 + 0x7c00), %si boot_error_12_16: /* prints string DS:SI (modifies AX BX SI) */ //print_12_16: 1: lodsb (%si), %al /* get token */ //xorw %bx, %bx /* video page 0 */ movb $0x0e, %ah /* print it */ int $0x10 /* via TTY mode */ cmpb $0, %al /* end of string? */ jne 1b /* until done */ /* The caller will change this to * ljmp $0x9400, $(try_next_partition - _start1) */ 1: jmp 1b . = Entry_12_16 + 0x1fc .word 0, 0xAA55 /* Win9x uses all 4 bytes as magic value here */ . = Entry_12_16 + 0x200 . = _start1 + 0x800 .arch i486, nojumps /* #; Ext2 boot sector for GRLDR */ #define DEBUG call debug_print #undef DEBUG //. = _start1 + 0x800 Entry_ext2: jmp 1f . = Entry_ext2 + 0x02 /* The default mode is CHS. This is for maximum compatiblity with * small-sized disks, e.g., floppies. * * Valid values are 0x02 for CHS mode, or 0x42 for LBA mode. * * If the BIOS int13 supports LBA, this byte can be safely set to 0x42. * * Some USB BIOSes might have bugs when using CHS mode, so the format * program should set this byte to 0x42. It seems that (generally) all * USB BIOSes have LBA support. * * If the format program does not know whether the BIOS has LBA * support, it may operate this way: * * if (partition_start + total_sectors_in_partition) exceeds the CHS * addressing ability(especially when it is greater than 1024*256*63), * the caller should set this byte to 0x42, otherwise, set to 0x02. */ .byte 0x02 /* for CHS. Another possible value is 0x42 for LBA */ . = Entry_ext2 + 0x03 #if 0 .ascii "ext2 grldr" #else msg_DiskReadError_ext2: .ascii "I/O error\0" #endif . = Entry_ext2 + 0x0d /* sectors per block. Valid values are 2, 4, 8, 16, 32. */ .byte 2 . = Entry_ext2 + 0x0e /* bytes per block. * Valid values are 0x400, 0x800, 0x1000, 0x2000, 0x4000. */ .word 1024 /* bytes per block, at most 16K */ . = Entry_ext2 + 0x10 /* pointers in pointers-per-block blocks, that is, number of blocks * covered by a double-indirect block. * Valid values are 0x10000, 0x40000, 0x100000, 0x400000, 0x1000000. */ .long 0x10000 /* number of blocks covered by double-indirect block */ /* low word=0 */ . = Entry_ext2 + 0x14 /* pointers per block, that is, number of blocks covered by an indirect * block. Valid values are 0x100, 0x200, 0x400, 0x800, 0x1000. */ .long 0x100 /* high word=0, low byte=0 */ . = Entry_ext2 + 0x18 /* this is default for 1.44M floppy, the caller should set it to * a correct value */ .word 18 /* sectors per track */ . = Entry_ext2 + 0x1a /* this is default for 1.44M floppy, the caller should set it to * a correct value */ .word 2 /* number of heads */ . = Entry_ext2 + 0x1c /* this is default for 1.44M floppy, the caller should set it to * a correct value */ .long 0 /* hidden sectors */ . = Entry_ext2 + 0x20 /* total sectors in the filesystem(or in the partition). * This value is informative. The code does not use it. */ /* this is default for 1.44M floppy, the caller should set it to * a correct value */ .long 2880 . = Entry_ext2 + 0x24 /* This byte is ignored for read. The program will write DL onto * this byte. The caller should set drive number in DL. * We assume all BIOSes pass correct drive number in DL. * That is to say, buggy BIOSes are not supported!! */ .byte 0 /* drive number */ . = Entry_ext2 + 0x25 /* this is default for floppies, the caller should set it to * a correct value for hard-drive partitions */ .byte 0xff /* partition number, 0xff for whole drive */ . = Entry_ext2 + 0x26 .word 0x80 /* inode size */ . = Entry_ext2 + 0x28 /* this is default for 1.44M floppy, the caller should set it to * a correct value */ .long 2048 /* s_inodes_per_group */ . = Entry_ext2 + 0x2c /* block number for group descriptors = s_first_data_block + 1. * Valid values are 2 for 1024-byte blocks, and 1 for otherwise. */ /* this is default for 1.44M floppy, the caller should set it to * a correct value */ .long 2 /* block number for group descriptors */ . = Entry_ext2 + 0x30 1: cld /* 0xFC */ xorw %ax, %ax /* 0x31, 0xC0; CF=0, ZF=1 */ /* this byte `nop' will be changed to `cwd' by bootlace for floppy */ nop /* 0x90=nop, 0x99=cwd */ /* cwd will set DL=0 forcibly for floppy A: */ movw %ax, %ss /* constant SS=0 */ movw $0x7c00, %sp movw %sp, %bp /* constant BP=0x7c00 */ movw %ax, %ds /* constant DS=0 */ pushw %ax /* 0x0000 at 0000:7bfe */ movw $0x1000, %bx pushw %bx /* 0x1000 at 0000:7bfc */ pushw %ax /* 0x0000 at 0000:7bfa */ /* SP=0x7bfa */ /* the 6 bytes in the stack are used by read_block(): * 0000 ---- -2(%bp) * 1000 ---- -4(%bp) * 0000 ---- -6(%bp) * Don't touch them! */ movb %dl, 0x24(%bp) /* BIOS passes drive number in DL */ movb $0x41, %ah movw $0x55AA, %bx int $0x13 #if 0 jnc 1f /* No EBIOS */ movb $0x02, (ebios_ext2 - 1 - Entry_ext2 + 0x7c00) #else jc 1f #; No EBIOS //testb $1, %cl //jz 1f #; No EBIOS #if 0 /* gcc-4.0.1 does not generate 2-byte code. */ rcrb $1, %cl #; also can be rorb $1, %cl #else .byte 0xD0, 0xD9 #; ror cl: D0 C9 #endif jnc 1f #; No EBIOS movb $0x42, (ebios_ext2 - 1 - Entry_ext2 + 0x7c00) #endif 1: xorl %eax, %eax /* CF=0, ZF=1 */ #if 0 /* the INC touches ZF flag, so use MOV instead */ incw %ax incw %ax /* EAX=2=inode number for root dir */ #else /* MOV keeps all flags untouched, so it is better than INC */ movb $2, %al /* EAX=2=inode number for root dir */ #endif /* CF=0, ZF=1 because MOV and PUSH do not touch Flags */ /* read root dir to 0000:1000, and grldr to 1000:0000 */ 4: /* EAX holds the inode number: for root dir or grldr */ /* These 3 PUSHes is intended to place 1000:0000 onto the stack for * grldr. For root dir, the stack is not used since CF is cleared. * Although there is no corresponding POPs, this is safe enough * because the program comes here only twice: the first is for * the root dir, and the second is for grldr. * * For root dir, CF=0 and ZF=1. For grldr, CF=1. */ pushw %di /* 0x1000, see "jz 4b" below. */ pushw %ss /* 0x0000 */ pushfw /* SP=0x7bf4 for root dir, or 0x7bee for grldr */ decl %eax /* EAX=(inode - 1) */ /* inode numbers are far less than 0x7fffffff, so it is safe to * initialise EDX with CDQ */ cdq /* let EDX=0 */ divl 0x28(%bp) /* s_inodes_per_group */ /* EAX=group number */ pushl %edx /* EDX=inode number in the group */ /* group numbers are far less than 0x7fffffff, so it is safe to * initialise EDX with CDQ */ cdq /* let EDX=0 */ shll $5, %eax /* EAX=relative displacement of the group descriptor */ divl 0x0e(%bp) /* bytes per block */ /* EAX=relative block number for the group descriptor */ /* DX=displacement in the block */ /* EDX high=0 */ pushw %dx /* we don't care about EDX high word, because it is 0 */ addl 0x2c(%bp), %eax /* EAX=absolute block number for the group descriptor */ /* CF=0, ZF=0 */ call read_block /* 0000:1000 points to the block data containing the group descriptor */ /* ES changed and > 0, BX=0x1000 */ /* ECX=EDX=0 */ /* CF=0, ZF=0 */ popw %si /* DS:[BX+SI] points to the group descriptor */ /* DS:[BX+SI+8] points to the starting block number of the group inode table */ popl %eax /* inode number in the group */ // shll $7, %eax /* inode struct size = 0x80 */ // /* EAX=relative displacement of the inode struct */ // /* EDX=0 */ movw 0x26(%bp), %dx /* EDX=inode size */ mull %edx /* EDX:EAX=relative displacement of the inode struct */ divl 0x0e(%bp) /* bytes per block */ /* EAX=relative block number for the inode struct */ pushw %dx /* DX=displacement of the inode struct in the block */ /* EDX high=0 */ addl 8(%bx, %si), %eax /* EAX=absolute block number for the inode struct */ /* CF=0, ZF=0 */ call read_block /* 0000:1000 points to the block data containing the inode struct */ /* ES changed and > 0, BX=0x1000 */ /* ECX=EDX=0 */ /* CF=0, ZF=0 */ popw %si /* DS:[BX+SI] points to the inode struct */ addw %bx, %si /* DS:SI points to the inode struct */ /* Move the inode struct to a known safe area(0000:0fa8 - 0000:0fff), * that is, 0x58 bytes immediately before 0000:1000. We care about only * the beginning 0x58 bytes of the 0x80-byte inode struct, the last * 0x28 bytes are ignored. The area from 0xfa8+0x28 to 0xfa8+0x57 * stores 12 direct block pointers. * * * At address Initial value Stores what? * ========== ============= ====================================== * 0xfa8+0x04 (const) the size of the file in bytes * * 0xfa8+0x08 total blocks blocks left to read * * 0xfa8+0x0c 0 serial number of the block to read * */ pushw %ss popw %es /* ES=0 */ leaw -0x58(%bx), %di /* BX=0x1000, so DI=0x0fa8 */ //movw $0x0fa8, %di movb $0x2c, %cl /* 0x2c words = 0x58 bytes */ repz movsw /* now ECX=0, BX=0x1000=DI */ movl %ecx, (0x0c - 0x58)(%di) /* block serial number of the file */ /* ECX=0 means first block */ /* DI=0x1000 */ movl (0x04 - 0x58)(%di), %eax /* i_size, the file size */ decl %eax divl 0x0e(%bp) /* bytes per block */ /* EDX=various */ incl %eax movl %eax, (0x08 - 0x58)(%di) /* total blocks for file data */ /* * 0000:1000 trebly indirect block * 0000:8000 indirect block * 0000:c000 double indirect block * 1000:0000 the file data */ /* now DS:SI points to indirect block number */ lodsl /* indirect block number */ testl %eax, %eax jz 1f //pushw %ss //popw %es /* ES=0 */ movb $0x80, %bh /* ES:BX=0000:8000 */ #if 0 stc call read_block #else call read_block_c #endif /* ES changed and > 0, BX=0x8000 */ /* ECX=EDX=0 */ /* ZF=0, CF=0 */ /* now DS:SI points to double indirect block number */ lodsl /* double indirect block number */ testl %eax, %eax jz 1f #if 0 pushw %ss popw %es /* ES=0 */ movb $0xc0, %bh /* ES:BX=0000:c000 */ stc call read_block #else movb $0xc0, %bh /* ES:BX=0000:c000 */ call read_block_c #endif /* ES changed and > 0, BX=0xc000 */ /* ECX=EDX=0 */ /* ZF=0, CF=0 */ /* now DS:SI points to trebly indirect block number */ lodsl /* trebly indirect block number */ testl %eax, %eax /* CF=0, TEST always clears CF */ jz 1f /* ZF=0 */ //pushw %ss //popw %es /* ES=0 */ //movb $0x10, %bh /* ES:BX=0000:1000 */ //stc call read_block /* 0000:1000 points to the block data */ /* ES changed and > 0, BX=0x1000 */ /* ECX=EDX=0 */ /* ZF=0, CF=0 */ /* the block at 0000:1000, which contains the indirect block numbers, * is just overwritten by the trebly indirect block */ 1: /* get absolute block number by block serial number */ movl (0x0c - 0x58)(%di), %ebx /* block serial number of the file */ subl $12, %ebx jc 3f /* direct block: block serial number < 12 */ pushw %bx subl 0x14(%bp), %ebx popw %ax jnc 2f /* indirect block: 12 <= block serial number < 12 + 0x14(%bp) */ //addw 0x14(%bp), %bx addb $(0x70 / 4), %ah //xchgw %ax, %bx jmp 8f 2: pushl %ebx subl 0x10(%bp), %ebx jc 7f /* EBX on the stack is < 0x10(%bp). double indirect block: * 12 + 0x14(%bp) <= block serial number < 12 + 0x14(%bp) + 0x10(%bp) */ /* trebly indirect block: block serial number >= 12 + 0x14(%bp) + 0x10(%bp) */ popl %eax /* discard the stack */ xchgl %eax, %ebx /* move EBX to EAX */ /* EDX=0 */ divl 0x10(%bp) /* EAX=indirect block number, < 0x14(%bp) */ /* EDX=block number, < 0x10(%bp) */ pushl %edx /* EDX < 0x10(%bp) */ testl %edx, %edx jnz 7f /* EDX=0, so we need to load the double indirect block */ shlw $2, %ax xchgw %ax, %bx /* get the double indirect block number from the trebly indirect * block data */ movl (%bx, %di), %eax //6: movw $0xc000, %bx /* ES:BX=0000:c000 */ //pushw %ss //popw %es /* ES=0 */ //stc call read_block_c /* 0000:c000 points to the block data */ /* ES changed and > 0, BX=0xc000 */ /* ECX=EDX=0 */ /* CF=0, ZF=0 */ 7: popl %eax /* EAX < 0x10(%bp) */ cdq /* let EDX=0 (notice the above jc 7f and jnz 7f) */ divl 0x14(%bp) /* EAX=indirect block number, < 0x14(%bp) */ /* EDX=block number, < 0x14(%bp) */ pushw %dx /* EDX < 0x14(%bp) */ testw %dx, %dx jnz 7f /* if DX=0, we need to load the indirect block */ //addb $(0xb0 / 4), %ah shlw $2, %ax xchgw %ax, %bx /* get the indirect block number from the double indirect block data */ movl 0xb000(%bx, %di), %eax //movl (%bx, %di), %eax //5: movw $0x8000, %bx /* ES:BX=0000:8000 */ //pushw %ss //popw %es /* ES=0 */ //stc call read_block_c /* 0000:8000 points to the block data */ /* ES changed and > 0, BX=0x8000 */ /* ECX=EDX=0 */ /* CF=0, ZF=0 */ 7: popw %ax /* AX < 0x14(%bp) */ 8: xchgw %ax, %bx 3: shlw $2, %bx movl (%bx, %di), %eax /* got it! EAX=absolute block number */ /* read block data to 1000:0000. For root dir, read each block to * 1000:0000(overwrite the previous read). For grldr, read blocks * one by one to the area starting at 1000:0000. */ popfw popw %bx popw %es pushfw /* CF=0 and ZF=1 for reading root dir, CF=1 for reading grldr */ call read_block /* 1000:0000 points to the block data */ /* ES changed and > 0x1000, BX=0 */ /* ECX=EDX=0 */ /* CF=0, ZF=0 */ popfw pushw %es pushw %bx pushfw jc 3f /* CF=1, we are reading grldr */ /* We have just read a block of the root dir to 1000:0000. * So we check all dir entries in the block to see if anyone * matches grldr. */ xorw %si, %si pushw %ss popw %es /* ES=0 */ 2: pushw %ds /* DS=0 */ movw %di, %ds /* DS=0x1000 */ movw $(filename_ext2 - Entry_ext2 + 0x7c00), %di pushw %si lodsl /* This is possible inode number for grldr */ pushl %eax /* This is possible inode number for grldr */ lodsw xchgw %ax, %dx /* rec_len */ lodsw /* AL=name_len, should be 5 for grldr */ /* AH=file_type(1 for regular file) */ #if 0 cmpw $0x0105, %ax jnz 5f movb %al, %cl /* CH is already 0 */ repz cmpsb #else decb %ah //jnz 5f xchgw %ax, %cx /* CX=name_len */ repz cmpsb jnz 5f xchgw %ax, %cx /* movb $0, %al */ scasb #endif 5: popl %eax /* This is possible inode number for grldr */ popw %si /* DS=0x1000, EAX=inode number */ movw %ds, %di /* DI=0x1000 */ popw %ds /* DS=0 */ stc /* indicates the new inode is for grldr */ jz 4b /* grldr is found with EAX=inode number */ addw %dx, %si cmpw 0x0e(%bp), %si /* bytes per block */ jb 2b /* file not found in this block, continue */ /* We are lucky that CF=0, which indicates we are dealing with * the root dir. */ 3: /* CF=1 for grldr, CF=0 for root dir. */ incl (0x0c - 0x58)(%di) decl (0x08 - 0x58)(%di) jnz 1b #if 0 /* The above 2 instructions INC and DEC do not touch CF, so we * can omit this POP-PUSH pair. */ popfw pushfw #endif movw $(msg_No_grldr_ext2 - Entry_ext2 + 0x7c00), %si jnc boot_error_ext2 /* grldr not found in the root dir */ /* All grldr blocks have been loaded to memory starting at 1000:0000, * Before the boot, we pass boot_drive and boot_partition to grldr. */ /* ES>0x1000, BX=0, ECX=EDX=0, DI=0x1000, SS=0, SI>0x7c00, DS=0 * BP=0x7c00, SP<=0x7c00 */ movw 0x24(%bp), %dx /* boot it now! */ pushw %di /* 0x1000 */ pushw %ss /* 0x0000 */ lret read_block_c: pushw %ss popw %es /* ES=0 */ stc /* read_block - read a block * input: CF - indicator for overlap or consecution * EAX = block number * ES:BX - buffer * * output: if CF is cleared on input, ES:BX is initialized to 0000:1000 * ES:BX - buffer filled with data * ES, EAX - Changed * ECX = 0 * EDX = 0 * ZF = 0 * CF = 0 */ read_block: jc 1f .byte 0xC4, 0x5E, 0xFC /* lesw -4(%bp), %bx */ /* ES:BX=0000:1000 */ jnz 1f //at this time, the gcc cannot generate 3 byte code .byte 0xC4, 0x5E, 0xFA /* lesw -6(%bp), %bx */ /* ES:BX=1000:0000 */ //. = . - (. - read_block) / 6 1: movzbl 0x0d(%bp), %ecx /* CX=sectors per block */ /* ECX high=0 */ . = . - (. - 1b) / 6 mull %ecx /* EAX=relative sector number */ /* EDX=0 */ . = . - (. - 1b) / 9 addl 0x1c(%bp), %eax /* EAX=absolute sector number */ #if 1 /* pass through, saving 4 bytes(call and ret) */ #else call readDisk_ext2 ret #endif /* Read sectors from disk, using LBA or CHS * input: EAX = 32-bit LBA sector number * CX = number of sectors to read * ECX high word = 0 * ES:BX = destination buffer * * output: No return on error * BX not changed * ES = ES + 0x20 * CX * EAX = EAX + CX * ZF = 0 * CF = 0 */ readDisk_ext2: 2: pushal //xorl %edx, %edx /* EDX:EAX = LBA */ pushl %edx /* hi 32bit of sector number */ pushl %eax /* lo 32bit of sector number */ pushw %es /* buffer segment */ pushw %bx /* buffer offset */ pushw $1 /* 1 sector to read */ pushw $16 /* size of this parameter block */ //xorl %ecx, %ecx pushl 0x18(%bp) /* lo:sectors per track, hi:number of heads */ popw %cx /* ECX = sectors per track */ divl %ecx /* residue is in EDX */ /* quotient is in EAX */ /* EDX high=0, DH=0 */ incw %dx /* DL=sector number */ popw %cx /* ECX = number of heads */ pushw %dx /* push sector number into stack */ xorw %dx, %dx /* EDX:EAX = cylinder * TotalHeads + head */ divl %ecx /* residue is in EDX, head number */ /* quotient is in EAX, cylinder number */ /* EDX high=0, EAX high=0 */ xchgb %dl, %dh /* head number should be in DH */ /* DL = 0 */ popw %cx /* pop sector number from stack */ xchgb %al, %ch /* lo 8bit cylinder should be in CH */ /* AL = 0 */ shlb $6, %ah /* hi 2bit cylinder ... */ orb %ah, %cl /* ... should be in CL */ incw %ax /* AL=1, read 1 sector */ /* Instead of 0x0e, the LBA indicator at 2(%bp) is * * 0x42 for LBA * * and * * 0x02 for CHS */ #if 0 movb $0x42, %ah /* ebios_ext2 - 1 points to 0x42 that can be changed to 0x02 */ #else movb $0x02, %ah /* ebios_ext2 - 1 points to 0x02 that can be changed to 0x42 */ #endif ebios_ext2: //andb 2(%bp), %ah movw %sp, %si /* DS:SI points to disk address packet */ movb 0x24(%bp), %dl /* drive number */ int $0x13 jc disk_error_ext2 movw %es, %ax addw $0x20, %ax /* here, carry is cleared */ movw %ax, %es popaw /* remove parameter block from stack */ popal incl %eax /* next sector, here ZF=0 */ loop 2b ret //. = . - (. - readDisk_ext2)/74 //msg_DiskReadError_ext2: // // .ascii "disk error\0" msg_No_grldr_ext2: .ascii "No " filename_ext2: #ifdef BOOTGRUB2 .ascii "g2ldr\0" #else .ascii "grldr\0" #endif . = Entry_ext2 + 0x1ee filename_end_ext2: .word (filename_ext2 - Entry_ext2)+(filename_end_ext2 - filename_ext2 - 1)*2048 . = Entry_ext2 + 0x1f0 disk_error_ext2: movw $(msg_DiskReadError_ext2 - Entry_ext2 + 0x7c00), %si boot_error_ext2: /* prints string DS:SI (modifies AX BX SI) */ //print_ext2: 1: lodsb (%si), %al /* get token */ //xorw %bx, %bx /* video page 0 */ movb $0x0e, %ah /* print it */ int $0x10 /* via TTY mode */ cmpb $0, %al /* end of string? */ jne 1b /* until done */ #if 1 /* The caller will change this to * ljmp $0x9400, $(try_next_partition - _start1) */ 1: jmp 1b #else /* boot failed, try to hand over the control to supervisor */ ldsw (1f + 3 - Entry_ext2)(%bp), %si lodsl cmpl $0x9400b8fa, %eax 1: jnz 1b /* no supervisor, hang up. */ ljmp $0x9400, $(try_next_partition - _start1) //. = . - (. - disk_error_ext2) / 30 #endif . = Entry_ext2 + 0x1fe .word 0xAA55 . = _start1 + 0xA00 #define INSIDE_GRLDR #include "ntfsbs.S" . = _start1 + 0x1200 .arch i586, jumps #ifdef DEBUG . = Entry_ext2 + 0x201 debug_print: pushfl pushal movl %eax, %ebp call 2f #if 0 popal pushal movl %ebx, %ebp call 2f popal pushal movl %ecx, %ebp call 2f popal pushal movl %edx, %ebp call 2f popal pushal movl %esi, %ebp call 2f popal pushal movl %edi, %ebp call 2f popal popfl pushfl pushal pushfl popl %ebp /* flags */ call 2f movw %ds, %bp shll $16, %ebp movw %es, %bp call 2f movw $0x0e0d, %ax /* print CR */ int $0x10 /* via TTY mode */ movw $0x0e0a, %ax /* print LF */ int $0x10 /* via TTY mode */ #endif popal popfl ret 2: movw $7, %cx 1: xorw %bx, %bx /* video page 0 */ movl %ebp, %eax shrl %cl, %eax shrl %cl, %eax shrl %cl, %eax shrl %cl, %eax andb $0x0f, %al addb $0x30, %al movb $0x0e, %ah /* print char in AL */ int $0x10 /* via TTY mode */ decw %cx testw %cx, %cx jns 1b movw $0x0e20, %ax /* print space */ int $0x10 /* via TTY mode */ ret #endif #if 1 /* restore GRLDR_CS */ /* this code is executed at 0000:MONITOR, which must be a 16-byte * aligned address. The address 0000:MONITOR should be designed in * a way that could avoid memory confliction with volume boot records * (currently FAT12/16/32/NTFS/EXT2/3 are built in). */ /* CS=code */ .align 16 restore_GRLDR_CS: 2: call 1f 1: popw %bx # instruction pointer of 1b movw %cs, %ax shrw $4, %bx addw %ax, %bx # BX=segment value of this code pushw %bx pushw $(1f - 2b) lret 1: /* modify gdt base */ xorl %eax, %eax movw %bx, %ax shll $4, %eax addl $(gdt -2b), %eax movl %eax, %cs:(gdt - 2b + 2) movw $GRLDR_CS, %bx movw %bx, %es movw %ds, %bx # save old DS to BX cli lgdt %cs:(gdt - 2b) movl %cr0, %eax orb $1, %al movl %eax, %cr0 movw $8, %si movw %si, %ds xorl %esi, %esi xorl %edi, %edi movl $(0x9000 / 4), %ecx cld repz movsl movw $16, %si movw %si, %ds andb $0xfe, %al movl %eax, %cr0 movw %bx, %ds # restore DS from BX ljmp $GRLDR_CS, $(try_next_partition - _start1) #endif # Descriptor tables # # NOTE: The intel manual says gdt should be sixteen bytes aligned for # efficiency reasons. However, there are machines which are known not # to boot with misaligned GDTs, so alter this at your peril! If you alter # GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two # empty GDT entries (one for NULL and one reserved). # # NOTE: On some CPUs, the GDT must be 8 byte aligned. This is # true for the Voyager Quad CPU card which will not boot without # This directive. 16 byte aligment is recommended by intel. # .align 16 gdt: /* this is the default null entry in GDT */ .word gdt_end - gdt - 1 # gdt limit .long (GRLDR_CS * 16 + gdt - _start1) # linear address of gdt .word 0 # pad 2 bytes /* real mode data segment base=0x200000 */ .word 0xFFFF, 0 .byte 0x20, 0x92, 0, 0 /* real mode data segment base=0 */ .word 0xFFFF, 0 .byte 0, 0x92, 0, 0 gdt_end: helper_start: /* helper function begins here * before the call: * CF=1 : indicates an invalid or corrupt entry * CF=0 : indicates a valid entry * * on return: * CF=1 : means "below", try next entry * CF=0,ZF=1 : means "equal", helper did nothing, so we need * a further try to boot via NT bootsector * CF=0,ZF=0 : means "above", helper succeeded, boot it now */ sti /* DS=SS=0x9400 */ pushw %cs popw %ds pushw $FS_BOOT popw %es /* ES=FS_BOOT */ /* Format of partition information blocks. * * Offset Length in bytes Field * 00h 1 Set to 80h if this partition is active. * 01h 1 Partition's starting head. * 02h 2 Partition's starting sector and track. * 04h(SI) 1 Partition's ID number. * 05h 1 Partition's ending head. * 06h 2 Partition's ending sector and track. * 08h 4 Starting LBA. * 0Ch 4 Partition's length in sectors. */ pushw %ds /* DS=0x9400 */ pushw %es /* ES=FS_BOOT */ pushal pushfw //pushw %si //stc //jc invalid_or_null /* invalid or null entry */ #if 0 /* backup 63 sectors at FS_BOOT:0 to 63 sectors at FS_BOOT:8000 * this piece of code is no longer useful. */ pushw %es popw %ds xorw %si, %si movw $0x8000, %di movw $0x3f00, %cx cld repz movsw #endif #if (defined(GRLDR_MBR)) || (defined(GRLDR_INSTALL)) testb $0x80, %cs:0x02 /* boot previous MBR first? */ jnz 2f /* no, continue to find GRLDR */ /* yes, call the routine for booting the previous MBR. * it will not return on success. * on failure, it will return here */ /* before we call the routine, we will check if the user want to * skip this step and continue to find the GRLDR */ #if 0 movw $(press_space_bar_string - _start1), %si cmpw $0x3920, %cs:0x04 je 1f movw $(press_hot_key_string - _start1), %si 1: /* if timeout==0, don't display the message */ cmpb $0, %cs:0x03 je 1f call print_message /* CS:SI points to message string */ movw $(press_any_key_string - _start1), %si call print_message /* CS:SI points to message string */ #else cmpb $0, %cs:0x03 je 1f movw $(press_hot_key_pre - _start1), %si call print_message movw $(press_hot_key_name - _start1), %si call print_message movw $(press_hot_key_sub - _start1), %si call print_message #endif 1: call sleep_5_seconds jc 1f /* desired hot-key pressed */ call boot_prev_mbr //Error_modify 1: orb $0x80, %cs:0x02 2: #endif popfw popal popw %es popw %ds pushw %ds /* DS=0x9400 */ pushw %es /* ES=FS_BOOT */ pushal pushfw //cmpb $0x0e, 0x00 /* EBIOS previously checked OK? */ //jbe 1f /* yes, skip the check */ movb $0x02, 0x00 /* initialise this byte to 0x02 */ movb $0x41, %ah /* EBIOS check existence */ movw $0x55aa, %bx int $0x13 jc 1f /* No EBIOS */ cmpw $0xaa55, %bx jnz 1f /* No EBIOS */ testb $1, %cl jz 1f /* No EBIOS */ movb $0x42, 0x00 /* LBA supported, save 0x42 to 9400:0000 */ 1: popfw popal popw %es popw %ds pushw %ds /* DS=0x9400 */ pushw %es /* ES=FS_BOOT */ pushal pushfw pushaw cmpw $0x1c2, %si jne 1f /* initialize partition number and partition entries end */ movw $0xffff, 0x1bc /* hd partition number */ movw $0x01fe, 0x1ba /* partition entries end */ 1: pushw %dx testb %dl, %dl jns 1f /* floppy, use normal CHS mode */ cmpw $0x1f2, %si /* is it a primary partition? */ ja 2f /* no, it is an extended partition */ movl 4(%si), %eax movl %eax, 8(%si) /* parent part_start saved here */ xorl %eax, %eax movl %eax, 4(%si) /* current part_start(0) saved here */ 2: //movl -4(%si), %eax //cmpl $0xfffffe00, %eax /* check the starting CHS */ //jb 1f /* use normal CHS mode */ /* get CHS total number of sectors */ pushw %es pushw %ds movb $8, %ah /* read drive parameters changes DX,ES,DI */ //movb $0x80, %dl /* BIOS drive number is in DL */ int $0x13 popw %ds popw %es jc 3f testb $63, %cl jnz 2f 3: /* failed to get drive parameters, use maximum value */ #if 0 popw %dx pushw %dx cmpb $0x80, %dl jne 3f pushw %ds xorw %ax, %ax movw %ax, %ds cmpb $0, 0x475 popw %ds je 3f 3: #endif movw $0xffff, %cx movw %cx, %dx 2: //xorl %eax, %eax movzbl %dh, %eax incw %ax movzbl %cl, %edx andb $63, %dl mulw %dx /* DX=0, AX=product */ shrb $6, %cl xchgb %cl, %dh xchgb %ch, %dl incw %dx /* DX=total cylinders */ mull %edx /* EDX=0, EAX=product */ /* check the partition's starting LBA */ movl 4(%si), %ebx addl 8(%si), %ebx /* EBX=start_LBA */ testl %ebx, %ebx je 1f ///* we always use LBA mode */ ////cmpl %eax, %ebx ////jb 1f /* use normal CHS mode */ cmpb $0x42, 0x00 /* EBIOS present? */ jne 1f /* no, skip the LBA mode int13 call */ /* load partition boot track to FS_BOOT using LBA mode */ popw %ax /* AX=orig DX which holds drive number DL */ pushw %ax pushl %edx /* EDX=0, higher 4 bytes of starting LBA */ pushl %ebx /* lower 4 bytes of starting LBA */ pushw %es /* ES=FS_BOOT */ pushw %dx /* DX=0, ES:0 is the buffer */ //pushl $0x003f0010 /* transfer 63 sectors */ pushw $0x3f /* transfer 63 sectors */ pushw $0x10 /* size of disk address packet */ xchgw %ax, %dx /* restore drive number DL from AL */ movb $0x42, %ah /* extended read */ movw %sp, %si /* DS:SI points to disk address packet */ int $0x13 /* ignore the read failure */ popaw /* adjust the stack */ jc 1f popw %dx popaw //popw %ax /* discard flags in the stack */ popfw clc pushfw /* push new flags with CF=0 */ pushaw pushw %dx 1: popw %dx popaw popfw popal popw %es popw %ds pushw %ds /* DS=0x9400 */ pushw %es /* ES=FS_BOOT */ pushal pushfw pushw %si pushfw pushw %es //--------------------------------------------------------- /* print "Try (hd0,n): " or "Try (fd0): "*/ pushw %ds popw %es /* ES=DS=CS=0x9400 */ cld /* for stosb */ xorw %ax, %ax testb %dl, %dl jns 1f /* floppy */ /* hard drive */ #if 0 movw %si, %ax subw $0x1c2, %ax shrw $4, %ax cmpw $0x1fe, %si /* is in MBR? */ jb 1f /* yes */ /* no, it is an entry in an extended partition */ movb $0xFC, (add_sub_si + 2 - _start1) /* addw $-4, %si */ incw 0x1bc /* logical partition number */ movb 0x1bc, %al #else incw 0x1bc /* logical partition number */ movw 0x1bc, %ax cmpb $4, %al jb 1f movb $0xFC, (add_sub_si + 2 - _start1) /* addw $-4, %si */ #endif 1: /* AL=partition number, AH=0 */ pushw %ax movw $(partition_message - _start1 + 7), %di /* drive type */ movb %dl, %al shrb $7, %al /* drive type: floppy=0, harddrive=1 */ shlb $1, %al addw $0x6466, %ax /* "fd" or "hd" */ stosw movb %dl, %al andb $0x7f, %al /* drive number */ aam /* convert binary to decimal, AH=high, AL=low */ testb %ah, %ah jz 1f addb $0x30, %ah movb %ah, (%di) incw %di 1: addb $0x30, %al stosb popw %ax testb %dl, %dl jns 2f /* floppy */ /* this is a hard drive, the partition number is in AL */ movb $0x2c, (%di) /* "," */ incw %di aam /* convert binary to decimal, AH=high, AL=low */ testb %ah, %ah jz 1f addb $0x30, %ah movb %ah, (%di) incw %di 1: addb $0x30, %al stosb 2: movl $0x00203a29, (%di) /* "): \0" */ movw $(partition_message - _start1), %si call print_message /* CS:SI points to message string */ //--------------------------------------------------------- popw %es popfw //stc jc invalid_or_null /* invalid or null entry */ xorw %si, %si pushw %es popw %ds /* DS=ES=FS_BOOT */ /* First, check for ext2 filesystem */ cmpw $0xEF53, 0x438 /* Magic signature */ jnz 1f xorl %eax, %eax cmpl %eax, 0x400 /* s_inodes_count */ jz 1f cmpl %eax, 0x404 /* s_blocks_count */ jz 1f // cmpw %ax, 0x458 /* s_inode_size, usually 0x80 */ // jz 1f cmpl %eax, 0x420 /* s_blocks_per_group */ jz 1f cmpl %eax, 0x428 /* s_inodes_per_group */ jz 1f movl 0x414, %eax /* s_first_data_block */ movw %ax, %bx /* BX=1 for 1K block, 0 otherwise */ shrl $1, %eax /* must be 0 */ jnz 1f movl 0x418, %ecx /* s_log_block_size */ cmpl $4, %ecx /* max size of block is 16K */ ja 1f negw %cx /* CF=0 for 1K block, CF=1 otherwise */ adcw %ax, %bx /* EAX=0 */ decw %bx jnz 1f /* BX = 0 */ /* EAX= 0 */ movw $0x80, %ax /* EXT2_GOOD_OLD_INODE_SIZE */ movw %ax, %cs:0x826 /* inode size */ movl 0x44C, %ecx /* ECX=s_rev_level */ jecxz 3f /* EXT2_GOOD_OLD_REV */ movw 0x458, %ax /* AX=s_inode_size */ testw %ax, %ax jz 1f /* invalid inode size */ pushw %ax pushw %dx movb 0x418, %cl /* s_log_block_size */ addb $10, %cl xorw %dx, %dx /* DX=0 */ incw %dx /* DX=1 */ shlw %cl, %dx /* DX=block size in bytes */ xchgw %ax, %cx /* CX=s_inode_size */ xchgw %ax, %dx /* AX=block size in bytes */ xorw %dx, %dx /* DX:AX=block size in bytes */ divw %cx /* quo=AX, rem=DX */ testw %dx, %dx popw %dx popw %ax jnz 1f /* invalid inode size */ movw %ax, %cs:0x826 /* inode size */ 3: /* BX = 0 */ /* super block is sane */ //pushw %cs //popw %ds ///* DS=SS=0x9400 */ ///* ES=FS_BOOT */ cld movw $0x800, %si xorw %di, %di movw $0x0200, %cx /* yes, we need 2 sectors if enable debug */ repz cs movsw /* CS segment override prefix(=0x2E) */ /* modify the boot partition number */ /* the boot partition number is at offset 0x25 for ext2 */ testb %dl, %dl jns 3f /* no modification for floppy */ movw $0x25, %di movw %cs:0x1bc, %ax /* partition number */ stosb 3: /* fix for ext2 partition: hidden_sectors, offset 0x1c */ popw %si /* DI points to old entry in MBR */ pushw %si xorl %eax, %eax /* let hidden_sectors=0 for floppy */ testb %dl, %dl jns 3f /* floppy */ movl %cs:4(%si), %eax addl %cs:8(%si), %eax 3: /* BX = 0 */ movl %eax, %es:0x1c(%bx) /* adjust hidden_sectors for EXT2 */ /* fix for ext2 partition: EBIOS indicator, offset 0x02 */ movb %cs:0x00(%bx), %al movb %al, %es:0x02(%bx) /* fix for ext2 partition: sectors per block, offset 0x0d */ /* fix for ext2 partition: bytes per block, offset 0x0e */ /* fix for ext2 partition: dwords per block(dpb), offset 0x14 */ /* fix for ext2 partition: square of dpb, offset 0x10 */ movb %es:0x418, %cl /* s_log_block_size */ //incw %cx movl $2, %eax shlw %cl, %ax movb %al, %es:0x0d(%bx) shlw $9, %ax /* block size is word wide */ movw %ax, %es:0x0e(%bx) shrw $2, %ax movl %eax, %es:0x14(%bx) addb $8, %cl shll %cl, %eax movl %eax, %es:0x10(%bx) /* fix for ext2 partition: sectors per track, offset 0x18 */ /* fix for ext2 partition: number of heads, offset 0x1a */ #if 1 pushw %ds pushw %es pushw %bx pushw %dx movb $8, %ah /* read drive parameters changes DX,ES,DI,BX */ movb $0x80, %dl /* BIOS drive number is in DL */ int $0x13 movw %dx, %ax popw %dx popw %bx popw %es popw %ds jc 3f andb $63, %cl jz 3f movb %cl, %es:0x18(%bx) shrw $8, %ax incw %ax movw %ax, %es:0x1a(%bx) 3: #else testb %dl, %dl jns 3f /* floppy */ popw %di /* DI points to old entry in MBR */ pushw %di movw %cs:1(%di), %ax andb $63, %ah movb %ah, %es:0x18 xorb %ah, %ah incw %ax movw %ax, %es:0x1a 3: #endif /* fix for ext2 partition: s_inodes_per_group, offset 0x28 */ movl %es:0x428, %eax /* s_inodes_per_group */ movl %eax, %es:0x28(%bx) /* fix for ext2 partition: block number for group descriptors, offset 0x2c */ /* At which block the group descriptors begin? */ movl %es:0x414, %eax /* s_first_data_block */ incw %ax movl %eax, %es:0x2c(%bx) /* fix for ext2 partition: on error go back to supervisor, offset 0x01fc */ movw $0x01fc, %si movw %si, %di lodsw cmpw $0xFEEB, %ax /* EB FE is jmp back to itself(infinite loop) */ jnz 3f decw %ax /* AL=0xEA, ljmp */ stosb //movw $(try_next_partition - _start1), %ax movw $MONITOR, %ax stosw //movw %cs, %ax /* AX=0x9400 */ xorw %ax, %ax stosw /* the last byte 0x00 is in the next sector! */ // addw $0x0f, %di // movw $(restore_GRLDR_CS - _start1), %si // movw $((gdt_end - restore_GRLDR_CS) / 4), %cx // .byte 0x2e /* %cs: prefix */ // repz movsl 3: movw $(EXT2_message - _start1), %si call print_message /* CS:SI points to message string */ clc jmp move_entries_and_return 1: #; It is not EXT2. Check for FAT12/16/32/NTFS. /* DS=ES=FS_BOOT */ cmpw $0x200, 0x0b(%si) /* bytes per sector */ jne 1f /* not a normal BPB */ movb 0x0d(%si), %al /* sectors per cluster */ testb %al, %al jz 1f /* invalid if = 0 */ movb %al, %cl movw $128, %ax divb %cl /* quo=AL, rem=AH */ testb %ah, %ah jnz 1f /* invalid if not 2^n */ movw 0x18(%si), %ax /* sectors per track */ testw %ax, %ax jz 1f /* invalid if = 0 */ cmpw $63, %ax ja 1f /* invalid if > 63 */ movw 0x1a(%si), %ax /* number of heads */ decw %ax /* Max head number, should be a byte */ testb %ah, %ah /* should be 0 */ jnz 1f /* invalid if number of heads > 256 */ cmpb $0xf0, 0x15(%si) /* media descriptor */ jb 1f cmpb $0x42, %cs:0x00 /* EBIOS present? */ jne 3f //movb $0x41, %ah /* EBIOS check existence */ //movw $0x55aa, %bx //int $0x13 //jc 3f /* No EBIOS */ //cmpw $0xaa55, %bx //jnz 3f /* No EBIOS */ //testb $1, %cl //jz 3f /* No EBIOS */ movb $0x0e, 0x02(%si) /* force LBA */ 3: cld movw $0x0600, %bx /* FAT12/FAT16 */ movw $0x003c, %cx /* FAT12/FAT16 */ movb 0x10(%si), %al /* number of FATs(NTFS:0, FAT:1,2) */ cmpb $2, %al ja 1f /* abnormal FAT */ movw 0x11(%si), %ax /* max root entries */ testw %ax, %ax jnz 2f /* FAT12/FAT16 */ /* FAT32 or NTFS */ movw 0x13(%si), %ax /* total sectors(small) */ testw %ax, %ax jnz 1f /* invalid FAT32 BPB */ movw 0x16(%si), %ax /* sectors per FAT(small) */ testw %ax, %ax jnz 1f /* invalid FAT32 BPB */ movb 0x10(%si), %al /* number of FATs(NTFS:0, FAT:1,2) */ testb %al, %al jz 8f /* FAT32 */ movl 0x20(%si), %eax /* FAT32 total sectors */ testl %eax, %eax jz 1f movl 0x24(%si), %eax /* FAT32 sectors per FAT */ testl %eax, %eax jz 1f movw $0x0400, %bx /* FAT32 */ movw $0x0058, %cx /* FAT32 */ movw $(FAT32_message - _start1), %si jmp 7f 8: /* NTFS */ movl 0x20(%si), %eax /* FAT32 total sectors */ testl %eax, %eax jnz 1f //movw 0x11(%si), %ax /* max root entries */ //testw %ax, %ax //jnz 1f movw 0x0e(%si), %ax /* reserved sectors */ testw %ax, %ax jnz 1f /* BUG fix for extended NTFS partition */ popw %si /* SI points to old entry in MBR */ pushw %si xorl %eax, %eax /* let hidden_sectors=0 for floppy */ testb %dl, %dl jns 3f /* floppy */ movl %cs:4(%si), %eax addl %cs:8(%si), %eax 3: movl %eax, 0x1c /* adjust hidden_sectors for NTFS */ movb %dl, 0x24 /* adjust drive number for NTFS */ #if 1 // Load NTFS using internal boot sector at 0xA00 movw $(NTFS5_message - _start1), %si call print_message /* CS:SI points to message string */ movw $0xA00, %bx movw $0x52, %cx pushw %cs popw %ds /* DS=SS=0x9400 */ /* ES=FS_BOOT */ movw %bx, %si xorw %di, %di lodsw stosw addw %cx, %si addw %cx, %di movw $0x800, %cx subw %di, %cx repz movsb /* modify the boot partition number */ movb %es:1, %al addb $5, %al /* AL is less than 0x80 */ cbw /* AH=0 */ xchgw %ax, %di /* move AX to DI */ movb $0xff, %al /* partition=whole drive for floppy */ testb %dl, %dl jns 3f /* no modification for floppy */ movb 0x1bc, %al /* partition number */ 3: stosb /* fix for NTFS partition: on error go back to supervisor, offset 0x01fa */ movw $0x01fa, %di movw %es:(%di), %ax cmpw $0xFEEB, %ax /* EB FE is jmp back to itself(infinite loop) */ jnz 3f decw %ax /* AL=0xEA, ljmp */ stosb //movw $(try_next_partition - _start1), %ax movw $MONITOR, %ax stosw //movw %cs, %ax /* AX=0x9400 */ xorw %ax, %ax stosw /* DI=0x01ff */ 3: clc jmp move_entries_and_return #else /* modify the boot partition number */ movb $0xB6, %al /* 0xB6="MOV DH,imm8" */ movb %cs:0x1bc, %ah testb %dl, %dl js 3f movb $0xff, %ah /* partition number for floppy is whole drive */ 3: /* before the call: * AH= partition number * AL= 0xB6 ; 0xB6 is opcode of "MOV DH,imm8" * DL= drive number * * on return: CF=0 if there is NTFS boot record; * CF=1 otherwise. * CF of flags_orig on the stack will set if CF=1 */ call modify_NTFS_boot_record //jnc move_entries_and_return //movw $(NTFS5_message - _start1), %si ////jmp 4f //call print_message /* CS:SI points to message string */ //stc jmp move_entries_and_return #endif 2: /* FAT12/FAT16 */ movb 0x10(%si), %al /* number of FATs(NTFS:0, FAT:1,2) */ testb %al, %al jz 1f movw 0x16(%si), %ax /* sectors per FAT(small) */ testw %ax, %ax jz 1f movw $(FAT16_message - _start1), %si cmpw $12, %ax ja 7f movw $(FAT12_message - _start1), %si 7: /* BUG fix for extended FAT12/16/32 partition */ popw %di /* DI points to old entry in MBR */ pushw %di xorl %eax, %eax /* let hidden_sectors=0 for floppy */ testb %dl, %dl jns 3f /* floppy */ movl %cs:4(%di), %eax addl %cs:8(%di), %eax 3: movl %eax, 0x1c /* adjust hidden_sectors for FAT */ call print_message /* CS:SI points to message string */ pushw %cs popw %ds /* DS=SS=0x9400 */ /* ES=FS_BOOT */ movw %bx, %si xorw %di, %di lodsw stosw addw %cx, %si addw %cx, %di movw $0x0200, %cx subw %di, %cx repz movsb /* modify the boot partition number */ movb %es:1, %al addb $5, %al /* AL is less than 0x80 */ cbw /* AH=0 */ xchgw %ax, %di /* move AX to DI */ movb $0xff, %al /* partition=whole drive for floppy */ testb %dl, %dl jns 3f /* no modification for floppy */ movb 0x1bc, %al /* partition number */ 3: stosb /* fix for FAT12/16/32 partition: on error go back to supervisor, offset 0x01fa */ //pushw %es //popw %ds movw $0x01fa, %di //movw %di, %si //lodsw movw %es:(%di), %ax cmpw $0xFEEB, %ax /* EB FE is jmp back to itself(infinite loop) */ jnz 3f decw %ax /* AL=0xEA, ljmp */ stosb //movw $(try_next_partition - _start1), %ax movw $MONITOR, %ax stosw //movw %cs, %ax /* AX=0x9400 */ xorw %ax, %ax stosw /* DI=0x01ff */ 3: clc jmp move_entries_and_return 1: #; It is not FAT12/16/32/NTFS. Check for extended partition. /* DS=ES=FS_BOOT */ pushw %cs popw %es /* ES=SS=0x9400 */ /* DS=FS_BOOT */ popw %si pushw %si cmpb $0x05, %es:(%si) /* extended */ je 1f cmpb $0x0f, %es:(%si) /* Win95 extended (LBA) */ je 1f cmpb $0x15, %es:(%si) /* hidden extended */ je 1f cmpb $0x1f, %es:(%si) /* hidden win95 extended (LBA) */ je 1f cmpb $0x85, %es:(%si) /* Linux extended */ je 1f movw $(non_MS_message - _start1), %si 4: call print_message /* CS:SI points to message string */ stc jmp move_entries_and_return 1: /* extended partition entry */ cmpw $0x1fe, %si jb 1f decw %es:0x1bc /* count the partitions in extended zone */ 1: movw $(extended_message - _start1), %si call print_message /* CS:SI points to message string */ movw $0x1be, %si movw $4, %cx 5: //xorl %eax, %eax //cmpl %eax, (%si) //jnz 2f movl (%si), %eax cmpw 2(%si), %ax /* Is EAX high word equal to AX? */ jnz 2f cmpb %al, %ah /* Is AL=AH? */ jnz 2f /* now all 4 bytes in EAX are equal to each other. */ cmpl %eax, 4(%si) jnz 2f cmpl %eax, 8(%si) jnz 2f cmpl %eax, 12(%si) jz 3f /* entry with 16 dups of a byte means empty entry */ 2: movb (%si), %al shlb $1, %al jnz 1f //jnz 3f /* invalid entry is treated as empty entry */ movb 2(%si), %al and $63, %al /* starting sector number */ jz 1f //jz 3f /* invalid entry is treated as empty entry */ movb 6(%si), %al and $63, %al /* ending sector number */ jz 1f //jz 3f /* invalid entry is treated as empty entry */ movl 8(%si), %eax /* starting LBA */ testl %eax, %eax jz 1f //jz 3f /* invalid entry is treated as empty entry */ movl 12(%si), %eax /* total number of sectors in partition */ testl %eax, %eax jz 1f 3: addw $16, %si loop 5b cmpw $0xaa55, (%si) jnz 1f movw $0x1be, %si movw $4, %cx popw %bx /* the old SI points to extended partition ID in MBR */ pushw %bx 5: #if 1 //xorl %eax, %eax //cmpl %eax, (%si) //jnz 2f movl (%si), %eax cmpw 2(%si), %ax /* Is EAX high word equal to AX? */ jnz 2f cmpb %al, %ah /* Is AL=AH? */ jnz 2f /* now all 4 bytes in EAX are equal to each other. */ cmpl %eax, 4(%si) jnz 2f cmpl %eax, 8(%si) jnz 2f cmpl %eax, 12(%si) jz 3f /* entry with 16 dups of a byte means empty entry */ 2: /* now it is an acceptable entry */ movw %es:0x1ba, %di /* partition entries end */ /* ensure our stack not to be overwritten by the partition entries */ cmpw $0x83f0, %di ja 3f /* try next */ /* ensure our code not to be overwritten by the partition entries */ cmpw $0x3fe, %di jne 6f /* more entries stores at 0x9be00-0x9c3ff */ movw $0x7e00, %di movw %di, %es:0x1ba 6: addw $16, %es:0x1ba /* increment partition entries end */ lodsl stosl lodsl stosl xchgw %ax, %dx /* save AL(the partition ID)to DL */ lodsl xchgl %eax, %edx /* restore AL from DL(the partition ID) * and save EAX to EDX */ cmpb $0x05, %al je 6f cmpb $0x0f, %al je 6f cmpb $0x15, %al je 6f cmpb $0x1f, %al je 6f cmpb $0x85, %al je 6f /* normal partition, copied to 0x941fe-0x943fb */ addl %es:4(%bx), %edx /* current partition start */ 6: /* extended partition, copied to 0x941fe-0x943fb */ xchgl %eax, %edx /* restore or update EAX from EDX */ stosl lodsl /* adjust SI only */ movl %es:8(%bx), %eax /* parent partition start ... */ stosl /* ... stored here */ jmp 2f 3: addw $16, %si #endif //. = 5b + 0x7c 2: loop 5b /* extended partition is not a normal one, so set carry to try next */ stc jmp move_entries_and_return invalid_or_null: 1: movw $(invalid_message - _start1), %si call print_message /* CS:SI points to message string */ stc move_entries_and_return: popw %si pushfw pushw %cs popw %ds pushw %cs popw %es pushw %si cmpw $0x202, %si jne 1f /* move entries backward 1 entry */ movw $0x1fe, %di movw $0x20e, %si movw $0xf8, %cx /* 0x1f0 bytes = 0xf8 words */ cld /* move upward */ repz movsw movw $0x3ee, %di movw $0x7e00, %si movw $0x8, %cx /* 0x10 bytes = 0x8 words */ cld /* move upward */ repz movsw movw $0x7e00, %di movw $0x7e10, %si movw $0x2f8, %cx /* 0x5f0 bytes = 0x2f8 words */ cld /* move upward */ repz movsw cmpw $0x7e10, 0x1ba jne 2f movw $0x40e, 0x1ba 2: subw $0x10, 0x1ba 1: popw %si movw $0x1ff, (add_sub_si + 5 - _start1) cmpw $0x1fe, 0x1ba jne 1f decw (add_sub_si + 5 - _start1) cmpw $0x31b2, %si /* floppy? */ je 1f /* yes */ cmpw $0x1f2, %si ja 2f /* logical partition */ jb 1f /* primary partition 0, 1, 2 */ /* primary partition 3 */ cmpw $0x0003, 0x1bc /* are there any logical partitions? */ ja 1f /* yes */ 2: inc_hard_drive: /* all partitions on the drive have been checked, try next drive. * * the current stack is: * * SP + 38 : DS * SP + 36 : ES * SP + 32 : EAX * SP + 28 : ECX * SP + 24 : EDX * SP + 20 : EBX * SP + 16 : ESP_temp * SP + 12 : EBP * SP + 8 : ESI * SP + 4 : EDI * SP + 2 : flags_orig * SP : flags * */ /* get total hard drives */ xorw %ax, %ax movw %ax, %ds movb 0x475, %dh pushw %cs popw %ds // cmpb $16, %dh // jnb 2f // movb $16, %dh //2: orb $0x80, %dh /* CF=0, DH=Max harddrive number + 1 */ //xchgw %ax, %cx /* CL=Max harddrive number + 1, CH=0 */ movw %sp, %bp movb 24(%bp), %dl /* BIOS drive number is in DL */ 2: jnc 3f call print_message /* CS:SI points to message string */ movw $(drive_number_string - _start1), %si movb %dl, %al andb $0x7f, %al aam /* AH=high decimal, AL=low decimal */ addw $0x3030, %ax xchgb %al, %ah movw %ax, 9(%si) call print_message /* CS:SI points to message string */ 3: incw %dx cmpb %dh, %dl jnb 2f /* all drives checked, try floppy finally */ pushw %bx pushw %dx pushw %es movb $8, %ah /* read drive parameters changes DX, ES, DI */ int $0x13 popw %es jc 3f /* try next hard drive */ //xchgw %ax, %cx /* this moves CL to AL */ andb $63, %cl /* CL=sectors per track, CF cleared */ stc jz 3f /* try next hard drive */ popw %dx /* get DL */ popw %bx movb %dl, %ch /* DL saved at BP high byte in the stack */ pushw %cx /* push new BX onto stack */ pushw %dx //movb $0x02, %ah //movw %ax, %si /* save AX to SI: read 1 track */ movw $0x201, %ax /* read 1 sector */ movw $0x7e00, %bx /* read MBR to 9400:7e00 */ movw $1, %cx //popw %dx //pushw %dx xorb %dh, %dh stc int $0x13 sti 3: popw %dx popw %bx /* BL=sectors per track, BH=DL */ //movw %si, %bx /* BL=sectors per track */ movw $(Error_while_reading_string - _start1), %si jc 2b /* read failure, try next hard drive */ /* on seccessful return, should be: ah=0 for OK, al=1 for 1 sector */ //decw %ax /* some BIOSes return incorrect AL */ testb %ah, %ah stc jnz 2b /* The new partition table might be empty or invalid. * Move the new partition table onto the old one while checking */ //movb %dl, %bh /* DL saved at BP high byte in the stack */ movw $0x7fbe, %si movw $0x01be, %di 3: cmpw $0x1fe, %di jnb 3f xorl %ecx, %ecx lodsl stosl orl %eax, %ecx lodsl stosl orl %eax, %ecx lodsl stosl orl %eax, %ecx lodsl stosl orl %eax, %ecx jecxz 3b /* null entry, check next */ //lodsw //stosw movb -16(%si), %al shlb $1, %al stc xchgw %ax, %si /* save SI to AX */ movw $(partition_boot_indicator_string - _start1), %si jnz 2b xchgw %ax, %si /* restore SI from AX */ //lodsw //stosw movb -14(%si), %al andb $63, %al stc xchgw %ax, %si /* save SI to AX */ movw $(partition_sectors_per_track_string - _start1), %si jz 2b xchgw %ax, %si /* restore SI from AX */ //lodsw //stosw //lodsw //stosw movb -10(%si), %al andb $63, %al stc xchgw %ax, %si /* save SI to AX */ movw $(partition_sectors_per_track_string - _start1), %si jz 2b xchgw %ax, %si /* restore SI from AX */ //lodsl //stosl movl -8(%si), %eax testl %eax, %eax stc xchgw %ax, %si /* save SI to AX */ movw $(partition_start_sector_string - _start1), %si jz 2b xchgw %ax, %si /* restore SI from AX */ //lodsl //stosl movl -4(%si), %eax testl %eax, %eax stc xchgw %ax, %si /* save SI to AX */ movw $(partition_end_sector_string - _start1), %si jz 2b xchgw %ax, %si /* restore SI from AX */ jmp 3b 3: cmpw $0xAA55, (%si) stc xchgw %ax, %si /* save SI to AX */ movw $(no_boot_signature_string - _start1), %si jnz 2b xchgw %ax, %si /* restore SI from AX */ //lodsw //stosw /* store boot signature */ /* Now the partition table is OK */ movw %bx, 12(%bp) /* adjust BP in the stack */ movw $0x1b2, 8(%bp) /* adjust SI in the stack */ /* temp change the code: call self_modify_once * * "call self_modify_once" at add_sub_si is: * * .byte 0xE8 * .word (self_modify_once - add_sub_si - 3) * */ movb $0xE8, (add_sub_si - _start1) movw $(self_modify_once - add_sub_si - 3), (add_sub_si + 1 - _start1) /* initialize partition number and partition entries end */ movw $0xffff, 0x1bc /* hd partition number */ movw $0x01fe, 0x1ba /* partition entries end */ jmp 1f 2: /* get here if all drives have been checked */ #if 0 movw $0x202, 8(%bp) /* adjust SI in the stack */ /* restore the original code: addw $-4, %si */ movw $0xC683, (add_sub_si - _start1) /* 0x83, 0xC6 */ movb $0xFC, (add_sub_si + 2 - _start1) /* 0xFC */ #endif //-------------------------------------------------------------------- /* change the code: jmp Error_modify * * "jmp Error_modify" at Error_or_prev_MBR: * * .byte 0xE9 * .word (Error_modify - Error_or_prev_MBR - 3) * */ movb $0xE9, (Error_or_prev_MBR - _start1) movw $(Error_modify - Error_or_prev_MBR - 3), (Error_or_prev_MBR + 1 - _start1) //-------------------------------------------------------------------- //-------------------------------------------------------------------- /* floppy search disabled ? */ #if 0 testb $1, 0x02 /* test bit0 of the third byte */ jz 1f /* zero means floppy search enabled */ /* 0x1fd or below means disable floppy search */ decw (add_sub_si + 5 - _start1) #else movb 0x02, %al andb $0x01, %al subb %al, (add_sub_si + 5 - _start1) #endif //-------------------------------------------------------------------- 1: #if 0 popfw lahf /* Load Flags into AH Register. */ /* AH = SF:ZF:xx:AF:xx:PF:xx:CF */ /* CF will be moved to ZF */ movb %ah, %al andb $1, %al /* CF=0 */ shlb $6, %al /* move CF to ZF */ popfw lahf /* Load Flags into AH Register. */ /* AH = SF:ZF:xx:AF:xx:PF:xx:CF */ andb $0xbf, %ah /* 0xbf= binary 1011 1111. It clears ZF */ orb %al, %ah #else popw %ax /* AX=Flags */ popfw /* Flags_orig */ lahf /* Load Flags_orig into AH Register. */ /* AH = SF:ZF:xx:AF:xx:PF:xx:CF */ shlb $2, %ah rorw $2, %ax /* move CF of Flags to ZF of Flags_orig */ #endif sahf /* update flags */ /* current CF is the CF of Flags_orig */ /* current ZF is the CF of Flags */ jc 1f /* CF=1 means failed in loading bootsector */ popal /* get drive number DL */ pushal pushfw cmpb $0xff, %cs:0x06 jz 2f movb %cs:0x1bc, %dh testb %dl, %dl js 3f movb $0xff, %dh /* partition # for floppy is "whole drive" */ 3: cmpw %cs:0x06, %dx jz 2f popfw stc pushfw 2: popfw 1: popal popw %es popw %ds ret self_modify_once: /* when we get here, SI should be 0x1b2, and BP high holds DL */ addw $12, %si /* 0x83, 0xC6, 0x0C */ movw %bp, %ax movb %ah, %dl /* note: DS=0x9400 */ /* restore the original code: addw $12, %si */ movw $0xC683, (add_sub_si - _start1) /* 0x83, 0xC6 */ movb $0x0C, (add_sub_si + 2 - _start1) /* 0x0C */ ret Error_modify: cmpb $0xff, %cs:0x06 /* preferred drive? */ jz 1f /* not active. Turn to the final step. */ /* preferred drive is already handled, so de-activate it now. */ movb $0xff, %cs:0x06 /* we will do the second pass, from drive 0x80. */ movb $0x7f, %dl /* this will become 0x80 after inc. */ /* pass "error" to PUSHF, simulating a load failure, in order * to try the first entry after return from the helper function. */ stc pushw $(helper_call + 3 - _start1) /* return address */ pushw %cs /* 0x9400, it is for DS. */ pushw $FS_BOOT /* 0x0d00, it is for ES. */ pushal //pushl %eax //pushl %ecx //pushl %edx //pushl %ebx //pushl %esp //pushl %ebp //pushl %esi //pushl %edi pushfw /* CF=1 */ pushfw pushw %cs popw %es /* ES=0x9400 */ /* redo from start: DL will be 0x80 after inc. */ jmp inc_hard_drive 1: boot_prev_mbr: /* prepare to boot the previous MBR */ /* at this moment DS=0x9400, ES=$FS_BOOT or ES=0x9400 */ xorw %ax, %ax //pushw %ax /* AX=0, for the segment of 0000:7c00 */ movw %ax, %es /* ES=0x0000 */ movw %ax, %ds /* DS=0x0000 */ pushw %ds pushw %es movw $0x0202, %ax /* read 2 sectors ... */ movw $0x7A00, %bx /* ... to 0000:7A00 */ //pushw %bx /* BX=0x7c00, for the offset of 0000:7c00 */ movw $0x0001, %cx /* from the first sector ... */ movw $0x0080, %dx /* ... of the first hard drive */ stc int $0x13 sti popw %es popw %ds jc 1f testb %ah, %ah jnz 1f cmpw $0xAA55, 0x7dfe jne 1f cmpw $0xAA55, 0x7bfe jne 1f /* has a valid partition table ? */ movw $0x7dbe, %si 3: cmpw $0x7dfe, %si jnb 3f /* partition table is OK */ movw $4, %cx movw %si, %di 2: lodsl negl %eax jc 2f loop 2b /* empty entry, check next */ jmp 3b 2: /* non-empty entry */ movw %di, %si lodsw shlb $1, %al jnz 2f lodsw andb $63, %al jz 2f lodsw lodsw andb $63, %al jz 2f lodsl negl %eax jnc 2f lodsl negl %eax jc 3b 2: stc /* invalid partition table */ 3: pushfw /* disable the boot of non-MBR bootsector ? */ testb $2, %cs:0x02 /* test bit1 of the third byte */ jz 2f /* zero means non-MBR enabled */ popfw jc 1f /* invalid partition table, print "Error" */ /* the partition table is valid */ pushfw 2: /* the check passed, and the boot is permitted */ popfw jc 2f /* invalid partition table */ /* use partition table in MBR instead */ /* copy 72 bytes at 0000:7bb8 to 0000:7db8 */ movw $0x7bb8, %si movw $0x7db8, %di movw $36, %cx cld repz movsw 2: testb $0x80, %cs:0x02 /* test bit 7 of the third byte */ jz 2f /* zero means boot prev-MBR first */ movw $(Cannot_find_GRLDR_string - _start1), %si call print_message /* CS:SI points to message string */ //#if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) movw $(press_space_bar_string - _start1), %si cmpw $0x3920, %cs:0x04 je 3f movw $0x3920, %cs:0x04 #;movw $(press_hot_key_string - _start1), %si 3: call print_message /* CS:SI points to message string */ movw $(prev_MBR_string - _start1), %si call print_message /* CS:SI points to message string */ //#else // movw $(press_hot_key_pre - _start1), %si // call print_message // movw $(press_hot_key_name - _start1), %si // call print_message // movw $(press_hot_key_sub - _start1), %si // call print_message //#endif 3: call sleep_5_seconds /* if hot-key is pressed, wait forever until another key is pressed. */ movb $0xff, %cs:0x03 jc 3b /* desired hot-key is pressed */ 2: /* boot the previous MBR */ /* clear the DUCE indicator */ movl $0, 0x5FC /* DS=ES=0 */ //movb $0x80, %dl ljmp $0, $0x7c00 1: /* no previous MBR, print "Error" */ ///* Note the 0000:7C00 is on the stack */ //popw %ax /* AX=0x0000 */ //popw %ax /* AX=0x7C00 */ testb $0x80, %cs:0x02 /* are we called prior to the GRLDR search? */ jnz 1f /* no, it is a failure at last */ /* yes, so return to the caller */ movw $(continue_string - _start1), %si call print_message /* CS:SI points to message string */ call sleep_5_seconds ret 1: movw $(message_string_helper - _start1), %si call print_message /* CS:SI points to message string */ 1: jmp 1b /* hang */ sleep_5_seconds: /* sleep 5 seconds */ /* sleep forever if %cs:0x03 is 0xff */ /* calculate the timeout ticks */ pushw %ds pushl %esi pushl %edx movl $0xffffffff, %edx movzbl %cs:0x03, %eax cmpb $0xff, %al je 1f movl $18, %edx /* 18.2 ticks per second. We simply use 18. */ mulw %dx /* EDX=0, EAX=ticks */ xchgw %ax, %dx /* EAX=0, EDX=ticks */ 1: xorw %ax, %ax movw %ax, %ds movl 0x46c, %eax /* initial tick */ movl %eax, %ecx /* ECX=initial tick */ testl %edx, %edx js 1f addl %edx, %eax /* EAX=timeout tick */ pushl %eax movzbl %cs:0x03, %eax orl %eax, %eax jz 3f movw $(hot_key_timeout_pre - _start1), %si pushl %eax call print_message popl %eax movw $(hot_key_timeout_num - _start1), %si call print_decimal 3: movl %ecx, %esi addl $18, %esi popl %eax jmp 3f 1: movl %edx, %eax /* EAX=0xffffffff */ movl %edx, %esi 3: movl 0x46c, %ebx /* EBX=current tick */ cmpl %ecx, %ebx jnb 2f /* current tick is less than initial tick, this means the ticks have * overflowed to the next day, and EBX is rather small. */ xorl %ecx, %ecx movl %edx, %eax movl $18, %esi 2: /* check if there is any key press. */ pushl %eax movb $1, %ah int $0x16 pushw %ax pushfw movb $0x11, %ah int $0x16 jnz 1f popfw jnz 2f /* no, there is no key press. */ popw %ax popl %eax cmpl %esi, %ebx jb 4f pushl %esi pushl %eax pushl %edx subl %esi, %eax xorl %edx, %edx movl $18, %esi divl %esi movw $(hot_key_timeout_num - _start1), %si pushl %ebx call print_decimal popl %ebx popl %edx popl %eax popl %esi addl $18, %esi 4: cmpl %eax, %ebx /* timeout? */ jbe 3b /* no, continue to wait */ /* timeout reached, CF=0, no key pressed. */ popl %edx popl %esi popw %ds ret 1: popfw 2: /* yes, there is a key press. */ #if 0 /* clear the keyboard buffer */ movb $1, %ah int $0x16 jz 1f /* no keys, end */ movb $0, %ah int $0x16 /* discard the key */ jmp 1b 1: #endif /* check if it is the desired key. */ xorw %cs:0x04, %ax /* CF=0 */ popw %ax je 1f xorw %cs:0x04, %ax /* CF=0 */ jne 2f /* not desired, return CF=0 */ /* remove the desired key from the keyboard buffer. */ movb $0, %ah int $0x16 /* discard the key */ jmp 3f 1: /* remove the desired key from the keyboard buffer. */ movb $0x10, %ah int $0x16 /* discard the key */ 3: stc /* CF=1, the desired key pressed */ 2: popl %eax popl %edx popl %esi popw %ds ret out_decimal: /* * input: EAX = number, CS:SI = buffer */ pushl %edx pushl %ecx pushw %bx movl $10, %ecx movw %si, %bx 1: xorl %edx, %edx divl %ecx addb $'0', %dl movb %dl, %cs:(%si) incw %si orl %eax, %eax jnz 1b pushw %si 1: decw %si cmpw %bx, %si jbe 1f movb %cs:(%si), %al xchgb %al, %cs:(%bx) movb %al, %cs:(%si) incw %bx jmp 1b 1: popw %si popw %bx popl %ecx popl %edx ret print_decimal: pushw %si call out_decimal 1: cmpb $'\b', %cs:(%si) jz 2f movb $' ', %cs:(%si) incw %si jmp 1b 2: popw %si call print_message ret #if 0 modify_NTFS_boot_record: /* before the call: * AH= partition number * AL= 0xB6 ; 0xB6 is opcode of "MOV DH,imm8" * DL= drive number * * on return: CF=0 if there is NTFS boot record; * CF=1 otherwise. * CF of flags_orig on the stack will set if CF=1 */ /* * * the current stack is: * * SP + 40 : DS * SP + 38 : ES * SP + 34 : EAX * SP + 30 : ECX * SP + 26 : EDX * SP + 22 : EBX * SP + 18 : ESP_temp * SP + 14 : EBP * SP + 10 : ESI * SP + 6 : EDI * SP + 4 : flags_orig * SP + 2 : SI ; SI points to old entry in MBR * SP : return_IP * */ /* DS=ES=FS_BOOT */ /* change NTLDR to GRLDR */ /* check GR or NT or anything else */ pushw %ax movw $0x200, %si lodsw cmpw $5, %ax jne 1f /* failure */ lodsw testb %ah, %ah /* high byte of unicode ASCII should be 0 */ jne 1f /* failure */ /* 'N' should be a capital letter */ cmpb $0x41, %al /* Less than 'A' */ jb 1f /* failure */ cmpb $0x5A, %al /* Greater than 'Z'*/ ja 1f /* failure */ xchgw %ax, %cx /* save AX to CX. CL='N' */ lodsw testb %ah, %ah /* high byte of unicode ASCII should be 0 */ jne 1f /* failure */ /* 'T' should be a capital letter */ cmpb $0x41, %al /* Less than 'A' */ jb 1f /* failure */ cmpb $0x5A, %al /* Greater than 'Z'*/ ja 1f /* failure */ movb %al, %ch /* save AL to CH. CH='T' */ lodsw cmpw $0x4C, %ax /* 'L' */ jne 1f /* failure */ lodsw cmpw $0x44, %ax /* 'D' */ jne 1f /* failure */ lodsw cmpw $0x52, %ax /* 'R' */ jne 1f /* failure */ lodsw cmpw $0x04, %ax /* length of "$I30" */ jne 1f /* failure */ lodsw cmpw $0x24, %ax /* '$' */ jne 1f /* failure */ lodsw cmpw $0x49, %ax /* 'I' */ jne 1f /* failure */ lodsw cmpw $0x33, %ax /* '3' */ jne 1f /* failure */ lodsw cmpw $0x30, %ax /* '0' */ jne 1f /* failure */ /* assume it is NT bootsector. first, find "NTLDR". CX holds "NT" */ movw $0x0100, %di movb %cl, %al /* AL="N" */ movb $1, %ah /* AH=Carry for SAHF below */ movl $0x52444c00, %ebx /* "LDR" */ movb %ch, %bl /* 'T' */ movw $0x00fa, %cx /* now AL holds 'N' and BL holds 'T' */ //cld /* already upward */ 3: repnz scasb /* find "N" */ jcxz 4f /* gets the end, exit */ cmpl %ebx, (%di) /* is it "NTLDR"? */ jnz 3b /* no, continue to find */ /* "NTLDR" is found, so we believe it is NT boot sector. */ movw $0x5247, -1(%di) /* change "NT" to "GR" */ /* CF=0 for now */ lahf /* Load Flags into AH */ /* AH = SF:ZF:xx:AF:xx:PF:xx:CF */ /* AH = binary xxxxxxx0 */ jmp 3b 4: sahf /* Store AH into flags SF ZF xx AF xx PF xx CF */ /* CF=0 means "NTLDR" is found, CF=1 means "NTLDR" is not found. */ jc 1f /* failure */ movl $0x00520047, 0x202 /* change to "G R L D R" */ /* check NT 4.0 */ movw $0x406, %si movl (%si), %ebx /* NT 4.0 */ cmpl $0x03E8B800, %ebx /* MOV AX, 03E8 */ jnz 3f movl 0x84, %ebx cmpl $0x680007E8, %ebx /* call 008e; push (0D00) */ jnz 3f // movw 0x154, %bx /* CR LF at end of "A disk read error occurred." */ // cmpw $0x0A0D, %bx /* CR LF */ // jnz 3f // movw 0x180, %bx /* CR LF at end of "A kernel file is missing from the disk." */ // cmpw $0x0A0D, %bx /* CR LF */ // jnz 3f // movw 0x1A8, %bx /* CR LF at end of "A kernel file is too discontiguous." */ // cmpw $0x0A0D, %bx /* CR LF */ // jnz 3f // movw 0x1F8, %bx /* CR LF at end of "NTLDR is compressed." */ // cmpw $0x0A0D, %bx /* CR LF */ // jnz 3f movl 0xE8, %ebx cmpl $0x13CD80B2, %ebx /* "B2 80"="mov DL, 80", "CD 13"="int 13" */ jnz 3f popw %ax movw %ax, 4(%si) movl $0x68909090, %ebx /* nop;nop;nop;push (0D00) */ movl %ebx, 0x84 // /* change CRLF in NTFS error messages to spaces */ // movw $0x2020, %bx /* change CRLF to 2 spaces */ // movw %bx, 0x154 // movw %bx, 0x180 // movw %bx, 0x1A8 // movw %bx, 0x1F8 movb %dl, 0xE9 /* modify drive number */ /* modify NTFS boot record */ movb $0xea, %al /* ljmp, hand over the control to supervisor */ movb %al, 0x122 //movw $(try_next_partition - _start1), %ax /* offset for ljmp */ movw $MONITOR, %ax /* offset for ljmp */ movw %ax, 0x123 //movw %cs, %ax /* AX=0x9400, segment for ljmp */ xorw %ax, %ax movw %ax, 0x125 movw $(NTFS4_message - _start1), %si call print_message /* CS:SI points to message string */ clc ret 3: /* check NT 5.0 */ movw $0x44b, %si movl (%si), %ebx /* NT 5.0 */ cmpl $0x03E8B800, %ebx /* MOV AX, 03E8 */ jz 2f movw $0x479, %si movl (%si), %ebx /* NT 5.1 SP2 */ cmpl $0x03E8B800, %ebx /* MOV AX, 03E8 */ jnz 1f 2: movl 0x71, %ebx cmpl $0x680053E8, %ebx /* call 00C7; push (0D00) */ jnz 1f //movw 0x183, %bx /* CR LF at begin of "A disk read error occurred." */ movb 0x1F8, %bl movb $1, %bh movw (%bx), %bx cmpw $0x0A0D, %bx /* CR LF */ jnz 1f //movw 0x1A0, %bx /* CR LF at begin of "NTLDR is missing." */ movb 0x1F9, %bl movb $1, %bh movw (%bx), %bx cmpw $0x0A0D, %bx /* CR LF */ jnz 1f //movw 0x1B3, %bx /* CR LF at begin of "NTLDR is compressed." */ movb 0x1FA, %bl movb $1, %bh movw (%bx), %bx cmpw $0x0A0D, %bx /* CR LF */ jnz 1f popw %ax movw %ax, 4(%si) movl $0x68909090, %ebx /* nop;nop;nop;push (0D00) */ movl %ebx, 0x71 /* change CRLF in NTFS error messages to spaces */ movw $0x2020, %ax movb 0x1F8, %bl movb $1, %bh movw %ax, (%bx) // 0x183 movb 0x1F9, %bl movb $1, %bh movw %ax, (%bx) // 0x1A0 movb 0x1FA, %bl movb $1, %bh movw %ax, (%bx) // 0x1B3 /* modify NTFS boot record */ movb $0xEA, %al /* ljmp, hand over the control to supervisor */ movb %al, 0x167 //movw $(try_next_partition - _start1), %ax /* offset for ljmp */ movw $MONITOR, %ax /* offset for ljmp */ movw %ax, 0x168 //movw %cs, %ax /* AX=0x9400, segment for ljmp */ xorw %ax, %ax movw %ax, 0x16A cmpw $0x44b, %si jne 2f movw $(NTFS5_message - _start1), %si jmp 3f 2: movw $(NTFS5p_message - _start1), %si 3: call print_message /* CS:SI points to message string */ clc ret 1: /* NTFS boot record not found. */ movw $(NTFS_no_boot_record_message - _start1), %si call print_message /* CS:SI points to message string */ popw %ax popl %eax /* return_IP and SI */ popfw stc pushfw pushl %eax /* return_IP and SI */ ret #endif //#if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) move_helper: /* called only once and only when the boot loader loaded this code */ pushw %si pushw %bx pushl %eax movw $0x0003, %ax /* set display mode: 80*25 color text */ int $0x10 movw $0x200, %si movw %si, %di movw $0xf00, %cx cld repz movsw popl %eax popw %bx popw %si ret //#endif #if (defined(GRLDR_MBR)) || (defined(GRLDR_INSTALL)) filesystem_boot: /* The partition boot record successfully modified, just boot it */ /* * The boot might fail, but we want to take back the control. * So we save the registers now. */ pushw %ds pushw %es pushal /* DS=CS=GRLDR_CS, ES=FS_BOOT */ /* save GRLDR_CS */ movw %es, %bx # save old ES to BX cli lgdt gdt - _start1 movl %cr0, %eax orb $1, %al movl %eax, %cr0 movw $8, %si movw %si, %es xorl %esi, %esi xorl %edi, %edi movl $(0x9000 / 4), %ecx cld repz movsl movw $16, %si movw %si, %es andb $0xfe, %al movl %eax, %cr0 movw %bx, %es # restore ES from BX /* move FS_BOOT:0000 to 0:7c00 */ #if 0 /* for single sector boot record */ movw $0x0200, %cx /* move 2 sectors, the old FS_BOOT:0000 will * keep untouched. */ #else /* for 4-sector NTFS boot record */ movw $0x0400, %cx /* move 4 sectors, the old FS_BOOT:0000 will * keep untouched. */ #endif xorw %si, %si pushw %si /* SI=0, for the segment of 0000:7c00 */ movw $0x7c00, %di pushw %di /* DI=0x7c00, for the offset of 0000:7c00 */ pushw %es /* ES=FS_BOOT */ popw %ds /* DS=FS_BOOT */ pushw %si /* SI=0 */ popw %es /* ES=0 */ cld repz movsw movw $MONITOR, %di movw $(restore_GRLDR_CS - _start1), %si movw $((gdt_end - restore_GRLDR_CS) / 4), %cx cld repz cs movsl /* CS segment override prefix(=0x2E) */ pushw %es /* ES=0 */ popw %ds /* DS=0 */ sti lret //ljmp $0, $0x7c00 #endif press_space_bar_string: .ascii "\r\nPress space bar\0" press_hot_key_pre: .ascii "\r\nPress \0" press_hot_key_sub: .ascii " to start GRUB, any other key to boot previous MBR ...\0" hot_key_timeout_pre: .ascii "\r\nTimeout : \0" hot_key_timeout_num: .ascii " \b\b\b\0" continue_string: .ascii "\r\nInvalid previous MBR. Press any key to start GRUB ...\0" Cannot_find_GRLDR_string: .ascii "\r\nCannot find GRLDR.\0" prev_MBR_string: .ascii " to hold the screen, any other key to boot previous MBR ...\0" Error_while_reading_string: .ascii "\r\nError while reading MBR of \0" drive_number_string: .ascii "drive (hd0 ) \0" partition_boot_indicator_string: .ascii "\r\nInvalid boot indicator in partition table of \0" partition_sectors_per_track_string: .ascii "\r\nInvalid sectors_per_track in partition table of \0" partition_start_sector_string: .ascii "\r\nInvalid start_sector in partition table of \0" partition_end_sector_string: .ascii "\r\nInvalid end_sector in partition table of \0" no_boot_signature_string: .ascii "\r\nNo boot signature in partition table of \0" message_string_helper: .ascii "\r\nError: Cannot find GRLDR in all devices. Press Ctrl+Alt+Del to restart.\0" partition_message: .ascii "\r\nTry (hd0,0 ) : \0" EXT2_message: .ascii "EXT2: \0" NTFS4_message: .ascii "NTFS4: \0" NTFS5_message: .ascii "NTFS5: \0" NTFS5p_message: .ascii "NTFS5p: \0" FAT32_message: .ascii "FAT32: \0" FAT16_message: .ascii "FAT16: \0" FAT12_message: .ascii "FAT12: \0" non_MS_message: .ascii "non-MS: skip \0" extended_message: .ascii "Extended: \0" invalid_message: .ascii "invalid or null \0" #if 0 NTFS_no_boot_record_message: .ascii "This partition is NTFS but with unknown boot record. Please\r\ninstall Microsoft NTFS boot sectors to this partition correctly, or create an\r\nFAT12/16/32 partition and place the same copy of GRLDR and MENU.LST there.\0" #endif #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) . = _start1 + 0x1ffa #else . = . + (0x3ec - ((. - _start1) % 0x200)) % 0x200 press_hot_key_name: /* hot key name, the address is (grldr_signature - 16) */ .ascii "hot-key\0" . = press_hot_key_name + 14 //. = . + (0x3fa - ((. - _start1) % 0x200)) % 0x200 #endif /* version word of grldr.mbr, the address is (grldr_signature - 2) */ .word 2 grldr_signature: .byte 0x47, 0x52, 0x55, 0xaa /* signature for helper */ .align 0x200 #if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) /* pre_stage2 start at 0x2000 for grldr */ . = _start1 + 0x2000 #endif #if defined(GRLDR_MBR) /* if the size is less than 8192, let it be 8192 */ . = . + (0x2000 - (. - _start1)) * (0x4000 / (. - _start1 + 0x2001)) #endif pre_stage2_start: debian/grub-extras/ntldr-img/Makefile.core.common0000664000000000000000000000177012524662415017222 0ustar if COND_i386_pc # Compatibility symlink. g2hdr.bin: g2hdr.img rm -f $@ $(LN_S) $< $@ platform_DATA += g2hdr.bin CLEANFILES += g2hdr.bin g2ldr.mbr: g2ldr.img head -c 8192 $< > $@ platform_DATA += g2ldr.mbr CLEANFILES += g2ldr.mbr grldr.mbr: grldr.img head -c 8192 $< > $@ CLEANFILES += grldr.mbr bin2h: contrib/ntldr-img/bin2h.c $(BUILD_CC) $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) $^ -o $@ CLEANFILES += bin2h grub_mbr.h: grldr.mbr bin2h ./bin2h grub_mbr 8192 < $< > $@ CLEANFILES += grub_mbr.h grub-ntldr-img$(EXEEXT): contrib/ntldr-img/grubinst.c contrib/ntldr-img/utils.c grub_mbr.h $(HOST_CC) $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(HOST_LDFLAGS) -DGRUB_UTIL=1 -I. -I$(srcdir)/contrib/ntldr-img -DLINUX -o $@ $(srcdir)/contrib/ntldr-img/grubinst.c $(srcdir)/contrib/ntldr-img/utils.c bin_PROGRAMS += grub-ntldr-img CLEANFILES += grub-ntldr-img # Compatibility symlink. grubinst$(EXEEXT): grub-ntldr-img$(EXEEXT) rm -f $@ $(LN_S) $< $@ noinst_PROGRAMS += grubinst CLEANFILES += grubinst endif debian/grub-extras/ntldr-img/README0000664000000000000000000000043612524662415014222 0ustar grub-extras is meant to be used as an overlay on grub2 source tree. Build instructions: - Copy grub-extras in a subdirectory of your grub2 checkout. For example, "grub-extras". - Export GRUB_CONTRIB environment variable to point to this directory. - Build GRUB as usual. debian/grub-extras/ntldr-img/version.h0000664000000000000000000000007612524662415015200 0ustar #define VERSION "1.1" #define VER_MAJOR 1 #define VER_MINOR 1 debian/grub-extras/ntldr-img/COPYING0000664000000000000000000010451312524662415014376 0ustar GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . debian/grub-extras/ntldr-img/utils.c0000664000000000000000000002166412524662415014654 0ustar /* * GRUB Utilities -- Utilities for GRUB Legacy, GRUB2 and GRUB for DOS * Copyright (C) 2007 Bean (bean123@126.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef LINUX #define _FILE_OFFSET_BITS 64 // This is required to enable 64-bit off_t #include #endif #include #include #include #include "utils.h" static unsigned char ebuf[512]; #if defined(WIN32) #ifdef __GNUC__ // Mingw or Cygwin #define u_off_t off64_t #define u_lseek lseek64 #else #define u_off_t __int64 #define u_lseek _lseeki64 #endif #else #define u_off_t off_t // In FreeBSD, off_t is 64-bit ! #define u_lseek lseek #endif int go_sect(int hd,unsigned long sec) { // Test if 64-bit seek is supported if (sizeof(u_off_t)>=8) { u_off_t bs,rs; bs=sec; bs<<=9; rs=u_lseek(hd,bs,SEEK_SET); return (bs!=rs); } else { unsigned long bs[2]; bs[0]=sec<<9; bs[1]=sec>>23; if (bs[1]) return 1; return (lseek(hd,bs[0],SEEK_SET)!=(off_t)bs[0]); } } // Partition enumerator // xe->cur is the current partition number, before the first call to xd_enum, // it should be set to 0xFF // xe->nxt is the target partition number, if it equals 0xFF, it means enumerate // all partitions, otherwise, it means jump to the specific partition. int xd_enum(int hd,xde_t* xe) { int nn=512,kk=1,cc; for (cc=xe->cur;;) { if (cc==0xFF) { unsigned long pt[4][2]; int i,j,np; if (go_sect(hd,0)) return 1; if (read(hd,ebuf,nn)!=nn) return 1; if (get16(ebuf,0x1FE)!=0xAA55) return 1; np=0; for (i=0x1BE;i<0x1FE;i+=16) if (ebuf[i+4]) { if ((pt[np][1]=get32(ebuf,i+12))==0) return 1; pt[np++][0]=get32(ebuf,i+8); } if (np==0) return 1; // Sort partition table base on start address for (i=0;ipt[j][0]) k=j; if (k!=i) { unsigned long tt; tt=pt[i][0]; pt[i][0]=pt[k][0]; pt[k][0]=tt; tt=pt[i][1]; pt[i][1]=pt[k][1]; pt[k][1]=tt; } } // Should have space for MBR if (pt[0][0]==0) return 1; // Check for partition overlap for (i=0;ipt[i+1][0]) return 1; cc=0; } else if (kk) cc++; if ((unsigned char)cc>xe->nxt) return 1; if (cc<4) { if (xe->nxt<4) { // Empty partition if (! ebuf[xe->nxt*16+4+0x1BE]) return 1; xe->cur=xe->nxt; xe->dfs=ebuf[xe->nxt*16+4+0x1BE]; xe->bse=get32(ebuf,xe->nxt*16+8+0x1BE); xe->len=get32(ebuf,xe->nxt*16+12+0x1BE); return 0; } else if (xe->nxt!=0xFF) cc=4; else while (cc<4) { if (ebuf[cc*16+4+0x1BE]) { xe->cur=cc; xe->dfs=ebuf[cc*16+4+0x1BE]; xe->bse=get32(ebuf,cc*16+8+0x1BE); xe->len=get32(ebuf,cc*16+12+0x1BE); return 0; } cc++; } } if ((cc==4) && (kk)) { int i; // Scan for extended partition for (i=0;i<4;i++) if ((ebuf[i*16+4+0x1BE]==5) || (ebuf[i*16+4+0x1BE]==0xF)) break; if (i==4) return 1; xe->ebs=xe->bse=get32(ebuf,i*16+8+0x1BE); } else { // Is end of extended partition chain ? if (((ebuf[4+0x1CE]!=0x5) && (ebuf[4+0x1CE]!=0xF)) || (get32(ebuf,8+0x1CE)==0)) return 1; xe->bse=xe->ebs+get32(ebuf,8+0x1CE); } { while (1) { if (go_sect(hd,xe->bse)) return 1; if (read(hd,ebuf,nn)!=nn) return 1; if (get16(ebuf,0x1FE)!=0xAA55) return 1; if ((ebuf[4+0x1BE]==5) || (ebuf[4+0x1BE]==0xF)) { if (get32(ebuf,8+0x1BE)==0) return 1; else { xe->bse=xe->ebs+get32(ebuf,8+0x1BE); continue; } } break; } kk=(ebuf[4+0x1BE]!=0); if ((kk) && ((xe->nxt==0xFF) || (cc==xe->nxt))) { xe->cur=cc; xe->dfs=ebuf[4+0x1BE]; xe->bse+=get32(ebuf,8+0x1BE); xe->len=get32(ebuf,12+0x1BE); return 0; } } } } #define EXT2_SUPER_MAGIC 0xEF53 int mbr_nhd, mbr_spt; static void split_chs(unsigned char* chs,unsigned long* c,unsigned long* h,unsigned long* s) { *h=chs[0]; *s=(chs[1] & 0x3F)-1; *c=((unsigned long)(chs[1]>>6))*256+chs[2]; } static int chk_chs(unsigned long nhd,unsigned long spt,unsigned long lba,unsigned char* chs) { unsigned long c,h,s; split_chs(chs,&c,&h,&s); if (c==0x3FF) return ((nhd==h+1) && (spt==s+1)); else return (c*nhd*spt+h*spt+s==lba); } static int chk_mbr(unsigned char* buf) { unsigned long nhd,spt,a1,a2,c2,h2,s2; int i; i=0x1BE; while ((i<0x1FE) && (buf[i+4]==0)) i+=16; if (i>=0x1FE) return 0; a1=get32(&buf[i],8); a2=a1+get32(&buf[i],12)-1; if (a1>=a2) return 0; split_chs(buf+i+5,&c2,&h2,&s2); if (c2==0x3FF) { nhd=h2+1; spt=s2+1; if (! chk_chs(nhd,spt,a1,buf+i+1)) return 0; } else { unsigned long c1,h1,s1; long n1,n2; split_chs(buf+i+1,&c1,&h1,&s1); if ((c1==0x3FF) || (c1>c2)) return 0; n1=(long)(c1*a2)-(long)(c2*a1)-(long)(c1*s2)+(long)(c2*s1); n2=(long)(c1*h2)-(long)(c2*h1); if (n2<0) { n2=-n2; n1=-n1; } if ((n2==0) || (n1<=0) || (n1 % n2)) return 0; spt=(unsigned long)(n1/n2); if (c2) { n1=(long)a2-(long)s2-(long)(h2*spt); n2=(long)(c2*spt); if ((n2==0) || (n1<=0) || (n1 % n2)) return 0; nhd=(unsigned long)(n1/n2); } else nhd=h2+1; } if ((nhd==0) || (nhd>255) || (spt==0) || (spt>63)) return 0; i+=16; while (i<0x1FE) { if (buf[i+4]) { if ((! chk_chs(nhd,spt,get32(&buf[i],8),buf+i+1)) || (! chk_chs(nhd,spt,get32(&buf[i],8)+get32(&buf[i],12)-1,buf+i+5))) return 0; } i+=16; } mbr_nhd=(int)nhd; mbr_spt=(int)spt; return 1; } int get_fstype(unsigned char* buf) { if (chk_mbr(buf)) return FST_MBR; // The first sector of EXT2 might not contain the 0xAA55 signature if (get16(&buf[1024],56)==EXT2_SUPER_MAGIC) return FST_EXT2; if (get16(&buf[0],0x1FE)!=0xAA55) return FST_OTHER; if (! memcmp(&buf[0x36],"FAT",3)) return ((buf[0x26]==0x28) || (buf[0x26]==0x29))?FST_FAT16:FST_OTHER; if (! memcmp(&buf[0x52],"FAT32",5)) return ((buf[0x42]==0x28) || (buf[0x42]==0x29))?FST_FAT32:FST_OTHER; if (! memcmp(&buf[0x3],"NTFS",4)) return ((buf[0]==0xEB) && (buf[1]==0x52))?FST_NTFS:FST_OTHER; return FST_OTHER; } const char* fst2str(int fs) { switch (fs) { case FST_OTHER: return "Other"; case FST_MBR: return "MBR"; case FST_FAT16: return "FAT12/FAT16"; case FST_FAT32: return "FAT32"; case FST_NTFS: return "NTFS"; case FST_EXT2: return "EXT2/EXT3"; default: return "Unknown"; } } typedef struct { int id; const char* str; } fstab_t; static fstab_t fstab[]= { {0x1,"FAT12"}, {0x4,"FAT16"}, {0x5,"Extended"}, {0x6,"FAT16B"}, {0x7,"NTFS"}, {0xB,"FAT32"}, {0xC,"FAT32X"}, {0xE,"FAT16X"}, {0xF,"ExtendedX"}, {0x11,"(H)FAT12"}, {0x14,"(H)FAT16"}, {0x16,"(H)FAT16B"}, {0x17,"(H)NTFS"}, {0x1B,"(H)FAT32"}, {0x1C,"(H)FAT32X"}, {0x1E,"(H)FAT16X"}, {0x82,"Swap"}, {0x83,"Ext2"}, {0xA5,"FBSD"}, {0,"Other"}}; const char* dfs2str(int fs) { int i; for (i=0;fstab[i].id;i++) if (fs==fstab[i].id) return fstab[i].str; return fstab[i].str; } debian/grub-extras/ntldr-img/Makefile.core.def0000664000000000000000000000153612524662415016470 0ustar AutoGen definitions Makefile.tpl; image = { name = g2hdr; i386_pc = contrib/ntldr-img/g2hdr.S; i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x0'; objcopyflags = '-O binary'; enable = i386_pc; }; image = { name = grldr; i386_pc = contrib/ntldr-img/grldrstart.S; i386_pc = contrib/ntldr-img/ntfsbs.S; i386_pc_ccasflags = -DGRLDR_MBR; i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7c00'; objcopyflags = '-O binary'; enable = i386_pc; }; image = { name = g2ldr; i386_pc = contrib/ntldr-img/grldrstart.S; i386_pc = contrib/ntldr-img/ntfsbs.S; i386_pc_ccasflags = '-DGRLDR_MBR -DBOOTGRUB2'; i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7c00'; objcopyflags = '-O binary'; enable = i386_pc; }; debian/grub-pc.templates.in0000664000000000000000000001313612524662415013067 0ustar # This file is concatenated. Do not delete the newline above. Template: grub-pc/chainload_from_menu.lst Type: boolean Default: true #flag:translate!:6 _Description: Chainload from menu.lst? GRUB upgrade scripts have detected a GRUB Legacy setup in /boot/grub. . In order to replace the Legacy version of GRUB in your system, it is recommended that /boot/grub/menu.lst is adjusted to load a GRUB 2 boot image from your existing GRUB Legacy setup. This step can be automatically performed now. . It's recommended that you accept chainloading GRUB 2 from menu.lst, and verify that the new GRUB 2 setup works before it is written to the MBR (Master Boot Record). . Whatever your decision, you can replace the old MBR image with GRUB 2 later by issuing the following command as root: . upgrade-from-grub-legacy Template: grub-pc/install_devices Type: multiselect Choices-C: ${RAW_CHOICES} Choices: ${CHOICES} _Description: GRUB install devices: The grub-pc package is being upgraded. This menu allows you to select which devices you'd like grub-install to be automatically run for, if any. . Running grub-install automatically is recommended in most situations, to prevent the installed GRUB core image from getting out of sync with GRUB modules or grub.cfg. . If you're unsure which drive is designated as boot drive by your BIOS, it is often a good idea to install GRUB to all of them. . Note: it is possible to install GRUB to partition boot records as well, and some appropriate partitions are offered here. However, this forces GRUB to use the blocklist mechanism, which makes it less reliable, and therefore is not recommended. Template: grub-pc/install_devices_disks_changed Type: multiselect Choices-C: ${RAW_CHOICES} Choices: ${CHOICES} _Description: GRUB install devices: The GRUB boot loader was previously installed to a disk that is no longer present, or whose unique identifier has changed for some reason. It is important to make sure that the installed GRUB core image stays in sync with GRUB modules and grub.cfg. Please check again to make sure that GRUB is written to the appropriate boot devices. . If you're unsure which drive is designated as boot drive by your BIOS, it is often a good idea to install GRUB to all of them. . Note: it is possible to install GRUB to partition boot records as well, and some appropriate partitions are offered here. However, this forces GRUB to use the blocklist mechanism, which makes it less reliable, and therefore is not recommended. Template: grub-pc/disk_description Type: text # Disk sizes are in decimal megabytes, to match how disk manufacturers # usually describe them. _Description: ${DEVICE} (${SIZE} MB; ${MODEL}) Template: grub-pc/partition_description Type: text # The "-" is used to indicate indentation. Leading spaces may not work. _Description: - ${DEVICE} (${SIZE} MB; ${PATH}) Template: grub-pc/install_devices_failed Type: boolean Default: false #flag:translate!:3 _Description: Writing GRUB to boot device failed - continue? GRUB failed to install to the following devices: . ${FAILED_DEVICES} . Do you want to continue anyway? If you do, your computer may not start up properly. Template: grub-pc/install_devices_failed_upgrade Type: boolean Default: true #flag:translate!:3 _Description: Writing GRUB to boot device failed - try again? GRUB failed to install to the following devices: . ${FAILED_DEVICES} . You may be able to install GRUB to some other device, although you should check that your system will boot from that device. Otherwise, the upgrade from GRUB Legacy will be canceled. Template: grub-pc/install_devices_empty Type: boolean Default: false _Description: Continue without installing GRUB? You chose not to install GRUB to any devices. If you continue, the boot loader may not be properly configured, and when this computer next starts up it will use whatever was previously in the boot sector. If there is an earlier version of GRUB 2 in the boot sector, it may be unable to load modules or handle the current configuration file. . If you are already using a different boot loader and want to carry on doing so, or if this is a special environment where you do not need a boot loader, then you should continue anyway. Otherwise, you should install GRUB somewhere. Template: grub-pc/postrm_purge_boot_grub Type: boolean Default: false _Description: Remove GRUB 2 from /boot/grub? Do you want to have all GRUB 2 files removed from /boot/grub? . This will make the system unbootable unless another boot loader is installed. Template: grub-pc/mixed_legacy_and_grub2 Type: boolean Default: true #flag:translate!:3 _Description: Finish conversion to GRUB 2 now? This system still has files from the GRUB Legacy boot loader installed, but it now also has GRUB 2 boot records installed on these disks: . ${DISKS} . It seems likely that GRUB Legacy is no longer in use, and that you should instead upgrade the GRUB 2 images on these disks and finish the conversion to GRUB 2 by removing old GRUB Legacy files. If you do not upgrade these GRUB 2 images, then they may be incompatible with the new packages and cause your system to stop booting properly. . You should generally finish the conversion to GRUB 2 unless these boot records were created by a GRUB 2 installation on some other operating system. Template: grub-pc/kopt_extracted Type: boolean Default: false Description: for internal use Template: grub-pc/timeout Type: string Default: @DEFAULT_TIMEOUT@ Description: GRUB timeout; for internal use Template: grub-pc/hidden_timeout Type: boolean Default: @DEFAULT_HIDDEN_TIMEOUT_BOOL@ Description: Hide the GRUB timeout; for internal use debian/grub-common.links0000664000000000000000000000010012524662415012455 0ustar usr/share/grub/grub-mkconfig_lib usr/lib/grub/grub-mkconfig_lib debian/build-efi-images0000775000000000000000000000600712524662415012233 0ustar #! /bin/sh set -e # Copyright (C) 2010, 2011, 2012 Canonical Ltd. # Author: Colin Watson # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. # Make EFI boot images for signing. if [ $# -lt 5 ]; then echo "usage: $0 GRUB-MKIMAGE GRUB-CORE OUTPUT-DIRECTORY PLATFORM EFI-NAME" fi grub_mkimage="$1" grub_core="$2" outdir="$3" platform="$4" efi_name="$5" workdir= cleanup () { [ -z "$workdir" ] || rm -rf "$workdir" } trap cleanup EXIT HUP INT QUIT TERM rm -rf "$outdir" mkdir -p "$outdir" workdir="$(mktemp -d build-efi-images.XXXXXX)" # GRUB's rescue parser doesn't understand 'if'. echo 'normal (memdisk)/grub.cfg' >"$workdir/grub-bootstrap.cfg" # Skeleton configuration file which finds the real boot disk. cat >"$workdir/grub.cfg" <"$workdir/grub-netboot.cfg" <wZ㳪O<\Dp*eJ2);EǤ q䶥ʁv v&h0!a 4BXhwҠ]Xm}$ !ۦǀ7Vn|*| o=TDC{Th|q'L^0jHg}y)n;舯7o+cH*NwqUYC GGU6v8'dٞT5aPl4nUc_pt}@P9(^5sP0c8 ~Βg$>RG;{޾!$xp4p~f^LW7y_|Ĉi\5? ѵ t Eyk3sɩyeU A~ħe7Ȭ(~$x<ݾF/*G4ȥƍQTp叺|ҿ^PoEwbŐՙޤ+EhhS] !eQ uّ:字1ciVV-*4G3؂s'dkTǯd˳ ᠿj..nĮn\&)"ֿO%5M3N=S < z길slݣbm{޿Oab[*]48'ߟ/b;|Tɽ3 sL i^cEGNP&J8>,c5:dQU\JoN*1VS ;,yl ߅zK_|[D׽_`*T~^69B_&"0>|00ۀ_,حdSO>%ڗ0g*81A>Sޘݿv{`úͼ/@v]_&YfZ=0nQ9I|u `TGF! 1Vladimir 'phcoder' Serbinenko  'J f    5;t.B BbI7/ BR1&ۛMuV;$RSXӟe/ƦFL5 wݕRm'oBLLiě*wBͼ 6EBpFL5$ E)HĢtQ3ߞܹԽt~{I+X=E؈FL5j 6l.QJt:.e+%7Wz|(ZC\ J MCR!g}&9$P˚6job4(~ bu褴Odכum)+(.$E*"FM' g@P:m_yPŴm(VIu{.(ˍ"P[IX>p<$v[H=EALv CB4)< (70w[n j azKv| dn/Q$'"^{3y3:uIYvǤSttiU;(dNy_U>zoG:M4-WS &c[NM3W؞XMȞuH58ZTbsW-T+6-Vۺ Y@C;=}je&Yd_> "$tmpfile" echo "${setting}=\"${value}\"" >> "$tmpfile" fi } get_wubi_device() { if [ ! -x /usr/share/lupin-support/grub-mkimage ] || \ ! /usr/share/lupin-support/grub-mkimage --test; then return 1 fi local bootdev="$(grub-probe --target=device /boot)" || true local loop_file= case $bootdev in /dev/loop/*|/dev/loop[0-9]) loop_file="$(losetup "$bootdev" | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/")" # If it's loop-mounted from another device, it isn't Wubi. case $loop_file in /dev/*) return 1 ;; esac ;; *) return 1 ;; esac echo "$bootdev" } # This only works on a Linux system with udev running. This is probably the # vast majority of systems where we need any of this, though, and we fall # back reasonably gracefully if we don't have it. cached_available_ids= available_ids() { local id path if [ "$cached_available_ids" ]; then echo "$cached_available_ids" return fi [ -d /dev/disk/by-id ] || return cached_available_ids="$( for path in /dev/disk/by-id/*; do [ -e "$path" ] || continue printf '%s %s\n' "$path" "$(readlink -f "$path")" done | sort -k2 -s -u | cut -d' ' -f1 )" echo "$cached_available_ids" } # Returns non-zero and no output if no mapping can be found. device_to_id() { local id for id in $(available_ids); do if [ "$(readlink -f "$id")" = "$(readlink -f "$1")" ]; then echo "$id" return 0 fi done # Fall back to the plain device name if there's no by-id link for it. if [ -e "$1" ]; then echo "$1" return 0 fi return 1 } devices_to_ids() { local device id ids ids= for device; do id="$(device_to_id "$device" || true)" if [ "$id" ]; then ids="${ids:+$ids, }$id" fi done echo "$ids" } all_disks() { local id for id in $(available_ids); do case $id in *-part*) ;; *) echo "$id" ;; esac done } all_partitions() { local id ids ids= for id in $(available_ids); do if [ "$id" != "$1" ] && [ "${id%-part*}" = "$1" ]; then ids="${ids:+$ids }$id" fi done echo "$ids" } # In order to determine whether we accidentally ran grub-install without # upgrade-from-grub-legacy on versions older than 1.98+20100617-1, we need # to be able to scan a disk to determine whether GRUB 2 was installed in its # boot sector. This is specific to i386-pc (but that's the only platform # where we need it). scan_grub2() { if ! dd if="$1" bs=512 count=1 2>/dev/null | grep -aq GRUB; then # No version of GRUB is installed. return 1 fi # The GRUB boot sector always starts with a JMP instruction. initial_jmp="$(dd if="$1" bs=2 count=1 2>/dev/null | od -Ax -tx1 | \ head -n1 | cut -d' ' -f2,3)" [ "$initial_jmp" ] || return 1 initial_jmp_opcode="${initial_jmp%% *}" [ "$initial_jmp_opcode" = eb ] || return 1 initial_jmp_operand="${initial_jmp#* }" case $initial_jmp_operand in 47|4b|4c|63) # I believe this covers all versions of GRUB 2 up to the package # version where we gained a more explicit mechanism. GRUB Legacy # always had 48 here. return 0 ;; esac return 1 } # for Linux sysfs_size() { local num_sectors sector_size size # Try to find out the size without relying on a partitioning tool being # installed. This isn't too hard on Linux 2.6 with sysfs, but we have to # try a couple of variants on detection of the sector size. if [ -e "$1/size" ]; then num_sectors="$(cat "$1/size")" sector_size=512 if [ -e "$1/queue/logical_block_size" ]; then sector_size="$(cat "$1/queue/logical_block_size")" elif [ -e "$1/queue/hw_sector_size" ]; then sector_size="$(cat "$1/queue/hw_sector_size")" fi size="$(expr "$num_sectors" \* "$sector_size" / 1000 / 1000)" fi [ "$size" ] || size='???' echo "$size" } # for kFreeBSD camcontrol_size() { local num_sectors sector_size size= if num_sectors="$(camcontrol readcap "$1" -q -s -N)"; then sector_size="$(camcontrol readcap "$1" -q -b)" size="$(expr "$num_sectors" \* "$sector_size" / 1000 / 1000)" fi [ "$size" ] || size='???' echo "$size" } # Returns value in $RET, like a debconf command. describe_disk() { local disk id base size disk="$1" id="$2" model= case $(uname -s) in Linux) if which udevadm >/dev/null 2>&1; then size="$(sysfs_size "/sys$(udevadm info -n "$disk" -q path)")" else base="${disk#/dev/}" base="$(printf %s "$base" | sed 's,/,!,g')" size="$(sysfs_size "/sys/block/$base")" fi if which udevadm >/dev/null 2>&1; then model="$(udevadm info -n "$disk" -q property | sed -n 's/^ID_MODEL=//p')" if [ -z "$model" ]; then model="$(udevadm info -n "$disk" -q property | sed -n 's/^DM_NAME=//p')" if [ -z "$model" ]; then model="$(udevadm info -n "$disk" -q property | sed -n 's/^MD_NAME=//p')" if [ -z "$model" ] && which dmsetup >/dev/null 2>&1; then model="$(dmsetup info -c --noheadings -o name "$disk" 2>/dev/null || true)" fi fi fi fi ;; GNU/kFreeBSD) disk_basename=$(basename "$disk") size="$(camcontrol_size "$disk_basename")" model="$(camcontrol inquiry "$disk_basename" | sed -ne "s/^pass0: <\([^>]*\)>.*/\1/p")" ;; esac [ "$model" ] || model='???' db_subst grub-pc/disk_description DEVICE "$disk" db_subst grub-pc/disk_description SIZE "$size" db_subst grub-pc/disk_description MODEL "$model" db_metaget grub-pc/disk_description description } # Returns value in $RET, like a debconf command. describe_partition() { local disk part id path diskbase partbase size disk="$1" part="$2" id="$3" path="$4" if which udevadm >/dev/null 2>&1; then size="$(sysfs_size "/sys$(udevadm info -n "$part" -q path)")" else diskbase="${disk#/dev/}" diskbase="$(printf %s "$diskbase" | sed 's,/,!,g')" partbase="${part#/dev/}" partbase="$(printf %s "$partbase" | sed 's,/,!,g')" size="$(sysfs_size "/sys/block/$diskbase/$partbase")" fi db_subst grub-pc/partition_description DEVICE "$part" db_subst grub-pc/partition_description SIZE "$size" db_subst grub-pc/partition_description PATH "$path" db_metaget grub-pc/partition_description description } usable_partitions() { local last_partition path partition partition_id last_partition= for path in / /boot /boot/grub; do partition="$(grub-probe -t device "$path" || true)" if [ -z "$partition" ] || [ "$partition" = "$last_partition" ]; then continue fi partition_id="$(device_to_id "$partition" || true)" echo "$path:$partition_id" last_partition="$partition" done | sort -t: -k2 } get_mountpoint() { local relpath boot_mountpoint relpath="$(grub-mkrelpath "$1")" boot_mountpoint="${1#$relpath}" echo "${boot_mountpoint:-/}" } config_item() { for x in /etc/default/grub /etc/default/grub.d/*.cfg; do if [ -e "$x" ]; then . "$x" fi done if [ "$(eval echo "\${$1+set}")" = set ]; then eval echo "\$$1" else return fi } running_in_container() { type running-in-container >/dev/null 2>&1 && running-in-container >/dev/null } case "$1" in configure) . /usr/share/debconf/confmodule if dpkg --compare-versions "$2" lt-nl 1.99-1; then # Force dpkg to replace this directory with a symlink. if [ ! -L /usr/share/doc/@PACKAGE@ ] && [ -d /usr/share/doc/@PACKAGE@ ]; then if rmdir /usr/share/doc/@PACKAGE@ 2>/dev/null; then ln -sf grub-common /usr/share/doc/@PACKAGE@ fi fi fi devicemap_regenerated= if egrep -q '^[[:space:]]*post(inst|rm)_hook[[:space:]]*=[[:space:]]*(/sbin/|/usr/sbin/)?update-grub' /etc/kernel-img.conf 2>/dev/null; then echo 'Removing update-grub hooks from /etc/kernel-img.conf in favour of' >&2 echo '/etc/kernel/ hooks.' >&2 sed -ri /etc/kernel-img.conf -e '\%^[[:space:]]*post(inst|rm)_hook[[:space:]]*=[[:space:]]*(/sbin/|/usr/sbin/)?update-grub%d' fi case @PACKAGE@ in grub-pc) mkdir -p /boot/grub if test -e /boot/grub/device.map && ! test -e /boot/grub/core.img && \ ! test -e /boot/grub/@FIRST_CPU_PLATFORM@/core.img; then # Looks like your device.map was generated by GRUB Legacy, which # used to generate broken device.map (see #422851). Avoid the risk # by regenerating it. grub-mkdevicemap --no-floppy devicemap_regenerated=1 fi ;; esac if test -z "$devicemap_regenerated" && test -s /boot/grub/device.map && \ dpkg --compare-versions "$2" lt-nl 1.98+20100702-1 && \ test "$(uname -s)" = Linux; then # Earlier versions of GRUB used unstable device names in device.map, # which caused a variety of problems. There is some risk associated with # regenerating it (so we prompt the user if it's non-trivial), but on the # whole it's less risky to move to /dev/disk/by-id/. devicemap_lines="$(egrep -v '^[[:space:]]+#' /boot/grub/device.map | wc -l)" grub-mkdevicemap --no-floppy devicemap_regenerated=1 if test "$devicemap_lines" != 1; then db_input critical grub2/device_map_regenerated || true db_go || true fi fi if test -z "$devicemap_regenerated" && \ dpkg --compare-versions "$2" lt-nl 1.99~20101210-2 && \ grep -qs /md-uuid- /boot/grub/device.map; then echo "Removing MD devices from device.map, since the BIOS cannot read from these." >&2 sed -i '/\/md-uuid-/d' /boot/grub/device.map fi tmp_default_grub="$(mktemp -t grub.XXXXXXXXXX)" trap "rm -f ${tmp_default_grub}" EXIT cp -p /usr/share/grub/default/grub ${tmp_default_grub} merge_debconf_into_conf "$tmp_default_grub" GRUB_CMDLINE_LINUX grub2/linux_cmdline merge_debconf_into_conf "$tmp_default_grub" GRUB_CMDLINE_LINUX_DEFAULT grub2/linux_cmdline_default case @PACKAGE@ in grub-pc) merge_debconf_into_conf "$tmp_default_grub" GRUB_TIMEOUT grub-pc/timeout sed -i -e 's/^\(GRUB_TIMEOUT=\)"\([0-9][0-9]*\)"/\1\2/' "$tmp_default_grub" db_get grub-pc/hidden_timeout if [ "$RET" = false ]; then sed -i -e 's/^GRUB_HIDDEN_TIMEOUT=/#&/' "$tmp_default_grub" fi ;; esac ucf --three-way --debconf-ok --sum-file=/usr/share/grub/default/grub.md5sum ${tmp_default_grub} /etc/default/grub package="$(ucfq --with-colons /etc/default/grub | cut -d : -f 2)" if echo $package | grep -q "^grub-" ; then ucfr --force @PACKAGE@ /etc/default/grub else ucfr @PACKAGE@ /etc/default/grub fi case @PACKAGE@ in grub-pc) fix_mixed_system= if test -e /boot/grub/stage2 && test -e /boot/grub/menu.lst && \ ! test -e /boot/grub/grub2-installed && \ test -z "$UPGRADE_FROM_GRUB_LEGACY"; then # Unfortunately, it's still possible that the user upgraded fully # to GRUB 2 in some way other than running # upgrade-from-grub-legacy; perhaps they ran grub-install by hand # for some reason. It's really quite difficult to detect this # situation, because the only difference between this and a # working chainloaded setup is that in this case grub-setup has # been run. So, to try to tell the difference, we scan the boot # sectors of all disks for a GRUB 2 boot sector. Hopefully this # won't cause too much to explode, since I can't think of a better # method. grub2_disks= for disk in $(all_disks); do if scan_grub2 "$disk"; then grub2_disks="${grub2_disks:+$grub2_disks }$(readlink -f "$disk")" fi done if [ "$grub2_disks" ]; then # No || true here; it's vital that the user sees this, and it's # better to throw an error than to do the wrong thing. db_subst grub-pc/mixed_legacy_and_grub2 DISKS "$grub2_disks" db_input critical grub-pc/mixed_legacy_and_grub2 db_go db_get grub-pc/mixed_legacy_and_grub2 if [ "$RET" = true ]; then db_reset grub-pc/install_devices UPGRADE_FROM_GRUB_LEGACY=1 fix_mixed_system=1 # Fall through to normal installation logic. fi fi fi # Make sure that Wubi users never see confusing device prompts. # Wubi is a very specialised hack that does complicated things with # grub-install diversions to create an image that's chained from the # Windows boot loader to boot an operating system from a file on a # Windows file system. In these circumstances, prompting for where # to install GRUB is not going to help anyone. wubi_device="$(get_wubi_device)" || true if [ "$wubi_device" ]; then db_set grub-pc/install_devices "$wubi_device" db_fset grub-pc/install_devices seen true fi if test -e /boot/grub/stage2 && test -e /boot/grub/menu.lst && \ ! test -e /boot/grub/grub2-installed && \ test -z "$UPGRADE_FROM_GRUB_LEGACY"; then db_get grub-pc/chainload_from_menu.lst if $RET ; then # Create core.img (but do not risk writing to MBR). # Using grub-probe instead of "(hd0)" avoids (UUID=) hack slowness # in case /boot/grub is not on (hd0) in device.map. echo "Generating core.img" >&2 grub-install --target=i386-pc --no-floppy --grub-setup=/bin/true "$(grub-probe -t drive /boot/grub)" > /dev/null # Update menu.lst to reflect that: # - core.img is present now # - core.img has to be the first option echo "Saving menu.lst backup in /boot/grub/menu.lst_backup_by_grub2_postinst" >&2 cp /boot/grub/menu.lst{,_backup_by_grub2_postinst} echo "Running update-grub Legacy to hook our core.img in it" >&2 LET_US_TRY_GRUB_2=true /usr/lib/grub-legacy/update-grub 2>&1 | sed -e "s/^/ /g" >&2 # We just hooked GRUB 2 in menu.lst; then also generate grub.cfg. touch /boot/grub/grub.cfg fi elif running_in_container; then # Skip grub-install in containers. : elif test -z "$2" || test -e /boot/grub/core.img || \ test -e /boot/grub/@FIRST_CPU_PLATFORM@/core.img || \ test "$UPGRADE_FROM_GRUB_LEGACY" || test "$wubi_device"; then question=grub-pc/install_devices device_map="$(grub-mkdevicemap -m - | grep -v '^(fd[0-9]\+)' || true)" devices="$(echo "$device_map" | cut -f2)" if dpkg --compare-versions "$2" lt 1.98+20100702-1 && \ test "$(uname -s)" = Linux && [ -z "$wubi_device" ]; then # Migrate to new by-id naming scheme. db_get grub-pc/install_devices old_devices="$(echo "$RET" | sed 's/, / /g')" new_devices= # Common-case optimisation: if the list of devices is # identical to the LHS of grub-mkdevicemap's output, then # there's no point asking again; just install to all disks. # (This handles e.g. "(hd0)" with one disk.) if [ "$(echo "$device_map" | cut -f1 | sort)" = \ "$(echo "$old_devices" | xargs -n1 | sort)" ]; then new_devices="$(devices_to_ids $devices)" db_set grub-pc/install_devices "$new_devices" # Alternatively, we might be installing to a single partition # on a single disk, and we can deal with that too if there's # only one available disk and it has an appropriate partition. # This doesn't necessarily work for multiple disks because now # the order matters. elif [ "$(echo "$device_map" | wc -l)" = 1 ] && \ [ "$(echo "$old_devices" | wc -w)" = 1 ] && \ echo "$old_devices" | grep -q ,; then old_device="${old_devices#(}" old_device="${old_device%)}" old_disk="${old_device%,*}" old_partition="${old_device##*,}" new_device="$(echo "$device_map" | grep "^($old_disk)" | \ cut -f2)" new_device="$(device_to_id $new_device)" if [ "$new_device" ]; then new_device="$new_device-part$old_partition" # Run through device_to_id again to check for existence. new_device="$(device_to_id $new_device)" fi if [ "$new_device" ]; then new_devices="$new_device" db_set grub-pc/install_devices "$new_device" fi fi if [ -z "$new_devices" ]; then new_devices="$(devices_to_ids $old_devices)" db_set grub-pc/install_devices "$new_devices" # Common-case optimisation: if all devices are translatable # to by-id and the number of devices there is the same as # the number of devices GRUB can see, then there's no point # asking again. (This handles e.g. "/dev/sda" with one # disk.) old_devices_count="$(echo "$old_devices" | wc -w)" new_devices_count="$(echo "$new_devices" | wc -w)" devices_count="$(echo "$devices" | wc -w)" if [ "$old_devices_count" != "$new_devices_count" ] || \ [ "$new_devices_count" != "$devices_count" ]; then db_fset grub-pc/install_devices seen false db_fset grub-pc/install_devices_empty seen false fi fi else db_get grub-pc/install_devices valid=1 for device in $RET; do if [ ! -e "${device%,}" ]; then valid=0 break fi done if [ "$valid" = 0 ]; then question=grub-pc/install_devices_disks_changed db_set "$question" "$RET" db_fset "$question" seen false db_fset grub-pc/install_devices_empty seen false fi fi while :; do ids= descriptions= partitions="$(usable_partitions)" for device in $devices; do disk_id="$(device_to_id "$device" || true)" if [ "$disk_id" ]; then ids="${ids:+$ids, }$disk_id" describe_disk "$(readlink -f "$device")" "$disk_id" RET="$(printf %s "$RET" | sed 's/,/\\,/g')" descriptions="${descriptions:+$descriptions, }$RET" for partition_pair in $partitions; do partition_id="${partition_pair#*:}" if [ "${partition_id#$disk_id-part}" != "$partition_id" ]; then ids="${ids:+$ids, }$partition_id" describe_partition "$(readlink -f "$device")" "$(readlink -f "$partition_id")" "$partition_id" "$(get_mountpoint "${partition_pair%%:*}")" RET="$(printf %s "$RET" | sed 's/,/\\,/g')" descriptions="${descriptions:+$descriptions, }$RET" fi done fi done # Some "partitions" may in fact be at the disk level, e.g. RAID. # List these as well if they haven't already been listed. for partition_pair in $partitions; do partition_id="${partition_pair#*:}" if [ "${partition_id#*-part}" = "$partition_id" ]; then case ", $ids, " in ", $partition_id, ") ;; *) ids="${ids:+$ids, }$partition_id" describe_disk "$(readlink -f "$partition_id")" "$partition_id" RET="$(printf %s "$RET" | sed 's/,/\\,/g')" descriptions="${descriptions:+$descriptions, }$RET" ;; esac fi done db_subst "$question" RAW_CHOICES "$ids" db_subst "$question" CHOICES "$descriptions" db_input high "$question" || true db_go db_get "$question" failed_devices= for i in `echo $RET | sed -e 's/, / /g'` ; do real_device="$(readlink -f "$i")" if grub-install --target=i386-pc --force --no-floppy $real_device ; then # We just installed GRUB 2; then also generate grub.cfg. touch /boot/grub/grub.cfg else failed_devices="$failed_devices $real_device" fi done if [ "$question" != grub-pc/install_devices ]; then db_set grub-pc/install_devices "$RET" db_fset grub-pc/install_devices seen true fi if [ "$failed_devices" ]; then if [ "$UPGRADE_FROM_GRUB_LEGACY" ]; then db_subst grub-pc/install_devices_failed_upgrade FAILED_DEVICES "$failed_devices" db_fset grub-pc/install_devices_failed_upgrade seen false if db_input critical grub-pc/install_devices_failed_upgrade; then db_go db_get grub-pc/install_devices_failed_upgrade if [ "$RET" = true ]; then db_fset "$question" seen false db_fset grub-pc/install_devices_failed_upgrade seen false continue else exit 1 fi else exit 1 # noninteractive fi else db_subst grub-pc/install_devices_failed FAILED_DEVICES "$failed_devices" db_fset grub-pc/install_devices_failed seen false if db_input critical grub-pc/install_devices_failed; then db_go db_get grub-pc/install_devices_failed if [ "$RET" = true ]; then break else db_fset "$question" seen false db_fset grub-pc/install_devices_failed seen false continue fi else break # noninteractive fi fi fi db_get grub-pc/install_devices if [ -z "$RET" ]; then # Reset the seen flag if the current answer is false, since # otherwise we'll loop with no indication of why. db_get grub-pc/install_devices_empty if [ "$RET" = false ]; then db_fset grub-pc/install_devices_empty seen false fi if db_input critical grub-pc/install_devices_empty; then db_go db_get grub-pc/install_devices_empty if [ "$RET" = true ]; then break else db_fset "$question" seen false db_fset grub-pc/install_devices_empty seen false fi else break # noninteractive fi else break fi done fi # /boot/grub/ has more chances of being accessible by GRUB if test -e /boot/grub/grub.cfg ; then for i in /usr/share/grub/unicode.pf2 ; do if test -e $i ; then cp $i /boot/grub/ fi done fi if [ "$fix_mixed_system" ]; then # These never contain any valuable information, and they aren't # useful for boot any more, since we just overwrote MBR/PBR. rm -f /boot/grub/{{xfs,reiserfs,e2fs,fat,jfs,minix}_stage1_5,stage{1,2}} # Remove marker file used to indicate that grub-install was run # rather than upgrade-from-grub-legacy. Since stage2 has been # removed, we don't need this any more. rm -f /boot/grub/grub2-installed fi ;; grub-efi-ia32|grub-efi-amd64|grub-efi-ia64|grub-efi-arm|grub-efi-arm64) bootloader_id="$(config_item GRUB_DISTRIBUTOR | tr A-Z a-z | \ cut -d' ' -f1)" case $bootloader_id in kubuntu) bootloader_id=ubuntu ;; esac if [ "$bootloader_id" ] && [ -d "/boot/efi/EFI/$bootloader_id" ]; then case @PACKAGE@ in grub-efi-ia32) target=i386-efi ;; grub-efi-amd64) target=x86_64-efi ;; grub-efi-ia64) target=ia64-efi ;; grub-efi-arm) target=arm-efi ;; grub-efi-arm64) target=arm64-efi ;; esac grub-install --target="$target" fi # /boot/grub/ has more chances of being accessible by GRUB for i in /usr/share/grub/unicode.pf2 ; do if test -e $i ; then mkdir -p /boot/grub cp $i /boot/grub/ fi done ;; grub-ieee1275) case $(dpkg --print-architecture) in ppc64el) grub-install --target=powerpc-ieee1275 ;; esac ;; grub-yeeloong) grub-install --target=mipsel-loongson ;; esac # If grub.cfg has been generated, update it. if test -e /boot/grub/grub.cfg && ! running_in_container; then update-grub 3>&- fi ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 debian/rules0000775000000000000000000004526112524662415010267 0ustar #!/usr/bin/make -f SHELL := bash deb_version := $(shell dpkg-parsechangelog | sed -ne "s/^Version: \(.*\)/\1/p") upstream_version := $(shell echo $(deb_version) | sed -e "s/-[^-]*$$//") package := grub2 DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH 2>/dev/null) DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS 2>/dev/null) DEB_HOST_ARCH_CPU ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_CPU 2>/dev/null) HOST_CFLAGS := -g -Wall -Wno-error=unused-result ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) HOST_CFLAGS += -O0 else HOST_CFLAGS += -O2 endif unexport CFLAGS export HOST_CFLAGS export TARGET_CPPFLAGS := -Wno-unused-but-set-variable ifeq (,$(shell which qemu-system-i386 2>/dev/null)) with_check := no else with_check := yes endif ifeq ($(DEB_HOST_ARCH_CPU),ppc64el) CC := gcc-4.8 else CC := gcc-4.7 endif confflags = PACKAGE_VERSION="$(deb_version)" PACKAGE_STRING="GRUB $(deb_version)" CC=$(CC) TARGET_CC=$(CC) --enable-grub-mkfont AUTOGEN_DEB_FILES = config templates preinst postinst postrm dirs install links maintscript BUILD_PACKAGES := $(strip $(shell dh_listpackages)) REAL_PACKAGES = grub-emu grub-pc grub-coreboot grub-efi-ia32 grub-efi-amd64 grub-efi-ia64 grub-efi-arm grub-efi-arm64 grub-ieee1275 grub-firmware-qemu grub-uboot grub-xen grub-yeeloong ifneq (,$(filter i386 amd64,$(DEB_HOST_ARCH_CPU))) COMMON_PLATFORM := pc else ifneq (,$(filter powerpc ppc64 ppc64el sparc,$(DEB_HOST_ARCH_CPU))) COMMON_PLATFORM := ieee1275 else ifeq (mipsel,$(DEB_HOST_ARCH_CPU)) COMMON_PLATFORM := yeeloong else ifeq (ia64,$(DEB_HOST_ARCH_CPU)) COMMON_PLATFORM := efi-ia64 else ifeq (arm,$(DEB_HOST_ARCH_CPU)) COMMON_PLATFORM := uboot else ifeq (arm64,$(DEB_HOST_ARCH_CPU)) COMMON_PLATFORM := efi-arm64 else $(error COMMON_PLATFORM not set for $(DEB_HOST_ARCH_CPU)) endif ifeq (yes,$(shell dpkg-vendor --derives-from Ubuntu && echo yes)) DEFAULT_CMDLINE := quiet splash DEFAULT_TIMEOUT := 10 DEFAULT_HIDDEN_TIMEOUT := 0 DEFAULT_HIDDEN_TIMEOUT_BOOL := true confflags += \ --enable-ubuntu-recovery \ --enable-quiet-boot \ --enable-quick-boot \ --enable-gfxpayload-dynamic \ --enable-vt-handoff substvars := \ -Vlsb-base-depends="lsb-base (>= 3.0-6)" \ -Vgfxpayload-depends="grub-gfxpayload-lists [any-i386 any-amd64]" else ifeq (yes,$(shell dpkg-vendor --derives-from Tanglu && echo yes)) DEFAULT_CMDLINE := quiet splash DEFAULT_TIMEOUT := 10 DEFAULT_HIDDEN_TIMEOUT := 0 DEFAULT_HIDDEN_TIMEOUT_BOOL := true confflags += \ --enable-quiet-boot \ --enable-quick-boot \ --enable-gfxpayload-dynamic \ --enable-vt-handoff substvars := \ -Vlsb-base-depends="lsb-base (>= 3.0-6)" \ -Vgfxpayload-depends="grub-gfxpayload-lists [any-i386 any-amd64]" else DEFAULT_CMDLINE := quiet DEFAULT_TIMEOUT := 5 DEFAULT_HIDDEN_TIMEOUT := DEFAULT_HIDDEN_TIMEOUT_BOOL := false substvars := endif SB_PACKAGE := ifeq (yes,$(shell dpkg-vendor --derives-from Ubuntu && echo yes)) ifeq ($(DEB_HOST_ARCH),amd64) SB_PACKAGE := grub-efi-amd64 SB_PLATFORM := x86_64-efi SB_EFI_NAME := x64 endif endif %: dh $@ --parallel override_dh_auto_configure: $(patsubst %,configure/%,$(BUILD_PACKAGES)) override_dh_auto_build: $(patsubst %,build/%,$(BUILD_PACKAGES)) override_dh_auto_install: $(patsubst %,install/%,$(BUILD_PACKAGES)) $(patsubst %,configure/%,$(REAL_PACKAGES)) :: configure/% : debian/stamps/configure-% $(patsubst %,build/%,$(REAL_PACKAGES) grub-rescue-pc) :: build/% : debian/stamps/build-% debian/stamps/configure-%: package = $(subst debian/stamps/configure-,,$@) debian/stamps/configure-%: export DH_OPTIONS = -p$(package) -Bobj/$(package) debian/stamps/build-%: package = $(subst debian/stamps/build-,,$@) debian/stamps/build-%: export DH_OPTIONS = -p$(package) -Bobj/$(package) install/%: package = $(subst install/,,$@) install/%: package_bin = $(package)-bin install/%: package_dbg = $(package)-dbg install/grub-emu: package_bin = grub-emu install/grub-emu: package_dbg = grub-emu-dbg install/%: export DH_OPTIONS = -p$(package) -Bobj/$(patsubst grub-common,grub-$(COMMON_PLATFORM),$(package)) debian/stamps/autogen: autogen.sh configure.ac Makefile.util.def grub-core/Makefile.core.def mkdir -p debian/stamps rm -rf debian/grub-extras-enabled mkdir debian/grub-extras-enabled set -e; for extra in 915resolution ntldr-img; do \ cp -a debian/grub-extras/$$extra debian/grub-extras-enabled/; \ done env -u DH_OPTIONS GRUB_CONTRIB=$(CURDIR)/debian/grub-extras-enabled \ dh_autoreconf -- ./autogen.sh touch $@ debian/stamps/configure-grub-common: debian/stamps/configure-grub-$(COMMON_PLATFORM) debian/stamps/build-grub-common: debian/stamps/build-grub-$(COMMON_PLATFORM) debian/stamps/configure-grub-pc debian/stamps/configure-grub-coreboot debian/stamps/configure-grub-emu debian/stamps/configure-grub-uboot debian/stamps/configure-grub-yeeloong: debian/stamps/autogen mkdir -p debian/stamps obj/$(package) dh_auto_configure -- $(confflags) --with-platform=$(subst grub-,,$(package)) touch $@ debian/stamps/configure-grub-ieee1275: debian/stamps/autogen mkdir -p debian/stamps obj/$(package) dh_auto_configure -- $(confflags) --with-platform=$(subst grub-,,$(package)) $(if $(filter ppc64el,$(DEB_HOST_ARCH_CPU)),--target=powerpc-linux-gnu TARGET_CC=powerpc-linux-gnu-gcc-4.8) touch $@ # This name scheme leaves room for things like amd32 someday debian/stamps/configure-grub-efi-ia32: debian/stamps/autogen mkdir -p debian/stamps obj/$(package) dh_auto_configure -- $(confflags) --with-platform=efi --target=i386-pe --program-prefix="" touch $@ debian/stamps/configure-grub-efi-amd64: debian/stamps/autogen mkdir -p debian/stamps $(subst debian/stamps/configure-,obj/,$@) dh_auto_configure -- $(confflags) --with-platform=efi --target=amd64-pe --program-prefix="" touch $@ debian/stamps/configure-grub-efi-ia64 debian/stamps/configure-grub-efi-arm debian/stamps/configure-grub-efi-arm64: debian/stamps/autogen mkdir -p debian/stamps $(subst debian/stamps/configure-,obj/,$@) dh_auto_configure -- $(confflags) --with-platform=efi touch $@ debian/stamps/configure-grub-xen-%: debian/stamps/autogen mkdir -p debian/stamps obj/$(package) dh_auto_configure -- $(confflags) --with-platform=xen --target=$(subst debian/stamps/configure-grub-xen-,,$@) --program-prefix="" touch $@ debian/stamps/configure-grub-xen: debian/stamps/configure-grub-xen-i386 debian/stamps/configure-grub-xen-amd64 touch $@ debian/stamps/configure-grub-firmware-qemu: debian/stamps/autogen mkdir -p debian/stamps $(subst debian/stamps/configure-,obj/,$@) dh_auto_configure -- $(confflags) --with-platform=qemu touch $@ debian/stamps/build-grub-efi-ia32 debian/stamps/build-grub-efi-amd64 debian/stamps/build-grub-efi-ia64 debian/stamps/build-grub-efi-arm debian/stamps/build-grub-efi-arm64 debian/stamps/build-grub-ieee1275 debian/stamps/build-grub-coreboot debian/stamps/build-grub-emu debian/stamps/build-grub-uboot debian/stamps/build-grub-xen-i386 debian/stamps/build-grub-xen-amd64 debian/stamps/build-grub-yeeloong: debian/stamps/build-%: debian/stamps/configure-% dh_auto_build touch $@ debian/stamps/build-grub-pc: debian/stamps/configure-grub-pc dh_auto_build ifeq ($(with_check), yes) LC_CTYPE=C.UTF-8 PATH="$$PATH:/sbin:/usr/sbin" VERBOSE=1 dh_auto_test endif touch $@ debian/stamps/build-grub-xen: debian/stamps/build-grub-xen-i386 debian/stamps/build-grub-xen-amd64 touch $@ debian/stamps/build-grub-firmware-qemu: debian/stamps/configure-grub-firmware-qemu dh_auto_build grub_dir=`mktemp -d` ; \ grub_memdisk=`mktemp` ; \ trap "rm -rf $${grub_dir} $${grub_memdisk}" EXIT HUP INT QUIT TERM ; \ mkdir -p $${grub_dir}/boot/grub ; \ cp debian/grub-firmware-qemu_grub.cfg $${grub_dir}/boot/grub/grub.cfg ; \ tar -cf - -C $${grub_dir} boot > $${grub_memdisk} ; \ obj/$(package)/grub-mkimage \ -O i386-qemu \ -d $(CURDIR)/obj/$(package)/grub-core \ $(CURDIR)/obj/$(package)/grub-core/*.mod \ -m $${grub_memdisk} \ -o $(CURDIR)/obj/$(package)/grub.bin touch $@ debian/stamps/build-grub-rescue-pc: debian/stamps/build-grub-pc mkdir -p obj/grub-rescue-pc/rescue-disk/boot/grub cp docs/grub.cfg obj/grub-rescue-pc/rescue-disk/boot/grub/ rm -rf obj/grub-rescue-pc/grub-core cp -a obj/grub-pc/grub-core obj/grub-rescue-pc/grub-core cp -a obj/grub-pc/unicode.pf2 obj/grub-rescue-pc/ pkgdatadir=$(CURDIR)/obj/grub-rescue-pc \ obj/grub-pc/grub-mkrescue \ --directory=$(CURDIR)/obj/grub-rescue-pc/grub-core \ --locale-directory=$(CURDIR)/obj/grub-rescue-pc/grub-core/po \ --output=$(CURDIR)/obj/grub-rescue-pc/grub-rescue-cdrom.iso \ $(CURDIR)/obj/grub-rescue-pc/rescue-disk # save space for floppy image rm -rf obj/grub-rescue-pc/grub-core/po obj/grub-rescue-pc/unicode.pf2 pkgdatadir=$(CURDIR)/obj/grub-rescue-pc \ obj/grub-pc/grub-mkrescue \ --directory=$(CURDIR)/obj/grub-rescue-pc/grub-core \ --locale-directory=$(CURDIR)/obj/grub-rescue-pc/grub-core/po \ --output=$(CURDIR)/obj/grub-rescue-pc/grub-rescue-floppy.img \ --compress=xz \ -- -no-pad $(CURDIR)/obj/grub-rescue-pc/rescue-disk touch $@ platform_subst = \ if [ -e debian/$(1) ]; then \ debian/platform-subst \ PACKAGE="$(2)" \ DEFAULT_CMDLINE="$(DEFAULT_CMDLINE)" \ DEFAULT_TIMEOUT="$(DEFAULT_TIMEOUT)" \ DEFAULT_HIDDEN_TIMEOUT_BOOL="$(DEFAULT_HIDDEN_TIMEOUT_BOOL)" \ debian/$(1) >> debian/$(2).$(3); \ fi install/grub-pc install/grub-efi-ia32 install/grub-efi-amd64 install/grub-efi-ia64 install/grub-efi-arm install/grub-efi-arm64 install/grub-ieee1275 install/grub-coreboot install/grub-emu install/grub-uboot install/grub-xen install/grub-yeeloong: set -e ; \ if [ "$@" = "install/grub-xen" ] ; then \ dh_auto_install -Bobj/grub-xen-i386 --destdir=debian/tmp-$(package); \ dh_auto_install -Bobj/grub-xen-amd64 --destdir=debian/tmp-$(package); \ else \ dh_auto_install --destdir=debian/tmp-$(package); \ fi set -e ; \ for i in $(AUTOGEN_DEB_FILES) ; do \ > debian/$(package).$$i; \ if [ "$@" != "install/grub-emu" ] ; then \ $(call platform_subst,$$i.in,$(package),$$i); \ fi ; \ $(call platform_subst,$(package).$$i.in,$(package),$$i); \ $(call platform_subst,$(package).$$i.$(DEB_HOST_ARCH_CPU).in,$(package),$$i); \ $(call platform_subst,$(package).$$i.$(DEB_HOST_ARCH_OS).in,$(package),$$i); \ $(call platform_subst,$(package).$$i.$(DEB_HOST_ARCH_OS)-$(DEB_HOST_ARCH_CPU).in,$(package),$$i); \ [ -s debian/$(package).$$i ] || rm -f debian/$(package).$$i; \ if [ "$@" != "install/grub-emu" ] ; then \ > debian/$(package_bin).$$i; \ $(call platform_subst,$$i-bin.in,$(package_bin),$$i); \ $(call platform_subst,$(package_bin).$$i.in,$(package_bin),$$i); \ $(call platform_subst,$(package_bin).$$i.$(DEB_HOST_ARCH_CPU).in,$(package_bin),$$i); \ $(call platform_subst,$(package_bin).$$i.$(DEB_HOST_ARCH_OS).in,$(package_bin),$$i); \ $(call platform_subst,$(package_bin).$$i.$(DEB_HOST_ARCH_OS)-$(DEB_HOST_ARCH_CPU).in,$(package_bin),$$i); \ [ -s debian/$(package_bin).$$i ] || rm -f debian/$(package_bin).$$i; \ fi ; \ > debian/$(package_dbg).$$i; \ if [ "$@" != "install/grub-emu" ] ; then \ $(call platform_subst,$$i-dbg.in,$(package_dbg),$$i); \ fi ; \ $(call platform_subst,$(package_dbg).$$i.in,$(package_dbg),$$i); \ $(call platform_subst,$(package_dbg).$$i.$(DEB_HOST_ARCH_CPU).in,$(package_dbg),$$i); \ $(call platform_subst,$(package_dbg).$$i.$(DEB_HOST_ARCH_OS).in,$(package_dbg),$$i); \ $(call platform_subst,$(package_dbg).$$i.$(DEB_HOST_ARCH_OS)-$(DEB_HOST_ARCH_CPU).in,$(package_dbg),$$i); \ [ -s debian/$(package_dbg).$$i ] || rm -f debian/$(package_dbg).$$i; \ done find debian/tmp-$(package)/usr/lib/grub -name modinfo.sh -print0 | \ xargs -0r chmod +x find debian/tmp-$(package)/usr/lib/grub -name gdb_grub -print0 | \ xargs -0r chmod -x find debian/tmp-$(package)/usr/lib/grub -name gmodule.pl -print0 | \ xargs -0r chmod -x mkdir -p debian/$(package_bin)/usr/share/lintian/overrides echo "$(package_bin): unstripped-binary-or-object *.mod" \ >> debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin) cd debian/tmp-$(package) && find usr/lib/grub -name kernel.img \ | sed -e "s%.*%$(package_bin): statically-linked-binary &%g" \ >> $(CURDIR)/debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin) cd debian/tmp-$(package) && find ./usr/lib/grub -name kernel.img \ | sed -e "s%.*%$(package_bin): statically-linked-binary &%g" \ >> $(CURDIR)/debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin) cd debian/tmp-$(package) && find usr/lib/grub -name kernel.img \ | sed -e "s%.*%$(package_bin): unstripped-binary-or-object &%g" \ >> $(CURDIR)/debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin) if ([ "$@" = "install/grub-efi-amd64" ] && [ "$(DEB_HOST_ARCH_CPU)" = "i386" ]) || \ [ "$@" = "install/grub-xen" ] ; then \ echo "$(package_bin): binary-from-other-architecture *.mod" \ >> debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin) ; \ cd debian/tmp-$(package) && find usr/lib/grub -name kernel.img \ | sed -e "s%.*%$(package_bin): binary-from-other-architecture &%g" \ >> $(CURDIR)/debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin) ; \ fi if ([ "$@" = "install/grub-pc" ] || \ [ "$@" = "install/grub-ieee1275" ] || \ [ "$@" = "install/grub-coreboot" ] || \ [ "$@" = "install/grub-xen" ] || \ [ "$@" = "install/grub-emu" ]) && \ [ "$(DEB_HOST_ARCH_OS)" = "linux" ] && \ [ "$(DEB_HOST_ARCH_CPU)" = "i386" ] ; then \ echo "$(package_bin): binary-from-other-architecture *efiemu64.o" \ >> debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin) ; \ fi mkdir -p debian/$(package_dbg)/usr/share/lintian/overrides echo "$(package_dbg): unstripped-binary-or-object *.module" \ >> debian/$(package_dbg)/usr/share/lintian/overrides/$(package_dbg) echo "$(package_dbg): statically-linked-binary *.image" \ >> debian/$(package_dbg)/usr/share/lintian/overrides/$(package_dbg) cd debian/tmp-$(package) && find usr/lib/grub -name kernel.exec \ | sed -e "s%.*%$(package_dbg): statically-linked-binary &%g" \ >> $(CURDIR)/debian/$(package_dbg)/usr/share/lintian/overrides/$(package_dbg) if ([ "$@" = "install/grub-efi-amd64" ] && [ "$(DEB_HOST_ARCH_CPU)" = "i386" ]) || \ [ "$@" = "install/grub-xen" ] ; then \ echo "$(package_dbg): binary-from-other-architecture *.module" \ >> debian/$(package_dbg)/usr/share/lintian/overrides/$(package_dbg) ; \ cd debian/tmp-$(package) && find usr/lib/grub -name kernel.exec \ | sed -e "s%.*%$(package_dbg): binary-from-other-architecture &%g" \ >> $(CURDIR)/debian/$(package_dbg)/usr/share/lintian/overrides/$(package_dbg) ; \ fi # Avoid failures later if we're building from a tree with no .po # files. mkdir -p debian/tmp-$(package)/usr/share/locale install/grub-common: set -e ; for i in $(AUTOGEN_DEB_FILES) ; do \ if [ -e debian/grub-common.$$i.in ] ; then \ cat debian/grub-common.$$i.in \ > debian/grub-common.$$i ; \ fi ; \ if [ -e debian/grub-common.$$i.$(DEB_HOST_ARCH_CPU).in ] ; then \ cat debian/grub-common.$$i.$(DEB_HOST_ARCH_CPU).in \ >> debian/grub-common.$$i ; \ fi ; \ if [ -e debian/grub-common.$$i.$(DEB_HOST_ARCH_OS).in ] ; then \ cat debian/grub-common.$$i.$(DEB_HOST_ARCH_OS).in \ >> debian/grub-common.$$i ; \ fi ; \ done ifeq (yes,$(shell dpkg-vendor --derives-from Ubuntu && echo yes)) install -D -m 0755 debian/grub-common.pm-sleep \ $(CURDIR)/debian/$(package)/etc/pm/sleep.d/10_grub-common endif override_dh_install: dh_install -pgrub2 -pgrub-linuxbios -pgrub-efi -pgrub-rescue-pc -pgrub-firmware-qemu set -e; for package in grub-common grub2-common grub-theme-starfield grub-mount-udeb; do \ dh_install -p$$package --sourcedir=debian/tmp-grub-$(COMMON_PLATFORM); \ done rm -f debian/grub2-common/usr/share/info/dir* rm -f debian/grub-theme-starfield/usr/share/grub/themes/starfield/COPYING.CC-BY-SA-3.0 set -e; for package in grub-pc grub-efi-ia32 grub-efi-amd64 grub-efi-ia64 grub-efi-arm grub-efi-arm64 grub-ieee1275 grub-coreboot grub-uboot grub-xen grub-yeeloong; do \ dh_install -p$$package --sourcedir=debian/tmp-$$package; \ dh_install -p$$package-bin --sourcedir=debian/tmp-$$package; \ dh_install -p$$package-dbg --sourcedir=debian/tmp-$$package; \ done dh_install -pgrub-emu --sourcedir=debian/tmp-grub-emu dh_install -pgrub-emu-dbg --sourcedir=debian/tmp-grub-emu sed -i \ -e "s/@DEFAULT_CMDLINE@/$(DEFAULT_CMDLINE)/g" \ -e "s/@DEFAULT_TIMEOUT@/$(DEFAULT_TIMEOUT)/g" \ debian/grub2-common/usr/share/grub/default/grub ifneq (,$(DEFAULT_HIDDEN_TIMEOUT)) perl -pi -e 's/^GRUB_TIMEOUT=.*/GRUB_HIDDEN_TIMEOUT=0\nGRUB_HIDDEN_TIMEOUT_QUIET=true\n$$&/' \ debian/grub2-common/usr/share/grub/default/grub endif ifeq (yes,$(shell dpkg-vendor --derives-from Ubuntu && echo yes)) ifneq (,$(filter grub-pc,$(BUILD_PACKAGES))) patch debian/grub-pc/usr/lib/grub-legacy/update-grub \ < debian/legacy/update-grub.ubuntu.patch endif endif override_dh_installdocs: dh_installdocs -pgrub-common -pgrub-rescue-pc -pgrub-firmware-qemu -A AUTHORS NEWS README THANKS TODO dh_installdocs -Ngrub-common -Ngrub-rescue-pc -Ngrub-firmware-qemu --link-doc=grub-common ifeq (yes,$(shell dpkg-vendor --derives-from Ubuntu && echo yes)) override_dh_installinit: dh_installinit -- start 99 2 3 4 5 . else ifeq (yes,$(shell dpkg-vendor --derives-from Tanglu && echo yes)) override_dh_installinit: dh_installinit -- start 99 2 3 4 5 . else override_dh_installinit: : endif override_dh_bugfiles: dh_bugfiles -A override_dh_strip: dh_strip -X/usr/bin/grub-emu override_dh_shlibdeps: dh_shlibdeps -X.module ifeq (yes,$(shell dpkg-vendor --derives-from Ubuntu && echo yes)) LEGACY_DOC_CONFLICTS := grub-doc (<< 0.97-29ubuntu60), grub-legacy-doc (<< 0.97-29ubuntu60) else LEGACY_DOC_CONFLICTS := grub-doc (<< 0.97-32), grub-legacy-doc (<< 0.97-59) endif override_dh_gencontrol: dh_gencontrol -- \ -Vlegacy-doc-conflicts="$(LEGACY_DOC_CONFLICTS)" $(substvars) TARNAME := grub2_$(deb_version)_$(DEB_HOST_ARCH).tar.gz override_dh_builddeb: dh_builddeb -- -Zxz ifneq (,$(SB_PACKAGE)) debian/build-efi-images \ obj/grub-$(COMMON_PLATFORM)/grub-mkimage \ obj/$(SB_PACKAGE)/grub-core \ debian/grub2-images/$(deb_version) \ $(SB_PLATFORM) $(SB_EFI_NAME) echo $(deb_version) \ > debian/grub2-images/$(deb_version)/version cd debian/grub2-images && tar czvf ../../../$(TARNAME) . dpkg-distaddfile $(TARNAME) raw-uefi - endif override_dh_auto_clean: -rm -rf debian/grub-extras-enabled debian/stamps obj -rm -f contrib grub-core/contrib override_dh_clean: dh_autoreconf_clean dh_clean chmod +x debian/{bug-script,grub.d/*,legacy/*,kernel/*} for i in $(AUTOGEN_DEB_FILES) ; do \ rm -f debian/grub-{pc,efi-*,ieee1275,coreboot,uboot,xen,yeeloong,emu}{,-bin,-dbg}.$$i ; \ done rm -f debian/grub-common.maintscript rm -rf debian/tmp-*/ ifneq (,$(SB_PACKAGE)) rm -rf debian/grub2-images endif # make sure PO files are always up-to-date debconf-updatepo .PHONY: $(patsubst %,configure/%,$(BUILD_PACKAGES)) $(patsubst %,build/%,$(BUILD_PACKAGES)) $(patsubst %,install/%,$(BUILD_PACKAGES))