1#!/bin/sh
2#
3# Copyright (c) 2010-2012 Haiku, Inc.
4# Distributed under the terms of the MIT License.
5#
6# Authors:
7#		Matt Madia, mattmadia@gmail.com
8#
9# Synopsis:
10#	Provide a mechanism for end-users to install various firmwares for wireless
11#	network cards in a manner that complies with their individual licenses.
12#
13# Supported chipsets:
14# 	Intel ipw2100
15#	Intel ipw2200/2225/2915
16#	Broadcom 43xx
17#	Marvell 88W8335
18
19
20MESSAGE="This script will install firmware for various wireless network cards.
21 The Broadcom 43xx and Marvell 88W8335 require an active network connection
22 to download additional files before installation. In the absence of internet
23 access, only Intel's ipw2100 and ipw2200 will be installed.
24
25 If you do not have internet access and need to install the other firmwares,
26 goto http://www.haiku-os.org/guides/dailytasks/wireless. This page has
27 instructions on which files to manually download and where to copy them into
28 this OS. It also has different script that can be run on another OS and will
29 prepare a zip archive for easy install. After that, re-run this script."
30VIEW='View licenses'
31ABORT='Abort installation'
32OK='I agree to the licenses. Install firmwares.'
33
34baseURL='http://www.haiku-files.org/files/wifi-firmwares'
35firmwareDir=`finddir B_SYSTEM_DATA_DIRECTORY`/firmware
36tempDir=`finddir B_COMMON_TEMP_DIRECTORY`/wifi-firmwares
37driversDir=`finddir B_SYSTEM_ADDONS_DIRECTORY`/kernel/drivers
38intelLicense='/boot/system/data/licenses/Intel (2xxx firmware)'
39
40
41function DisplayAlert()
42{
43	local result=`alert --stop "$MESSAGE" "$VIEW" "$ABORT" "$OK"`
44	case "${result}" in
45		"$VIEW")
46			ViewLicenses ;
47			DisplayAlert ;
48			;;
49		"$ABORT")
50			exit 0 ;;
51		"$OK")
52			InstallAllFirmwares ;
53			exit 0 ;
54			;;
55	esac
56}
57
58
59function ViewLicenses()
60{
61	license="$tempDir/Wifi_Firmware_Licenses"
62	cat << EOF > $license
63
64+-----------------------------------------------------------------------------+
65|                                                                             |
66|   Copyright and licensing information of the various wireless firmwares     |
67|                                                                             |
68| Firmware for broadcom43xx is under the Copyright of Broadcom Corporation(R) |
69| Firmware for marvell88w8335 is under the Copyright of Marvell Technology(R) |
70| ipw2100,iprowifi2200 firmware is covered by the following Intel(R) license: |
71|                                                                             |
72+-----------------------------------------------------------------------------+
73
74EOF
75	cat "$intelLicense" >> $license
76
77	open $license
78}
79
80
81function InstallAllFirmwares()
82{
83	InstallIpw2100
84	InstallIprowifi2200
85	InstallBroadcom43xx
86	InstallMarvell88w8335
87}
88
89
90function UnlinkDriver()
91{
92	# remove the driver's symlink
93	rm -f "${driversDir}/dev/net/${driver}"
94}
95
96
97function SymlinkDriver()
98{
99	# restore the driver's symlink
100	cd "${driversDir}/dev/net/"
101	ln -sf "../../bin/${driver}" "${driver}"
102}
103
104
105function DownloadFileIfNotCached()
106{
107	# DownloadFileIfNotCached <url> <filename> <destination dir>
108	local url=$1
109	local file=$2
110	local dir=$3
111
112	mkdir -p "$dir"
113	if [ ! -e $dir/$file ] ; then
114		echo "Downloading $url ..."
115		wget -nv -O $dir/$file $url
116	fi
117	result=$?
118	if [ $result -gt 0 ]; then
119		local error="Failed to download $url."
120		local msg="As a result, ${driver}'s firmware will not be installed."
121		alert --warning "$error $msg"
122	fi
123}
124
125
126function SetFirmwarePermissions()
127{
128	cd ${firmwareDir}/${driver}/
129	for file in * ; do
130		if [ "$file" != "$driver" ] && [ -f "$file" ] ; then
131			chmod a=r $file
132		fi
133	done
134}
135
136
137function CleanTemporaryFiles()
138{
139	rm -rf "$tempDir"
140	mkdir -p "$tempDir"
141}
142
143
144function PreFirmwareInstallation()
145{
146	echo "Installing firmware for ${driver} ..."
147	mkdir -p "${firmwareDir}/${driver}"
148	UnlinkDriver
149}
150
151
152function PostFirmwareInstallation()
153{
154	SetFirmwarePermissions
155	SymlinkDriver
156	CleanTemporaryFiles
157	echo "... firmware for ${driver} has been installed."
158}
159
160
161function InstallIpw2100()
162{
163	driver='iprowifi2100'
164	PreFirmwareInstallation
165
166	# Extract contents.
167	local file='ipw2100-fw-1.3.tgz'
168	local url="${baseURL}/intel/${file}"
169	local dir="${firmwareDir}/${driver}"
170	DownloadFileIfNotCached $url $file $dir
171
172	# Install the firmware & license file by extracting in place.
173	cd "${firmwareDir}/${driver}"
174	gunzip < "$file" | tar xf -
175
176	PostFirmwareInstallation
177}
178
179
180function InstallIprowifi2200()
181{
182	driver='iprowifi2200'
183	PreFirmwareInstallation
184
185	# Extract contents.
186	local file='ipw2200-fw-3.1.tgz'
187	local url="${baseURL}/intel/${file}"
188	local dir="${firmwareDir}/${driver}"
189	DownloadFileIfNotCached $url $file $dir
190
191	cd "$tempDir"
192	gunzip < "${firmwareDir}/${driver}/$file" | tar xf -
193
194	# Install the firmware & license file.
195	cd "${tempDir}/ipw2200-fw-3.1"
196	mv LICENSE.ipw2200-fw "${firmwareDir}/${driver}/"
197	mv ipw2200-ibss.fw "${firmwareDir}/${driver}/"
198	mv ipw2200-sniffer.fw "${firmwareDir}/${driver}/"
199	mv ipw2200-bss.fw "${firmwareDir}/${driver}/"
200
201	PostFirmwareInstallation
202}
203
204
205function InstallBroadcom43xx()
206{
207	driver='broadcom43xx'
208	PreFirmwareInstallation
209
210	BuildBroadcomFWCutter
211	returnCode=$?
212	if [ $returnCode -gt 0 ] ; then
213		echo "...failed. ${driver}'s firmware will not be installed."
214		return $returnCode
215	fi
216
217	CutAndInstallBroadcomFirmware
218	returnCode=$?
219	if [ $returnCode -gt 0 ] ; then
220		echo "...failed. ${driver}'s firmware will not be installed."
221		return $returnCode
222	fi
223
224	PostFirmwareInstallation
225}
226
227
228function InstallMarvell88w8335()
229{
230	driver='marvell88w8335'
231	PreFirmwareInstallation
232
233	# Download firmware archive.
234	local file="malo-firmware-1.4.tgz"
235	local url="${baseURL}/marvell/${file}"
236	local dir="${firmwareDir}/${driver}"
237	DownloadFileIfNotCached $url $file "$dir"
238	if [ $result -gt 0 ]; then
239		echo "...failed. ${driver}'s firmware will not be installed."
240		return $result
241	fi
242
243	# Extract archive.
244	cd "$tempDir"
245	tar xf "${firmwareDir}/${driver}/$file"
246
247	# Move firmware files to destination.
248	local sourceDir="${tempDir}/share/examples/malo-firmware"
249	mv ${sourceDir}/malo8335-h "${firmwareDir}/${driver}"
250	mv ${sourceDir}/malo8335-m "${firmwareDir}/${driver}"
251	PostFirmwareInstallation
252}
253
254
255function BuildBroadcomFWCutter()
256{
257	# Download & extract b43-fwcutter.
258	local file="b43-fwcutter-012.tar.bz2"
259	local dir="${firmwareDir}/${driver}/b43-fwcutter"
260	local url="${baseURL}/b43/fwcutter/${file}"
261	DownloadFileIfNotCached $url $file $dir
262	if [ $result -gt 0 ]; then
263		return $result
264	fi
265
266	# Extract archive.
267	cd "$tempDir"
268	tar xjf "$dir/$file"
269
270	# Download additonal files for building b43-fwcutter.
271	cd b43-fwcutter-012
272	local baseURL='http://cgit.haiku-os.org/haiku/plain/src/system/libroot/posix/glibc'
273	DownloadFileIfNotCached ${baseURL}/string/byteswap.h byteswap.h $dir
274	if [ $result -gt 0 ]; then
275		return $result
276	fi
277	DownloadFileIfNotCached ${baseURL}/include/arch/x86/bits/byteswap.h byteswap.h $dir/bits
278	if [ $result -gt 0 ]; then
279		return $result
280	fi
281
282	# Copy those files to working directory.
283	mkdir -p bits
284	cp $dir/byteswap.h .
285	cp $dir/bits/byteswap.h bits/
286
287	# Build b43-fwcutter.
288	echo "Compiling b43-fwcutter for installing Broadcom's firmware ..."
289	make PREFIX=/boot/common CFLAGS="-I. -Wall -D_BSD_SOURCE" > /dev/null 2>&1
290	result=$?
291	if [ $result -gt 0 ]; then
292		echo "... failed to compile b43-fwcutter."
293	else
294		echo "... successfully compiled b43-fwcutter."
295	fi
296	if [ ! -e b43-fwcutter ] ; then
297		return 1
298	fi
299	mv b43-fwcutter "$tempDir"
300
301	return 0
302}
303
304
305function CutAndInstallBroadcomFirmware()
306{
307	# Download firmware.
308	local file="wl_apsta-3.130.20.0.o"
309	local dir="${firmwareDir}/${driver}"
310	local url="${baseURL}/b43/${file}"
311	DownloadFileIfNotCached $url $file $dir
312	if [ $result -gt 0 ]; then
313		return $result
314	fi
315
316	# Cut firmware in pieces.
317	cp "$dir/$file" "$tempDir"
318	cd "$tempDir"
319	b43-fwcutter $file > /dev/null 2>&1
320
321	# Rename the pieces.
322	cd b43legacy
323	for i in $(ls -1); do
324		newFileName=$(echo $i | sed "s/\(.*\)\.fw$/bwi_v3_\1/g")
325		mv $i $newFileName
326	done
327	touch bwi_v3_ucode
328
329	# Install files.
330	mv * ${firmwareDir}/${driver}/
331
332	return 0
333}
334
335
336mkdir -p "$tempDir"
337DisplayAlert
338